फैक्टरी पैटर्न। कारखाने के तरीकों का उपयोग कब करें?


जवाबों:


387

मुझे अपनी कक्षाओं के 'लोगों' के संदर्भ में डिजाइन के बारे में सोचना पसंद है, और पैटर्न ऐसे तरीके हैं जिनसे लोग एक-दूसरे से बात करते हैं।

तो, मेरे लिए कारखाना पैटर्न एक भर्ती एजेंसी की तरह है। आपको कोई ऐसा व्यक्ति मिला है जिसे श्रमिकों की एक चर संख्या की आवश्यकता होगी। इस व्यक्ति को कुछ जानकारी पता हो सकती है कि उन्हें उन लोगों की ज़रूरत है जो वे किराए पर लेते हैं, लेकिन ऐसा है।

इसलिए, जब उन्हें एक नए कर्मचारी की आवश्यकता होती है, तो वे काम पर रखने वाली एजेंसी को बुलाते हैं और उन्हें बताते हैं कि उन्हें क्या चाहिए। अब, वास्तव में किसी को किराए पर लेने के लिए , आपको बहुत सारे सामान - लाभ, पात्रता सत्यापन, आदि जानने की आवश्यकता है, लेकिन काम पर रखने वाले व्यक्ति को इनमें से किसी को भी जानने की आवश्यकता नहीं है - भर्ती एजेंसी उस सभी को संभालती है।

उसी तरह, किसी कारखाने का उपयोग करने से उपभोक्ता नई वस्तुओं को बनाने की अनुमति देता है बिना यह जाने कि वे कैसे बनाई गई हैं, या उनकी निर्भरता क्या है - का विवरण उन्हें केवल उन सूचनाओं को देना होगा जो वे वास्तव में चाहते हैं।

public interface IThingFactory
{
    Thing GetThing(string theString);
}

public class ThingFactory : IThingFactory
{
    public Thing GetThing(string theString)
    {
        return new Thing(theString, firstDependency, secondDependency);
    }
}

इसलिए, अब उपभोक्ता से आने वाले स्ट्रिंग डेटा को छोड़कर, ThingFactory के उपभोक्ता को एक Thing मिल सकता है, जो Thing की निर्भरता के बारे में नहीं जानता है।


17
गेटटहिंग () के ठोस कार्यान्वयन को पहली निर्भरता और दूसरी निर्भरता के मूल्यों को फिर से प्राप्त नहीं होता है।
मिकीग ३६

88
कोई मुझे बता सकता है कि यह ओपी के सवाल का जवाब कैसे देता है? यह केवल वर्णन करता है कि 'फ़ैक्टरी पैटर्न' क्या है और फिर 'फ़ैक्टरी विधि' का एक उदाहरण जोड़ें, जो कि केवल तीन 'फ़ैक्टरी पैटर्न' में से एक है। दूसरे शब्द में, मुझे कहीं भी कोई तुलना नहीं दिख रही है।
फोरेथिंकर

4
ओपी के प्रश्न में स्पष्ट रूप से उल्लेख है within an object instead of a Factory class। मुझे लगता है कि उनका अभिप्राय उस परिदृश्य से है जहां आप ctor को निजी बनाते हैं और क्लास को तुरंत (ऑब्जेक्ट बनाने के लिए) स्टैटिक विधि का उपयोग करते हैं। लेकिन इस उदाहरण का पालन ThingFactoryकरने के लिए Thing, वस्तुओं को प्राप्त करने के लिए पहले वर्ग को तुरंत रोकना चाहिए , जिससे यह Factory classप्रभाव में आता है।
अय्यर

4
क्षमा करें, लेकिन स्पष्टीकरण बकवास है, क्योंकि एक कंस्ट्रक्टर को आश्रितों को छिपाने के लिए भी लिखा जा सकता है। मुख्य पृष्ठभूमि जानकारी जिसे आप निर्भरता प्रबंधन से निर्भरता निर्माण की जानकारी को अलग करना चाहते हैं गायब है। इसके अलावा, सवाल एक ही वर्ग के बारे में था, इसका कोई जवाब नहीं है।
क्रिश्चियन हुजेर

8
ओपी ने पूछा कि कब । Kyoryu ने उत्तर दिया कि कैसे । यद्यपि उत्तर की शैली सराहनीय है, इस प्रश्न के संदर्भ में, यह सिर्फ शोर है।
8bitjunkie

96

कारखाने के तरीकों को निर्माणकर्ताओं के विकल्प के रूप में माना जाना चाहिए - ज्यादातर जब निर्माणकर्ता पर्याप्त अर्थपूर्ण नहीं होते हैं, अर्थात।

class Foo{
  public Foo(bool withBar);
}

उतना स्पष्ट नहीं है:

class Foo{
  public static Foo withBar();
  public static Foo withoutBar();
}

जब आप ऑब्जेक्ट के निर्माण के लिए जटिल प्रक्रिया की आवश्यकता होती है, जब निर्माण को एक निर्भरता की आवश्यकता होती है, जो आपको वास्तविक वर्ग के लिए नहीं चाहिए, जब आपको विभिन्न वस्तुओं आदि के निर्माण की आवश्यकता होती है, तब फैक्ट्री कक्षाएं उपयोगी होती हैं।


2
यहाँ कारखाना वर्ग कहाँ है?
कोरे तुगे

20
@KorayTugay: कोई फैक्ट्री क्लास नहीं है, केवल फैक्ट्री के तरीके हैं। सवाल यह है कि फैक्ट्री क्लास के बजाय फैक्ट्री के तरीकों का इस्तेमाल कब किया जाए । लेकिन फ़ैक्टरी विधियाँ फ़ैक्टरी वर्गों के विकल्प की तुलना में कंस्ट्रक्टरों के लिए अधिक वैकल्पिक हैं। (मुझे नहीं पता कि केवल कारखाने की कक्षाओं के बारे में बात करने के बावजूद शीर्ष उत्तर को इतना अधिक क्यों दर्जा दिया गया है)।
रासमस फैबर

5
यह ध्यान दिया जाना चाहिए कि स्टेटिक फ़ैक्टरी विधियाँ गैंग ऑफ़ फोर: फैक्ट्री मेथड डिज़ाइन पैटर्न से पूरी तरह अलग हैं।
jaco0646

76

एक स्थिति जहां मैं व्यक्तिगत रूप से अलग-अलग फैक्ट्री कक्षाएं ढूंढता हूं, यह समझ में आता है कि अंतिम वस्तु आप कई अन्य वस्तुओं पर निर्भर बनाने की कोशिश कर रहे हैं। जैसे, PHP में: मान लीजिए कि आपके पास एक Houseऑब्जेक्ट है, जिसके बदले में Kitchenएक LivingRoomऑब्जेक्ट है, और ऑब्जेक्ट के अंदर LivingRoomभी एक TVऑब्जेक्ट है।

इसे प्राप्त करने की सबसे सरल विधि प्रत्येक वस्तु को उनके निर्माण की विधि पर अपने बच्चों को पैदा करने में है, लेकिन अगर गुण अपेक्षाकृत घोंसले के शिकार हैं, जब आपकी Houseअसफलता आपको पैदा करने में कुछ समय बिताएगी, जो असफल हो रहा है, ठीक करने के लिए कुछ समय बिताना होगा।

विकल्प निम्नलिखित है (निर्भरता इंजेक्शन, यदि आपको फैंसी शब्द पसंद है):

$TVObj = new TV($param1, $param2, $param3);
$LivingroomObj = new LivingRoom($TVObj, $param1, $param2);
$KitchenroomObj = new Kitchen($param1, $param2);
$HouseObj = new House($LivingroomObj, $KitchenroomObj);

यहाँ अगर Houseअसफलता पैदा करने की प्रक्रिया केवल देखने के लिए एक ही जगह है, लेकिन हर बार जब कोई नया चाहता है, तो इस ठग का उपयोग करना Houseसुविधाजनक होता है। कारखानों में प्रवेश करें:

class HouseFactory {
    public function create() {
        $TVObj = new TV($param1, $param2, $param3);
        $LivingroomObj = new LivingRoom($TVObj, $param1, $param2);
        $KitchenroomObj = new Kitchen($param1, $param2);
        $HouseObj = new House($LivingroomObj, $KitchenroomObj);

        return $HouseObj;
    }
}

$houseFactory = new HouseFactory();
$HouseObj = $houseFactory->create();

यहाँ कारखाने के लिए धन्यवाद एक बनाने की प्रक्रिया Houseअमूर्त है (इसमें आपको हर एक निर्भरता को बनाने और सेट करने की आवश्यकता नहीं है जब आप बस बनाना चाहते हैं House) और उसी समय केंद्रीकृत होता है जो इसे बनाए रखना आसान बनाता है। अलग-अलग फैक्ट्रियों का उपयोग करने के अन्य कारण फायदेमंद हो सकते हैं (उदाहरण के लिए टेस्टीबिलिटी) लेकिन मुझे लगता है कि फैक्ट्री कक्षाएं कैसे उपयोगी हो सकती हैं, यह बताने के लिए यह विशिष्ट उपयोग मामला है।


1
हालांकि इस पर कोई इकाई परीक्षण कैसे करेगा? मुझे लगा कि कक्षा में "नया" कीवर्ड का उपयोग करना बुरा व्यवहार माना जाता है क्योंकि यह यूनिट परीक्षण नहीं किया जा सकता है। या क्या एक कारखाना उस नियम के अपवाद का एक सा है?
अगमलाउचर

1
@AgmLauncher मेरे पास भी यही सवाल था जब मैंने यूनिट परीक्षण के साथ शुरुआत की, तो देखें: stackoverflow.com/questions/10128780/…
Mahn

1
यह नहीं मिला। अलग-अलग वस्तुओं को बनाने के लिए परमात्मा को HouseFactoryकक्षा में कैसे पारित किया जाता है ?
अतियार

1
@ मेन, क्या आप अंत में बहुत से परम को प्राप्त नहीं करेंगे?
पचेरियर

1
@ स्पेसर आपको अपनी जरूरतों के आधार पर मॉडल बनाने का निर्णय लेने के लिए कुछ है, लेकिन आपको हमेशा हर पैरामीटर को createविधि से पारित करने की आवश्यकता नहीं है । उदाहरण के लिए, यदि आपका Houseहमेशा एक ही तरह का है, LivingRoomतो यह तर्क के रूप में पारित होने के बजाय फैक्ट्री क्लास में हार्ड डिस्क को अपने पैराशूट के लिए समझ में आता है। यदि आप कुछ प्रकार के हैं और प्रत्येक प्रकार के हार्डकोडेड मापदंडों के साथ अंदर स्विच करते हैं, तो आप typeअपनी HouseFactory::createपद्धति को एक तर्क प्रदान करना चाह सकते हैं LivingRoom
महन

19

फैक्ट्री या फैक्ट्री पद्धति का उपयोग करने के पीछे के विचार को स्पष्ट रूप से अलग करना महत्वपूर्ण है। दोनों ही परस्पर भिन्न प्रकार की वस्तु निर्माण समस्याओं के समाधान के लिए हैं।

चलो "कारखाना विधि" के बारे में विशिष्ट हैं:

पहली बात यह है कि, जब आप पुस्तकालय या एपीआई विकसित कर रहे होते हैं, जिसका उपयोग आगे के विकास के लिए किया जाता है, तो कारखाना पद्धति निर्माण पैटर्न के लिए सबसे अच्छे चयनों में से एक है। पीछे कारण; हम जानते हैं कि जब आवश्यक कार्यक्षमता (ऑब्जेक्ट्स) का निर्माण करना है, लेकिन ऑब्जेक्ट का प्रकार अनिर्धारित रहेगा या यह तय किया जाएगा कि पास किए गए डायनामिक पैरामीटर क्या हैं

अब बिंदु यह है कि लगभग एक ही कारखाने के पैटर्न का उपयोग करके प्राप्त किया जा सकता है, लेकिन एक बहुत बड़ी खामी इस प्रणाली में लागू होगी यदि फैक्टरी पैटर्न का उपयोग ऊपर हाइलाइट की गई समस्या के लिए किया जाएगा, तो यह है कि विभिन्न वस्तुओं (सब क्लास ऑब्जेक्ट्स) को बनाने का आपका तर्क होगा भविष्य में कुछ व्यावसायिक स्थितियों के लिए विशिष्ट होना चाहिए जब आपको अपनी लाइब्रेरी की कार्यक्षमता को अन्य प्लेटफार्मों के लिए विस्तारित करने की आवश्यकता होती है (अधिक तकनीकी रूप से, आपको बुनियादी इंटरफ़ेस या अमूर्त वर्ग के अधिक उप वर्गों को जोड़ने की आवश्यकता है ताकि कारखाना उन वस्तुओं को वापस कर सके जो मौजूदा एक के अलावा भी हैं। कुछ गतिशील मापदंडों के आधार पर) तो हर बार आपको फैक्ट्री वर्ग के तर्क को बदलना (विस्तार) करना होगा जो महंगा ऑपरेशन होगा और डिजाइन के नजरिए से अच्छा नहीं होगा। दूसरी तरफ, अगर "कारखाना विधि"

interface Deliverable 
{
    /*********/
}

abstract class DefaultProducer 
{

    public void taskToBeDone() 
    {   
        Deliverable deliverable = factoryMethodPattern();
    }
    protected abstract Deliverable factoryMethodPattern();
}

class SpecificDeliverable implements Deliverable 
{
 /***SPECIFIC TASK CAN BE WRITTEN HERE***/
}

class SpecificProducer extends DefaultProducer 
{
    protected Deliverable factoryMethodPattern() 
    {
        return new SpecificDeliverable();
    }
}

public class MasterApplicationProgram 
{
    public static void main(String arg[]) 
    {
        DefaultProducer defaultProducer = new SpecificProducer();
        defaultProducer.taskToBeDone();
    }
}

15

वे भी उपयोगी होते हैं जब आपको एक ही पैरामीटर प्रकार के साथ लेकिन अलग-अलग व्यवहार के साथ कई "कंस्ट्रक्टर्स" की आवश्यकता होती है।


15

जब वस्तु के अंदर कारखाने के तरीकों का उपयोग करना अच्छा होता है:

  1. ऑब्जेक्ट की कक्षा को यह पता नहीं है कि इसे बनाने के लिए कौन-सी उप-कक्षाएं हैं
  2. ऑब्जेक्ट की कक्षा को इस तरह डिज़ाइन किया गया है कि यह जो ऑब्जेक्ट बनाता है वह सब-क्लास द्वारा निर्दिष्ट किया गया था
  3. ऑब्जेक्ट की कक्षा सहायक उप-वर्गों के लिए अपने कर्तव्यों को सौंपती है और यह नहीं जानती है कि सटीक वर्ग इन कर्तव्यों को क्या करेगा

अमूर्त कारखाना वर्ग का उपयोग करना कब अच्छा है:

  1. आपकी वस्तु इस बात पर निर्भर नहीं होनी चाहिए कि उसकी आंतरिक वस्तुएँ कैसे बनाई और डिज़ाइन की गई हैं
  2. लिंक की गई वस्तुओं के समूह का एक साथ उपयोग किया जाना चाहिए और आपको इस बाधा की सेवा करने की आवश्यकता है
  3. ऑब्जेक्ट को लिंक की गई वस्तुओं के कई संभावित परिवारों में से एक द्वारा कॉन्फ़िगर किया जाना चाहिए जो आपके मूल ऑब्जेक्ट का एक हिस्सा होगा
  4. यह केवल एक कार्यान्वयन नहीं बल्कि इंटरफेस दिखाने वाले बाल वस्तुओं को साझा करने के लिए आवश्यक है

9

से यू.एम.एल.

यहां छवि विवरण दर्ज करें

उत्पाद: यह उन वस्तुओं के एक इंटरफ़ेस को परिभाषित करता है जो फैक्टरी विधि बनाती है।

कंक्रीटप्रोडक्ट: इम्प्लीमेंट्स उत्पाद इंटरफ़ेस

निर्माता: फैक्टरी विधि की घोषणा करता है

ConcreateCreator: एक कंक्रीटप्रोडक्ट की आवृत्ति वापस करने के लिए फ़ैक्टरी विधि लागू करता है

समस्या कथन: फ़ैक्टरी विधियों का उपयोग करके खेलों का एक कारखाना बनाएँ, जो खेल इंटरफ़ेस को परिभाषित करता है।

सांकेतिक टुकड़ा:

import java.util.HashMap;


/* Product interface as per UML diagram */
interface Game{
    /* createGame is a complex method, which executes a sequence of game steps */
    public void createGame();
}

/* ConcreteProduct implementation as per UML diagram */
class Chess implements Game{
    public Chess(){

    }
    public void createGame(){
        System.out.println("---------------------------------------");
        System.out.println("Create Chess game");
        System.out.println("Opponents:2");
        System.out.println("Define 64 blocks");
        System.out.println("Place 16 pieces for White opponent");
        System.out.println("Place 16 pieces for Black opponent");
        System.out.println("Start Chess game");
        System.out.println("---------------------------------------");
    }
}
class Checkers implements Game{
    public Checkers(){

    }
    public void createGame(){
        System.out.println("---------------------------------------");
        System.out.println("Create Checkers game");
        System.out.println("Opponents:2 or 3 or 4 or 6");
        System.out.println("For each opponent, place 10 coins");
        System.out.println("Start Checkers game");
        System.out.println("---------------------------------------");
    }
}
class Ludo implements Game{
    public Ludo(){

    }
    public void createGame(){
        System.out.println("---------------------------------------");
        System.out.println("Create Ludo game");
        System.out.println("Opponents:2 or 3 or 4");
        System.out.println("For each opponent, place 4 coins");
        System.out.println("Create two dices with numbers from 1-6");
        System.out.println("Start Ludo game");
        System.out.println("---------------------------------------");
    }
}

/* Creator interface as per UML diagram */
interface IGameFactory {
    public Game getGame(String gameName);
}

/* ConcreteCreator implementation as per UML diagram */
class GameFactory implements IGameFactory {

     HashMap<String,Game> games = new HashMap<String,Game>();
    /*  
        Since Game Creation is complex process, we don't want to create game using new operator every time.
        Instead we create Game only once and store it in Factory. When client request a specific game, 
        Game object is returned from Factory instead of creating new Game on the fly, which is time consuming
    */

    public GameFactory(){

        games.put(Chess.class.getName(),new Chess());
        games.put(Checkers.class.getName(),new Checkers());
        games.put(Ludo.class.getName(),new Ludo());        
    }
    public Game getGame(String gameName){
        return games.get(gameName);
    }
}

public class NonStaticFactoryDemo{
    public static void main(String args[]){
        if ( args.length < 1){
            System.out.println("Usage: java FactoryDemo gameName");
            return;
        }

        GameFactory factory = new GameFactory();
        Game game = factory.getGame(args[0]);
        if ( game != null ){                    
            game.createGame();
            System.out.println("Game="+game.getClass().getName());
        }else{
            System.out.println(args[0]+  " Game does not exists in factory");
        }           
    }
}

उत्पादन:

java NonStaticFactoryDemo Chess
---------------------------------------
Create Chess game
Opponents:2
Define 64 blocks
Place 16 pieces for White opponent
Place 16 pieces for Black opponent
Start Chess game
---------------------------------------
Game=Chess

यह उदाहरण एक Factoryवर्ग को लागू करके दिखाता है FactoryMethod

  1. Gameसभी प्रकार के खेलों के लिए इंटरफ़ेस है। यह जटिल विधि को परिभाषित करता है:createGame()

  2. Chess, Ludo, Checkers खेलों के विभिन्न प्रकार हैं, जो कार्यान्वयन प्रदान करते हैं createGame()

  3. public Game getGame(String gameName)है FactoryMethodमें IGameFactoryवर्ग

  4. GameFactoryकंस्ट्रक्टर में विभिन्न प्रकार के खेल पूर्व-निर्मित होते हैं। यह IGameFactoryकारखाना विधि को लागू करता है ।

  5. गेम का नाम कमांड लाइन तर्क के रूप में दिया गया है NotStaticFactoryDemo

  6. getGameमें GameFactoryएक खेल का नाम है और इसी रिटर्न स्वीकार करता है Gameवस्तु।

फैक्टरी:

क्लाइंट के लिए तात्कालिकता तर्क को उजागर किए बिना ऑब्जेक्ट बनाता है।

FactoryMethod

एक ऑब्जेक्ट बनाने के लिए एक इंटरफ़ेस को परिभाषित करें, लेकिन उपवर्गों को यह तय करने दें कि किस वर्ग को त्वरित करना है। फैक्ट्री पद्धति उपवर्गों को एक क्लास डिफरेंट इंस्टालेशन की सुविधा देती है

उदाहरण:

उपयोग कब करें: Clientरनटाइम के दौरान कौन सी ठोस कक्षाएं बनाने की आवश्यकता होगी, यह नहीं पता, लेकिन बस एक वर्ग प्राप्त करना चाहता है जो काम करेगा।


आप के लिए धन्यवाद, आप इसे नोट कर सकते हैं। यह मेरे लिए संक्षिप्त है। लेकिन, यह अकल्पनीय है कि "getArea () शेप इंटरफेस में फैक्ट्री मेथड है", क्योंकि मेथड getArea कभी भी किसी भी क्लास में नहीं आता है, यह सिर्फ एक गणना करता है। "यह परिभाषित करें कि" परिभाषित करें। ऑब्जेक्ट बनाने के लिए इंटरफ़ेस, लेकिन उपवर्गों को यह तय करने दें कि कौन सी क्लास को "तुरंत" करें।
Reco

getArea()एक कारखाने की विधि बिल्कुल नहीं है
21

1
मेरी एक अलग राय है - विशेषज्ञ कृपया मान्य करें और नोट डालें। 1. ग्राहक (या आक्रमणकारी) को ब्याज की वस्तु की आवश्यकता होती है ... इसलिए नए GameFactory () को कॉल करने की आवश्यकता नहीं होनी चाहिए, बल्कि फैक्ट्री क्लास में स्थिर getInstance () 2. होना चाहिए। यदि ऐसा है तो games.put (Chess.class.getName) ), नया शतरंज (); हमेशा शतरंज के उसी संदर्भ को लौटाएगा [अगर इसे स्थैतिक के रूप में लागू किया जाए] - उस परिदृश्य को सबसे प्रभावी तरीके से कैसे प्रबंधित किया जाए?
अर्नब दत्ता

मैंने गैर-स्थैतिक कारखाने का उदाहरण दिया है। आप चाहें तो इसे स्टैटिक ब्लॉक और तरीकों के साथ लागू कर सकते हैं। आपके प्रश्नों के बारे में: १। गेम प्राप्त करने के लिए क्लाइंट फैक्टरी को कॉल करेगा। 2. मैं एक बार ऑब्जेक्ट डाल रहा हूं और सभी गेट एक ही उदाहरण लौटाएंगे - वही रेस्पेक्ट। शतरंज का हर रिटर्न मिलता है
रवींद्र बाबू

6

यह वास्तव में स्वाद की बात है। कारखाने की कक्षाओं को आवश्यक रूप से अलग किया जा सकता है / बाधित किया जा सकता है, जबकि कारखाने के तरीके हल्के वजन के होते हैं (और परीक्षण योग्य भी होते हैं, क्योंकि उनके पास परिभाषित प्रकार नहीं होता है, लेकिन उन्हें एक सेवा के लिए एक प्रसिद्ध पंजीकरण बिंदु की आवश्यकता होती है। लोकेटर लेकिन कारखाने के तरीकों का पता लगाने के लिए)।


4

फैक्ट्री कक्षाएं तब उपयोगी होती हैं जब ऑब्जेक्ट प्रकार जो वे वापस करते हैं, एक निजी कंस्ट्रक्टर होता है, जब अलग-अलग फैक्ट्री कक्षाएं रिटर्निंग ऑब्जेक्ट पर अलग-अलग गुण सेट करती हैं, या जब एक विशिष्ट फैक्ट्री प्रकार अपने रिटर्निंग कंक्रीट प्रकार के साथ युग्मित होता है।

WCF विभिन्न स्थितियों में ServiceHost ऑब्जेक्ट्स को पुनः प्राप्त करने के लिए ServiceHostFactory कक्षाओं का उपयोग करता है। मानक ServiceHostFactory के लिए ServiceHost उदाहरणों को पुनः प्राप्त करने का उपयोग IIS .svc फ़ाइलें, लेकिन एक WebScriptServiceHostFactory सेवाओं के लिए प्रयोग किया जाता है कि जावास्क्रिप्ट ग्राहकों को वापसी serializations। ADO.NET Data Services का अपना एक विशेष DataServiceHostFactory है और ASP.NET का अपना ApplicationServicesHostFactory है क्योंकि इसकी सेवाओं में निजी कंस्ट्रक्टर हैं।

यदि आपके पास केवल एक वर्ग है जो कारखाने का उपभोग कर रहा है, तो आप बस उस वर्ग के भीतर एक कारखाना विधि का उपयोग कर सकते हैं।


2

एक परिदृश्य पर विचार करें जब आपको ऑर्डर और ग्राहक वर्ग डिज़ाइन करना होगा। सादगी और प्रारंभिक आवश्यकताओं के लिए आपको ऑर्डर क्लास के लिए कारखाने की आवश्यकता महसूस नहीं होती है और अपने आवेदन को कई 'नए ऑर्डर ()' कथनों से भरना होता है। चीजें अच्छी तरह से काम कर रही हैं।

अब एक नई आवश्यकता चित्र में आती है कि ऑर्डर ऑब्जेक्ट को ग्राहक संघ (नई निर्भरता) के बिना तत्काल नहीं किया जा सकता है। अब आपके पास निम्नलिखित विचार हैं।

1- आप कंस्ट्रक्टर ओवरलोड बनाते हैं जो केवल नए कार्यान्वयन के लिए काम करेगा। (स्वीकार्य नहीं है)। 2- आप ऑर्डर () हस्ताक्षरों को बदलते हैं और प्रत्येक और प्रत्येक इनवोकेशन को बदलते हैं। (एक अच्छा अभ्यास और वास्तविक दर्द नहीं)।

इसके बजाय यदि आपने ऑर्डर क्लास के लिए एक कारखाना बनाया है तो आपको केवल एक लाइन कोड को बदलना होगा और आप जाने के लिए अच्छे हैं। मेरा सुझाव है कि लगभग हर कुल संघ के लिए कारखाना वर्ग। उम्मीद है की वो मदद करदे।


1

यदि आप उपयोग करने के संदर्भ में एक अलग वस्तु बनाना चाहते हैं। यह उपयोगी है।

public class factoryMethodPattern {
      static String planName = "COMMERCIALPLAN";
      static int units = 3;
      public static void main(String args[]) {
          GetPlanFactory planFactory = new GetPlanFactory();
          Plan p = planFactory.getPlan(planName);
          System.out.print("Bill amount for " + planName + " of  " + units
                        + " units is: ");
          p.getRate();
          p.calculateBill(units);
      }
}

abstract class Plan {
      protected double rate;

      abstract void getRate();

      public void calculateBill(int units) {
            System.out.println(units * rate);
      }
}

class DomesticPlan extends Plan {
      // @override
      public void getRate() {
            rate = 3.50;
      }
}

class CommercialPlan extends Plan {
      // @override
      public void getRate() {
            rate = 7.50;
      }
}

class InstitutionalPlan extends Plan {
      // @override
      public void getRate() {
            rate = 5.50;
      }
}

class GetPlanFactory {

      // use getPlan method to get object of type Plan
      public Plan getPlan(String planType) {
            if (planType == null) {
                  return null;
            }
            if (planType.equalsIgnoreCase("DOMESTICPLAN")) {
                  return new DomesticPlan();
            } else if (planType.equalsIgnoreCase("COMMERCIALPLAN")) {
                  return new CommercialPlan();
            } else if (planType.equalsIgnoreCase("INSTITUTIONALPLAN")) {
                  return new InstitutionalPlan();
            }
            return null;
      }
}

1

किसी भी वर्ग को जिस वस्तु के साथ काम करने की आवश्यकता होती है, उसके लिए अपने उप-वर्ग को ऑब्जेक्ट निर्माण को संदर्भित करते हुए फैक्टरी पैटर्न के उदाहरण के रूप में देखा जा सकता है।

मैंने https://stackoverflow.com/a/49110001/504133 पर एक अन्य उत्तर में विस्तार से उल्लेख किया है


1

मुझे लगता है कि यह ढीली युग्मन डिग्री पर निर्भर करेगा जिसे आप अपने कोड में लाना चाहते हैं।

फैक्टरी विधि बहुत अच्छी तरह से चीजों को डिकॉय करती है लेकिन फैक्ट्री क्लास नं।

दूसरे शब्दों में, यदि आप कारखाने की विधि का उपयोग करते हैं तो इसकी तुलना में चीजों को बदलना आसान है यदि आप एक साधारण कारखाने (जिसे कारखाना वर्ग के रूप में जाना जाता है) का उपयोग करते हैं।

इस उदाहरण में देखें: https://connected2know.com/programming/java-factory-pattern/ । अब, कल्पना करें कि आप एक नया पशु लाना चाहते हैं। फैक्ट्री क्लास में आपको फैक्ट्री बदलने की आवश्यकता होती है, लेकिन फैक्ट्री विधि में, नहीं, आपको केवल एक नया उपवर्ग जोड़ने की जरूरत है।


0

फ़ैक्टरी कक्षाएं अधिक भारी होती हैं, लेकिन आपको कुछ फायदे देती हैं। ऐसे मामलों में जब आपको कई, कच्चे डेटा स्रोतों से अपनी वस्तुओं का निर्माण करने की आवश्यकता होती है, तो वे आपको एक ही स्थान पर केवल बिल्डिंग लॉजिक (और शायद डेटा का एकत्रीकरण) को एनकैप्सुलेट करने की अनुमति देते हैं। वहां इसे ऑब्जेक्ट इंटरफ़ेस से संबंधित किए बिना अमूर्त में परीक्षण किया जा सकता है।

मुझे यह एक उपयोगी पैटर्न मिला है, खासकर जहां मैं ओआरएम को बदलने और अपर्याप्त करने में असमर्थ हूं और डीबी टेबल जॉइन या स्टोर की गई प्रक्रियाओं से कई वस्तुओं को कुशलता से निकालना चाहता हूं।


0

मैं कारखानों को पुस्तकालयों की अवधारणा के लिए पसंद करता हूं। उदाहरण के लिए आपके पास संख्याओं के साथ काम करने के लिए एक पुस्तकालय और आकृतियों के साथ काम करने के लिए दूसरा हो सकता है। आप इन पुस्तकालयों के कार्यों को तार्किक रूप से नामित निर्देशिकाओं में Numbersया के रूप में संग्रहीत कर सकते हैं Shapes। ये सामान्य प्रकार हैं जो आकृतियों के मामले में पूर्णांक, फ़्लोट, डब्यूल्स, लॉन्ग या आयताकार, सर्कल, त्रिकोण, पेंटागन शामिल कर सकते हैं।

फैक्ट्री पेटर पॉलीमोर्फिज़्म, निर्भरता इंजेक्शन और नियंत्रण के व्युत्क्रम का उपयोग करता है।

फैक्ट्री पैटर्न का घोषित उद्देश्य है: Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

तो मान लीजिए कि आप एक ऑपरेटिंग सिस्टम या फ्रेमवर्क बना रहे हैं और आप सभी असतत घटकों का निर्माण कर रहे हैं।

यहाँ PHP में फ़ैक्टरी पैटर्न की अवधारणा का एक सरल उदाहरण है। मैं इस सब पर 100% नहीं हो सकता लेकिन यह एक सरल उदाहरण के रूप में सेवा करने का इरादा है। मैं एक विशेषज्ञ नहीं हूं।

class NumbersFactory {
    public static function makeNumber( $type, $number ) {
        $numObject = null;
        $number = null;

        switch( $type ) {
            case 'float':
                $numObject = new Float( $number );
                break;
            case 'integer':
                $numObject = new Integer( $number );
                break;
            case 'short':
                $numObject = new Short( $number );
                break;
            case 'double':
                $numObject = new Double( $number );
                break;
            case 'long':
                $numObject = new Long( $number );
                break;
            default:
                $numObject = new Integer( $number );
                break;
        }

        return $numObject;
    }
}

/* Numbers interface */
abstract class Number {
    protected $number;

    public function __construct( $number ) {
        $this->number = $number;
    }

    abstract public function add();
    abstract public function subtract();
    abstract public function multiply();
    abstract public function divide();
}
/* Float Implementation */
class Float extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}
/* Integer Implementation */
class Integer extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}
/* Short Implementation */
class Short extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}
/* Double Implementation */
class Double extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}
/* Long Implementation */
class Long extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}

$number = NumbersFactory::makeNumber( 'float', 12.5 );

मैं समझता हूं कि यहां क्या हो रहा है, लेकिन मुझे नहीं लगता कि इसका क्या मतलब है। अगर मुझे पता है कि मुझे जरूरत है तो मैं क्या NumbersFactory::makeNumber( 'float', 12.5 );कह new Float(12.5);रहा हूं Float? यह वही है जो मैं कारखानों के बारे में नहीं समझता ... क्या बात है?
बैडहोरसी

यह आपको अलग-अलग कार्यान्वयन चुनने देता है और आपको केवल एक के लिए बाध्य नहीं करता है। एक इंटरफ़ेस स्थापित है और सभी कार्यान्वयनों को इसकी गारंटी और सम्मान देना चाहिए।
रॉबर्ट रोचा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.