CodeGym /Java Blog /अनियमित /डिजाइन पैटर्न: सार कारखाना
John Squirrels
स्तर 41
San Francisco

डिजाइन पैटर्न: सार कारखाना

अनियमित ग्रुप में प्रकाशित
नमस्ते! आज हम डिजाइन पैटर्न का अध्ययन करना जारी रखेंगे और हम एब्स्ट्रैक्ट फैक्ट्री पैटर्न पर चर्चा करेंगे। डिजाइन पैटर्न: सार कारखाना - 1यहाँ हम पाठ में क्या शामिल करेंगे:
  • हम चर्चा करेंगे कि अमूर्त कारखाना क्या है और यह पैटर्न किस समस्या का समाधान करता है
  • हम यूजर इंटरफेस के माध्यम से कॉफी ऑर्डर करने के लिए एक क्रॉस-प्लेटफॉर्म एप्लिकेशन का कंकाल तैयार करेंगे
  • हम आरेख और कोड को देखने सहित इस पैटर्न का उपयोग करने के निर्देशों का अध्ययन करेंगे
  • और एक बोनस के रूप में, इस पाठ में एक छिपा हुआ ईस्टर अंडा शामिल है जो आपको यह सीखने में मदद करेगा कि ऑपरेटिंग सिस्टम का नाम निर्धारित करने के लिए जावा का उपयोग कैसे करें और, परिणाम के आधार पर, एक या दूसरे क्रिया को करने के लिए।
इस पैटर्न को पूरी तरह से समझने के लिए, आपको निम्नलिखित विषयों से अच्छी तरह वाकिफ होना चाहिए:
  • जावा में विरासत
  • जावा में सार वर्ग और तरीके

एक अमूर्त कारखाना किन समस्याओं का समाधान करता है?

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

आइए अपनी कॉफी शॉप को स्वचालित करना जारी रखें

आखिरी पाठ में, हमने फ़ैक्टरी विधि पैटर्न का अध्ययन किया। हमने इसका उपयोग अपने कॉफी व्यवसाय का विस्तार करने और कई नए स्थान खोलने के लिए किया। आज हम अपने व्यवसाय का आधुनिकीकरण करना जारी रखेंगे। एब्स्ट्रैक्ट फैक्ट्री पैटर्न का उपयोग करते हुए, हम ऑनलाइन कॉफी ऑर्डर करने के लिए एक नए डेस्कटॉप एप्लिकेशन की नींव रखेंगे। डेस्कटॉप एप्लिकेशन लिखते समय, हमें हमेशा क्रॉस-प्लेटफ़ॉर्म समर्थन के बारे में सोचना चाहिए। हमारे एप्लिकेशन को macOS और Windows दोनों पर काम करना चाहिए (स्पॉइलर: लिनक्स के लिए समर्थन आपके लिए होमवर्क के रूप में लागू करने के लिए छोड़ दिया गया है)। हमारा आवेदन कैसा दिखेगा? बहुत सरल: यह एक टेक्स्ट फ़ील्ड, एक चयन फ़ील्ड और एक बटन वाला एक फॉर्म होगा। यदि आपके पास विभिन्न ऑपरेटिंग सिस्टम का उपयोग करने का अनुभव है, तो आपने निश्चित रूप से देखा है कि मैक की तुलना में विंडोज पर बटन अलग-अलग तरीके से प्रस्तुत किए जाते हैं। जैसा कि बाकी सब कुछ है... अच्छा, चलिए शुरू करते हैं।
  • बटन
  • पाठ क्षेत्र
  • चयन क्षेत्रों
अस्वीकरण: प्रत्येक इंटरफ़ेस में, हम onClick, onValueChanged, या जैसे तरीकों को परिभाषित कर सकते हैं onInputChanged। दूसरे शब्दों में, हम उन तरीकों को परिभाषित कर सकते हैं जो हमें विभिन्न घटनाओं (एक बटन दबाकर, टेक्स्ट दर्ज करना, चयन बॉक्स में एक मान का चयन करना) को संभालने की अनुमति देगा। यह सब जानबूझकर यहां छोड़ दिया गया है ताकि उदाहरण को अधिभारित न किया जा सके और फैक्ट्री पैटर्न का अध्ययन करते समय इसे स्पष्ट किया जा सके। आइए हमारे उत्पादों के लिए अमूर्त इंटरफेस को परिभाषित करें:

public interface Button {}
public interface Select {}
public interface TextField {}
प्रत्येक ऑपरेटिंग सिस्टम के लिए, हमें ऑपरेटिंग सिस्टम की शैली में इंटरफ़ेस तत्वों का निर्माण करना चाहिए। हम Windows और MacOS के लिए कोड लिख रहे हैं। आइए विंडोज के लिए कार्यान्वयन बनाएं:

public class WindowsButton implements Button {
}

public class WindowsSelect implements Select {
}

public class WindowsTextField implements TextField {
}
अब हम MacOS के लिए भी ऐसा ही करते हैं:

public class MacButton implements Button {
}

public class MacSelect implements Select {
}

public class MacTextField implements TextField {
}
उत्कृष्ट। अब हम अपने अमूर्त कारखाने में आगे बढ़ सकते हैं, जो सभी उपलब्ध अमूर्त उत्पाद प्रकारों का निर्माण करेगा:

public interface GUIFactory {

    Button createButton();
    TextField createTextField();
    Select createSelect();

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

public class WindowsGUIFactory implements GUIFactory {
    public WindowsGUIFactory() {
        System.out.println("Creating GUIFactory for Windows OS");
    }

    public Button createButton() {
        System.out.println("Creating Button for Windows OS");
        return new WindowsButton();
    }

    public TextField createTextField() {
        System.out.println("Creating TextField for Windows OS");
        return new WindowsTextField();
    }

    public Select createSelect() {
        System.out.println("Creating Select for Windows OS");
        return new WindowsSelect();
    }
}
क्या हो रहा है, इसे और स्पष्ट करने के लिए हमने मेथड्स और कंस्ट्रक्टर के अंदर कुछ कंसोल आउटपुट जोड़े हैं। अब macOS के लिए:

public class MacGUIFactory implements GUIFactory {
    public MacGUIFactory() {
        System.out.println("Creating GUIFactory for macOS");
    }

    @Override
    public Button createButton() {
        System.out.println("Creating Button for macOS");
        return new MacButton();
    }

    @Override
    public TextField createTextField() {
        System.out.println("Creating TextField for macOS");
        return new MacTextField();
    }

    @Override
    public Select createSelect() {
        System.out.println("Creating Select for macOS");
        return new MacSelect();
    }
}
ध्यान दें कि प्रत्येक विधि हस्ताक्षर इंगित करता है कि विधि एक सार प्रकार लौटाती है। लेकिन तरीकों के अंदर, हम उत्पादों के विशिष्ट कार्यान्वयन बना रहे हैं। यह एकमात्र ऐसा स्थान है जहां हम विशिष्ट उदाहरणों के निर्माण को नियंत्रित करते हैं। अब फॉर्म के लिए क्लास लिखने का समय आ गया है। यह एक जावा वर्ग है जिसके क्षेत्र इंटरफ़ेस तत्व हैं:

public class CoffeeOrderForm {
    private final TextField customerNameTextField;
    private final Select coffeeTypeSelect;
    private final Button orderButton;

    public CoffeeOrderForm(GUIFactory factory) {
        System.out.println("Creating coffee order form");
        customerNameTextField = factory.createTextField();
        coffeeTypeSelect = factory.createSelect();
        orderButton = factory.createButton();
    }
}
एक सार फैक्ट्री जो इंटरफ़ेस तत्व बनाती है, फॉर्म के कन्स्ट्रक्टर को पास कर दी जाती है। हम किसी विशेष OS के लिए इंटरफ़ेस तत्व बनाने के लिए आवश्यक फ़ैक्टरी कार्यान्वयन को कंस्ट्रक्टर को पास करेंगे।

public class Application {
    private CoffeeOrderForm coffeeOrderForm;

    public void drawCoffeeOrderForm() {
        // Determine the name of the operating system through System.getProperty()
        String osName = System.getProperty("os.name").toLowerCase();
        GUIFactory guiFactory;

        if (osName.startsWith("win")) { // For Windows
            guiFactory = new WindowsGUIFactory();
        } else if (osName.startsWith("mac")) { // For Mac
            guiFactory = new MacGUIFactory();
        } else {
            System.out.println("Unknown OS. Unable to draw form :(");
            return;
        }
        coffeeOrderForm = new CoffeeOrderForm(guiFactory);
    }

    public static void main(String[] args) {
        Application application = new Application();
        application.drawCoffeeOrderForm();
    }
}
यदि हम विंडोज़ पर एप्लिकेशन चलाते हैं, तो हमें निम्न आउटपुट मिलते हैं:

Creating GUIFactory for Windows OS
Creating coffee order form
Creating TextField for Windows OS
Creating Select for Windows OS
Creating Button for Windows OS
मैक पर, आउटपुट निम्नानुसार होगा:

Creating GUIFactory for macOS
Creating coffee order form
Creating TextField for macOS
Creating Select for macOS
Creating Button for macOS
लिनक्स पर:

Unknown OS. Unable to draw form :( 
और अब हम संक्षेप करते हैं। हमने जीयूआई-आधारित एप्लिकेशन का कंकाल लिखा है जिसमें विशेष रूप से संबंधित ओएस के लिए इंटरफ़ेस तत्व बनाए गए हैं। हमने जो बनाया है उसे संक्षेप में दोहराएंगे:
  • एक उत्पाद परिवार जिसमें एक इनपुट फ़ील्ड, एक चयन फ़ील्ड और एक बटन होता है।
  • विंडोज और मैकओएस के लिए उत्पाद परिवार के विभिन्न कार्यान्वयन।
  • एक एब्स्ट्रैक्ट फ़ैक्टरी जो हमारे उत्पादों को बनाने के लिए एक इंटरफ़ेस परिभाषित करती है।
  • हमारे कारखाने के दो कार्यान्वयन, उत्पादों का एक विशिष्ट परिवार बनाने के लिए प्रत्येक जिम्मेदार।
  • एक फॉर्म (एक जावा वर्ग) जिसके क्षेत्र सार इंटरफ़ेस तत्व हैं जो एक अमूर्त कारखाने का उपयोग करके निर्माता में आवश्यक मूल्यों के साथ आरंभीकृत होते हैं।
  • एप्लिकेशन क्लास इस क्लास के अंदर, हम एक फॉर्म बनाते हैं, वांछित फैक्ट्री इम्प्लीमेंटेशन को इसके कंस्ट्रक्टर को पास करते हैं।
नतीजा यह है कि हमने एब्स्ट्रैक्ट फ़ैक्टरी पैटर्न लागू किया है।

सार कारखाना: कैसे उपयोग करें

एक अमूर्त कारखाना ठोस उत्पाद वर्गों से बंधे बिना विभिन्न उत्पाद परिवारों के निर्माण के प्रबंधन के लिए एक डिज़ाइन पैटर्न है। इस पैटर्न का उपयोग करते समय, आपको चाहिए:
  1. उत्पाद परिवारों को परिभाषित करें। मान लीजिए हमारे पास उनमें से दो हैं:
    • SpecificProductA1,SpecificProductB1
    • SpecificProductA2,SpecificProductB2
  2. परिवार के भीतर प्रत्येक उत्पाद के लिए, एक सार वर्ग (इंटरफ़ेस) परिभाषित करें। हमारे मामले में, हमारे पास है:
    • ProductA
    • ProductB
  3. प्रत्येक उत्पाद परिवार के भीतर, प्रत्येक उत्पाद को चरण 2 में परिभाषित इंटरफ़ेस को लागू करना चाहिए।
  4. चरण 2 में परिभाषित प्रत्येक उत्पाद को बनाने के तरीकों के साथ एक सार कारखाना बनाएँ। हमारे मामले में, ये विधियाँ होंगी:
    • ProductA createProductA();
    • ProductB createProductB();
  5. सार कारखाना कार्यान्वयन बनाएँ ताकि प्रत्येक कार्यान्वयन एकल परिवार के उत्पादों के निर्माण को नियंत्रित करे। ऐसा करने के लिए, अमूर्त कारखाने के प्रत्येक कार्यान्वयन के अंदर, आपको सभी निर्माण विधियों को लागू करने की आवश्यकता होती है ताकि वे विशिष्ट उत्पाद कार्यान्वयन बना सकें और वापस कर सकें।
निम्नलिखित यूएमएल आरेख ऊपर बताए गए निर्देशों को दिखाता है: डिजाइन पैटर्न: सार कारखाना - 3अब हम इन निर्देशों के अनुसार कोड लिखेंगे:

    // Define common product interfaces
    public interface ProductA {}
    public interface ProductB {}

    // Create various implementations (families) of our products
    public class SpecificProductA1 implements ProductA {}
    public class SpecificProductB1 implements ProductB {}

    public class SpecificProductA2 implements ProductA {}
    public class SpecificProductB2 implements ProductB {}

    // Create an abstract factory
    public interface AbstractFactory {
        ProductA createProductA();
        ProductB createProductB();
    }

    // Implement the abstract factory in order to create products in family 1
    public class SpecificFactory1 implements AbstractFactory {

        @Override
        public ProductA createProductA() {
            return new SpecificProductA1();
        }

        @Override
        public ProductB createProductB() {
            return new SpecificProductB1();
        }
    }

    // Implement the abstract factory in order to create products in family 2
    public class SpecificFactory2 implements AbstractFactory {

        @Override
        public ProductA createProductA() {
            return new SpecificProductA2();
        }

        @Override
        public ProductB createProductB() {
            return new SpecificProductB2();
        }
    }

गृहकार्य

सामग्री को सुदृढ़ करने के लिए, आप 2 चीज़ें कर सकते हैं:
  1. कॉफ़ी-ऑर्डरिंग एप्लिकेशन को परिशोधित करें ताकि यह लिनक्स पर भी काम करे।
  2. किसी भी सैन्य रणनीति में शामिल इकाइयों के उत्पादन के लिए अपना खुद का अमूर्त कारखाना बनाएं। यह या तो वास्तविक सेनाओं से जुड़ी एक ऐतिहासिक सैन्य रणनीति हो सकती है, या orcs, gnomes और कल्पित बौने के साथ एक फंतासी हो सकती है। महत्वपूर्ण बात यह है कि कुछ ऐसा चुनें जिसमें आपकी रुचि हो। रचनात्मक बनें, कंसोल पर संदेश प्रिंट करें और पैटर्न के बारे में सीखने का आनंद लें!
टिप्पणियां
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION