CodeGym /Java Blog /यादृच्छिक /डिझाइन नमुने: अमूर्त कारखाना
John Squirrels
पातळी 41
San Francisco

डिझाइन नमुने: अमूर्त कारखाना

यादृच्छिक या ग्रुपमध्ये प्रकाशित केले
हाय! आज आपण डिझाइन पॅटर्नचा अभ्यास करत राहू आणि अमूर्त फॅक्टरी पॅटर्नवर चर्चा करू. डिझाइन पॅटर्न: अ‍ॅबस्ट्रॅक्ट फॅक्टरी - १आम्ही धड्यात काय कव्हर करू ते येथे आहे:
  • अ‍ॅबस्ट्रॅक्ट फॅक्टरी म्हणजे काय आणि हा पॅटर्न कोणत्या समस्येचे निराकरण करतो यावर आम्ही चर्चा करू
  • आम्ही वापरकर्ता इंटरफेसद्वारे कॉफी ऑर्डर करण्यासाठी क्रॉस-प्लॅटफॉर्म अनुप्रयोगाचा सांगाडा तयार करू
  • आकृती आणि कोड पाहण्यासह हा नमुना कसा वापरायचा यावरील सूचनांचा अभ्यास करू
  • आणि बोनस म्हणून, या धड्यात छुपे ईस्टर अंडी समाविष्ट आहे जी तुम्हाला ऑपरेटिंग सिस्टमचे नाव निश्चित करण्यासाठी आणि परिणामानुसार, एक किंवा दुसरी क्रिया करण्यासाठी Java कसे वापरावे हे शिकण्यास मदत करेल.
हा नमुना पूर्णपणे समजून घेण्यासाठी, तुम्हाला खालील विषयांमध्ये पारंगत असणे आवश्यक आहे:
  • जावा मध्ये वारसा
  • जावा मधील अमूर्त वर्ग आणि पद्धती

अमूर्त कारखाना कोणत्या समस्या सोडवतो?

एक अमूर्त कारखाना, सर्व फॅक्टरी नमुन्यांप्रमाणे, नवीन वस्तू योग्यरित्या तयार केल्या जातील याची खात्री करण्यात आम्हाला मदत करते. आम्ही ते एकमेकांशी जोडलेल्या वस्तूंच्या विविध कुटुंबांचे "उत्पादन" व्यवस्थापित करण्यासाठी वापरतो. एकमेकांशी जोडलेल्या वस्तूंची विविध कुटुंबे... याचा अर्थ काय? काळजी करू नका: सराव मध्ये, सर्वकाही दिसते त्यापेक्षा सोपे आहे. सुरुवातीला, एकमेकांशी जोडलेल्या वस्तूंचे कुटुंब काय असू शकते? समजा आम्ही अनेक प्रकारच्या युनिट्सचा समावेश असलेली लष्करी रणनीती विकसित करत आहोत:
  • पायदळ
  • घोडदळ
  • धनुर्धारी
या प्रकारचे युनिट्स एकमेकांशी जोडलेले आहेत, कारण ते एकाच सैन्यात काम करतात. आम्ही असे म्हणू शकतो की वर सूचीबद्ध केलेल्या श्रेणी एकमेकांशी जोडलेल्या वस्तूंचे कुटुंब आहेत. हे आम्हाला समजते. परंतु अमूर्त कारखाना नमुना परस्पर जोडलेल्या वस्तूंच्या विविध कुटुंबांच्या निर्मितीची व्यवस्था करण्यासाठी वापरला जातो. इथेही काहीही क्लिष्ट नाही. चला लष्करी रणनीतीच्या उदाहरणासह पुढे जाऊ या. सर्वसाधारणपणे, लष्करी तुकड्या अनेक वेगवेगळ्या लढाऊ पक्षांशी संबंधित असतात. ते कोणाच्या बाजूने आहेत यावर अवलंबून, लष्करी युनिट्सचे स्वरूप लक्षणीय बदलू शकते. रोमन सैन्यातील पायदळ सैनिक, घोडेस्वार आणि धनुर्धारी हे वायकिंग पायदळ सैनिक, घोडेस्वार आणि धनुर्धारी सारखे नाहीत. लष्करी रणनीतीमध्ये, वेगवेगळ्या सैन्याचे सैनिक एकमेकांशी जोडलेल्या वस्तूंचे वेगवेगळे कुटुंब आहेत. जर एखादा प्रोग्रामर असेल तर ते मजेदार होईल या चुकीमुळे नेपोलियनच्या काळातील फ्रेंच गणवेशातील एक सैनिक, तयार मस्केट, रोमन पायदळाच्या तुकड्यांमध्ये फिरताना दिसला. या समस्येचे निराकरण करण्यासाठी अमूर्त फॅक्टरी डिझाइन नमुना तंतोतंत आवश्यक आहे. नाही, वेळेच्या प्रवासातून येऊ शकणार्‍या पेचाची समस्या नाही, परंतु परस्पर जोडलेल्या वस्तूंचे विविध गट तयार करण्याची समस्या आहे. एक अमूर्त कारखाना सर्व उपलब्ध उत्पादने (वस्तूंचे एक कुटुंब) तयार करण्यासाठी इंटरफेस प्रदान करते. अ‍ॅबस्ट्रॅक्ट फॅक्टरीमध्ये सामान्यत: एकाधिक अंमलबजावणी असते. त्यापैकी प्रत्येक कुटुंबातील एकाची उत्पादने तयार करण्यासाठी जबाबदार आहे. आमच्या लष्करी रणनीतीमध्ये एक अमूर्त कारखाना समाविष्ट असेल जो अमूर्त पायदळ सैनिक, धनुर्धारी आणि घोडदळ तयार करेल तसेच या कारखान्याची अंमलबजावणी करेल. उदाहरणार्थ, एक कारखाना जो रोमन सैन्यदल तयार करतो आणि एक कारखाना जो कार्थॅजिनियन सैनिक तयार करतो. अ‍ॅब्स्ट्रॅक्शन हे या पॅटर्नचे सर्वात महत्त्वाचे मार्गदर्शक तत्त्व आहे. फॅक्टरीचे क्लायंट फॅक्टरी आणि त्याच्या उत्पादनांसोबत फक्त अमूर्त इंटरफेसद्वारे काम करतात. परिणामी, सध्या कोणते सैनिक तयार केले जात आहेत याचा विचार करण्याची गरज नाही. त्याऐवजी, तुम्ही ही जबाबदारी अमूर्त कारखान्याच्या काही ठोस अंमलबजावणीकडे द्या.

चला आमचे कॉफी शॉप स्वयंचलित करणे सुरू ठेवूया

शेवटच्या धड्यात, आम्ही कारखाना पद्धतीचा अभ्यास केला. आम्ही आमच्या कॉफी व्यवसायाचा विस्तार करण्यासाठी आणि अनेक नवीन स्थाने उघडण्यासाठी याचा वापर केला. आज आम्ही आमच्या व्यवसायाचे आधुनिकीकरण करत राहू. अ‍ॅबस्ट्रॅक्ट फॅक्टरी पॅटर्नचा वापर करून, आम्ही ऑनलाइन कॉफी ऑर्डर करण्यासाठी नवीन डेस्कटॉप ऍप्लिकेशनचा पाया घालू. डेस्कटॉप ऍप्लिकेशन लिहिताना, आम्ही नेहमी क्रॉस-प्लॅटफॉर्म समर्थनाचा विचार केला पाहिजे. आमचा ऍप्लिकेशन macOS आणि Windows या दोन्हींवर काम करायचा आहे (स्पॉयलर: Linux साठी सपोर्ट तुमच्यासाठी गृहपाठ म्हणून अंमलात आणण्यासाठी बाकी आहे). आमचा अर्ज कसा दिसेल? अगदी सोपे: हा मजकूर फील्ड, निवड फील्ड आणि एक बटण असलेला एक फॉर्म असेल. तुम्हाला भिन्न ऑपरेटिंग सिस्टम वापरण्याचा अनुभव असल्यास, तुमच्या लक्षात आले असेल की Windows वरील बटणे Mac पेक्षा वेगळ्या पद्धतीने प्रस्तुत केली जातात. इतर सर्व गोष्टींप्रमाणे... ठीक आहे, चला सुरुवात करूया.
  • बटणे
  • मजकूर फील्ड
  • निवड फील्ड
अस्वीकरण: प्रत्येक इंटरफेसमध्ये, आम्ही 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();

}
उत्कृष्ट. जसे आपण पाहू शकता, आम्ही अद्याप काहीही क्लिष्ट केलेले नाही. खालील सर्व काही देखील सोपे आहे. उत्पादनांशी साधर्म्य साधून, आम्ही प्रत्येक OS साठी विविध फॅक्टरी अंमलबजावणी तयार करतो. चला Windows सह प्रारंभ करूया:

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 :( 
आणि आता आम्ही सारांश देतो. आम्ही GUI-आधारित अनुप्रयोगाचा सांगाडा लिहिला ज्यामध्ये इंटरफेस घटक विशेषत: संबंधित OS साठी तयार केले जातात. आम्ही तयार केलेल्या गोष्टींची आम्ही थोडक्यात पुनरावृत्ती करू:
  • इनपुट फील्ड, निवड फील्ड आणि एक बटण असलेले उत्पादन कुटुंब.
  • Windows आणि macOS साठी उत्पादन कुटुंबाची भिन्न अंमलबजावणी.
  • आमची उत्पादने तयार करण्यासाठी इंटरफेस परिभाषित करणारा एक अमूर्त कारखाना.
  • आमच्या कारखान्याची दोन अंमलबजावणी, प्रत्येक उत्पादनांचे विशिष्ट कुटुंब तयार करण्यासाठी जबाबदार आहे.
  • एक फॉर्म (एक Java वर्ग) ज्याचे फील्ड अमूर्त इंटरफेस घटक आहेत जे अमूर्त फॅक्टरी वापरून कन्स्ट्रक्टरमध्ये आवश्यक मूल्यांसह प्रारंभ केले जातात.
  • अनुप्रयोग वर्ग या वर्गाच्या आत, आम्ही एक फॉर्म तयार करतो, इच्छित फॅक्टरी अंमलबजावणी त्याच्या कन्स्ट्रक्टरला देतो.
परिणाम म्हणजे आम्ही अमूर्त कारखाना पॅटर्न लागू केला.

अमूर्त कारखाना: कसे वापरावे

अ‍ॅबस्ट्रॅक्ट फॅक्टरी हा कॉंक्रिट उत्पादन वर्गाशी न बांधता विविध उत्पादन कुटुंबांच्या निर्मितीचे व्यवस्थापन करण्यासाठी डिझाइन नमुना आहे. हा नमुना वापरताना, आपण हे करणे आवश्यक आहे:
  1. उत्पादन कुटुंबे परिभाषित करा. समजा आपल्याकडे त्यापैकी दोन आहेत:
    • SpecificProductA1,SpecificProductB1
    • SpecificProductA2,SpecificProductB2
  2. कुटुंबातील प्रत्येक उत्पादनासाठी, अमूर्त वर्ग (इंटरफेस) परिभाषित करा. आमच्या बाबतीत, आमच्याकडे आहे:
    • ProductA
    • ProductB
  3. प्रत्येक उत्पादन कुटुंबामध्ये, प्रत्येक उत्पादनाने चरण 2 मध्ये परिभाषित केलेला इंटरफेस लागू करणे आवश्यक आहे.
  4. चरण 2 मध्ये परिभाषित केलेल्या प्रत्येक उत्पादन तयार करण्याच्या पद्धतींसह एक अमूर्त कारखाना तयार करा. आमच्या बाबतीत, या पद्धती असतील:
    • ProductA createProductA();
    • ProductB createProductB();
  5. अमूर्त फॅक्टरी अंमलबजावणी तयार करा जेणेकरून प्रत्येक अंमलबजावणी एकाच कुटुंबाच्या उत्पादनांच्या निर्मितीवर नियंत्रण ठेवेल. हे करण्यासाठी, अमूर्त कारखान्याच्या प्रत्येक अंमलबजावणीमध्ये, आपल्याला सर्व निर्मिती पद्धती लागू करणे आवश्यक आहे जेणेकरून ते विशिष्ट उत्पादन अंमलबजावणी तयार करतील आणि परत करतील.
खालील UML आकृती वर वर्णन केलेल्या सूचना स्पष्ट करते: डिझाइन नमुने: अमूर्त कारखाना - 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. कॉफी ऑर्डरिंग ऍप्लिकेशन परिष्कृत करा जेणेकरून ते Linux वर देखील कार्य करेल.
  2. कोणत्याही लष्करी रणनीतीमध्ये सामील असलेल्या युनिट्सच्या उत्पादनासाठी तुमचा स्वतःचा अमूर्त कारखाना तयार करा. हे एकतर वास्तविक सैन्यासह एक ऐतिहासिक लष्करी धोरण असू शकते किंवा orcs, gnomes आणि elves सह कल्पनारम्य असू शकते. महत्त्वाची गोष्ट म्हणजे तुम्हाला आवडणारी एखादी गोष्ट निवडणे. सर्जनशील व्हा, कन्सोलवर संदेश छापा आणि नमुन्यांबद्दल शिकण्याचा आनंद घ्या!
टिप्पण्या
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION