java - डिजाइन पैटर्न: फैक्टरी बनाम फैक्टरी विधि बनाम सार फैक्टरी




design-patterns language-agnostic (4)

मैं एक वेबसाइट से डिजाइन पैटर्न पढ़ रहा था

वहां मैंने कारखाने, फैक्टरी विधि और सार कारखाने के बारे में पढ़ा लेकिन वे इतनी उलझन में हैं, परिभाषा पर स्पष्ट नहीं हैं। परिभाषाओं के अनुसार

फैक्ट्री - क्लाइंट को तत्काल तर्क को उजागर किए बिना ऑब्जेक्ट बनाता है और एक सामान्य इंटरफ़ेस के माध्यम से नव निर्मित ऑब्जेक्ट को संदर्भित करता है। फैक्टरी विधि का एक सरलीकृत संस्करण है

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

सार फैक्टरी - स्पष्ट रूप से अपनी कक्षाओं को निर्दिष्ट किए बिना, संबंधित वस्तुओं का एक परिवार बनाने के लिए इंटरफ़ेस प्रदान करता है।

मैंने सार फैक्ट्री बनाम फैक्टरी विधि के संबंध में अन्य स्टैक ओवरफ्लो थ्रेड भी देखे लेकिन यूएमएल आरेखों ने वहां मेरी समझ को और भी बदतर बना दिया।

क्या कोई मुझे बता सकता है

  1. ये तीन पैटर्न एक दूसरे से अलग कैसे हैं?
  2. किसका उपयोग करना है?
  3. और यदि संभव हो, तो इन पैटर्न से संबंधित किसी भी जावा उदाहरण?

  1. ये तीन पैटर्न एक दूसरे से अलग कैसे हैं?

फैक्टरी: ग्राहक को तत्काल तर्क को उजागर किए बिना वस्तुओं को बनाता है।

फैक्टरी विधि: ऑब्जेक्ट बनाने के लिए एक इंटरफ़ेस को परिभाषित करें, लेकिन उप-वर्गों को यह तय करने दें कि कौन सी कक्षा तुरंत चालू हो। कारखाने की विधि कक्षाओं को उप-वर्गों को स्थगित करने की अनुमति देती है

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

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

  1. किसका उपयोग करना है?

फैक्ट्री: क्लाइंट को सिर्फ एक कक्षा की आवश्यकता होती है और इस पर ध्यान नहीं दिया जाता है कि यह कौन सा ठोस कार्यान्वयन हो रहा है।

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

AbstactFactory: जब आपके सिस्टम को उत्पादों के कई परिवार बनाना पड़ता है या आप कार्यान्वयन विवरणों को उजागर किए बिना उत्पादों की एक लाइब्रेरी प्रदान करना चाहते हैं।

सार फैक्टरी कक्षाओं को अक्सर फैक्टरी विधि के साथ लागू किया जाता है। कारखाने के तरीके आमतौर पर टेम्पलेट विधियों के भीतर बुलाया जाता है।

  1. और यदि संभव हो, तो इन पैटर्न से संबंधित किसी भी जावा उदाहरण?

फैक्टरी और फैक्टरी विधि

आशय:

ऑब्जेक्ट बनाने के लिए एक इंटरफेस को परिभाषित करें, लेकिन उप वर्गों को यह तय करने दें कि कौन सी कक्षा को तुरंत चालू किया जाए। फैक्टरी विधि कक्षाओं को उप-वर्गों में तत्कालता को स्थगित करने देती है।

यूएमएल आरेख :

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

कंक्रीट उत्पाद : कार्यान्वयन उत्पाद इंटरफ़ेस

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

ConcreateCreator: एक ConcreteProduct के एक उदाहरण को वापस करने के लिए फैक्टरी विधि लागू करता है

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

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

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(){
        createGame();
    }
    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(){
        createGame();
    }
    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(){
        createGame();
    }
    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]);
        System.out.println("Game="+game.getClass().getName());
    }
}

उत्पादन:

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
---------------------------------------
---------------------------------------
Create Checkers game
Opponents:2 or 3 or 4 or 6
For each opponent, place 10 coins
Start Checkers game
---------------------------------------
---------------------------------------
Create Ludo game
Opponents:2 or 3 or 4
For each opponent, place 4 coins
Create two dices with numbers from 1-6
Start Ludo game
---------------------------------------
Game=Chess

यह उदाहरण Factory FactoryMethod को कार्यान्वित करके Factory क्लास FactoryMethod

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

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

  3. public Game getGame(String gameName) IGameFactory क्लास में IGameFactory

  4. GameFactory पहले GameFactory विभिन्न प्रकार के खेल बनाता है। यह IGameFactory फैक्टरी विधि लागू IGameFactory

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

  6. getGame में GameFactory एक गेम नाम स्वीकार करता है और संबंधित Game ऑब्जेक्ट देता है।

अन्य रचनात्मक पैटर्न के साथ तुलना:

  1. डिजाइन फैक्ट्री विधि (कम जटिल, अधिक अनुकूलन, सबक्लास उत्पन्न) का उपयोग शुरू करते हैं और सार फैक्ट्री, प्रोटोटाइप, या बिल्डर (अधिक लचीला, अधिक जटिल) की ओर विकसित होते हैं क्योंकि डिज़ाइनर पता लगाता है कि अधिक लचीलापन की आवश्यकता है

  2. सार फैक्ट्री कक्षाएं अक्सर फैक्ट्री विधियों के साथ कार्यान्वित की जाती हैं, लेकिन प्रोटोटाइप का उपयोग करके उन्हें भी कार्यान्वित किया जा सकता है

आगे पढ़ने के लिए संदर्भ: स्रोत निर्माण डिजाइन-पैटर्न


प्रत्येक डिजाइन पैटर्न यह सुनिश्चित करने में मदद करता है कि लिखित, कामकाजी कोड छुआ नहीं है। हम सभी जानते हैं कि एक बार जब हम कामकाजी कोड को छूते हैं, तो मौजूदा कामकाजी प्रवाह में दोष होते हैं, और यह सुनिश्चित करने के लिए बहुत अधिक परीक्षण करने की ज़रूरत है कि हमने कुछ भी तोड़ दिया नहीं है।

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

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

दोनों फैक्ट्री के पास एक दूसरे के साथ कुछ लेना देना नहीं है, इसलिए यह उन्हें विभिन्न कारखाने में रखने के लिए एक अच्छा डिजाइन है।

उम्मीद है कि यह अब स्पष्ट है। इस उदाहरण को ध्यान में रखते हुए वेबसाइट का फिर से अध्ययन करें, उम्मीद है कि इससे मदद मिलेगी। और मुझे उम्मीद है कि मैंने पैटर्न का सही ढंग से प्रतिनिधित्व किया है :)।


फैक्टरी - जटिल वस्तु बनाने के लिए अलग फैक्टरी वर्ग।

पूर्व: फल की वस्तु बनाने के लिए FruitFactory कक्षा

class FruitFactory{

public static Fruit getFruit(){...}

}

कारखाना विधि - फैक्ट्री के लिए पूरी तरह से अलग वर्ग के बजाय, उस वर्ग में एक कारखाने के रूप में केवल एक विधि जोड़ें।

उदाहरण के लिए:

Calendar.getInstance() (Java's Calendar)

सार फैक्टरी विधि - फैक्टरी की फैक्टरी

पूर्व: आइए कहें कि हम कंप्यूटर भागों के लिए कारखाना बनाना चाहते हैं। तो लैपटॉप, डेस्कटॉप, सर्वर जैसे कई प्रकार के कंप्यूटर हैं।

इसलिए प्रत्येक कंपटर प्रकार के लिए हमें कारखाने की आवश्यकता होती है। इसलिए हम नीचे कारखानों का एक उच्चस्तरीय कारखाना बनाते हैं

ComputerTypeAbstractFactory.getComputerPartFactory(String computerType) ---> This will return PartFactory which can be one of these ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

अब ये 3 खुद कारखानों हैं। (आप पार्टफैक्टरी से ही निपटेंगे, लेकिन हुड के तहत, अमूर्त कारखाने में जो कुछ भी आपने प्रदान किया है उसके आधार पर अलग-अलग कार्यान्वयन होगा)

  Interface-> PartFactory. getComputerPart(String s), 
Implementations -> ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

Usage:
new ComputerTypeAbstractFactory().getFactory(“Laptop”).getComputerPart(“RAM”)

संपादित करें: टिप्पणियों में आपत्तियों के अनुसार सार कारखाने के लिए सटीक इंटरफेस प्रदान करने के लिए संपादित किया गया।


AbstractProductA, A1 and A2 both implementing the AbstractProductA
AbstractProductB, B1 and B2 both implementing the AbstractProductB

interface Factory {
    AbstractProductA getProductA(); //Factory Method - generate A1/A2
}

फैक्टरी विधि का उपयोग, उपयोगकर्ता AbstractProductA के ए 1 या ए 2 बनाने में सक्षम हो सकता है।

interface AbstractFactory {
    AbstractProductA getProductA(); //Factory Method
    AbstractProductB getProductB(); //Factory Method
}

लेकिन सार कारखाने में 1 से अधिक फैक्ट्री विधि (पूर्व: 2 फैक्ट्री विधियां) हैं, उन फैक्ट्री विधियों का उपयोग करके यह ऑब्जेक्ट्स / संबंधित ऑब्जेक्ट्स का सेट तैयार करेगी। सार फैक्टरी का उपयोग करके, उपयोगकर्ता एबी, बी 1 ऑब्जेक्ट्स एब्स्ट्रक्ट प्रोडक्टा, एब्स्ट्रक्ट प्रोडक्ट बी





factory-method