JavaRush /مدونة جافا /Random-AR /نمط تصميم المصنع

نمط تصميم المصنع

نشرت في المجموعة
مرحبا يا صديق! اليوم سنواصل دراسة أنماط التصميم معك. في هذه المحاضرة سنتحدث عن المصنع. سنناقش معك ما هي المشكلة التي تم حلها باستخدام هذا القالب، وننظر إلى مثال لكيفية مساعدة المصنع في فتح مقهى. وسأعطيك أيضًا 5 خطوات بسيطة لإنشاء مصنع. نمط تصميم المصنع - 1لكي تكون على نفس الصفحة مع الجميع وتتمكن من فهم الجوهر بسهولة، يجب أن تكون على دراية بالمواضيع التالية:
  • الميراث في جاوة
  • تضييق وتوسيع أنواع المراجع في جافا
  • التفاعل بين الفئات والأشياء المختلفة

ما هو المصنع؟

يتيح لك نمط تصميم المصنع التحكم في إنشاء الكائنات. إن عملية إنشاء كائن جديد ليست بهذه البساطة، ولكنها ليست معقدة للغاية أيضًا. نعلم جميعًا أنه لإنشاء كائن جديد يجب علينا استخدام new. وقد يبدو أنه لا يوجد شيء يمكن إدارته هنا، لكن الأمر ليس كذلك. قد تنشأ صعوبات عندما يحتوي تطبيقنا على فئة معينة لها العديد من السلالات، ومن الضروري إنشاء مثيل لفئة معينة اعتمادًا على بعض الشروط. المصنع هو نمط تصميمي يساعد في حل مشكلة إنشاء كائنات مختلفة حسب بعض الشروط. مجردة، أليس كذلك؟ سيظهر المزيد من التحديد والوضوح عندما ننظر إلى المثال أدناه.

نحن نصنع أنواع مختلفة من القهوة

لنفترض أننا نريد أتمتة مقهى. نحن بحاجة إلى تعلم كيفية تحضير أنواع مختلفة من القهوة. للقيام بذلك، سنقوم في تطبيقنا بإنشاء فئة القهوة ومشتقاتها: أمريكانو، كابتشينو، إسبرسو، لاتيه - أنواع القهوة التي سنقوم بتحضيرها. لنبدأ بفصل القهوة العام:
public class Coffee {
    public void grindCoffee(){
        // перемалываем кофе
    }
    public void makeCoffee(){
        // делаем кофе
    }
    public void pourIntoCup(){
        // наливаем в чашку
    }
}
بعد ذلك، لنقم بإنشاء ورثته:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
سيطلب عملاؤنا نوعًا ما من القهوة، ويجب تمرير هذه المعلومات إلى البرنامج. ويمكن القيام بذلك بطرق مختلفة، على سبيل المثال باستخدام String. لكنها الأنسب لهذه الأغراض enum. لنقم بإنشاء enumوتحديد أنواع القهوة التي نقبل طلباتها:
public enum CoffeeType {
    ESPRESSO,
    AMERICANO,
    CAFFE_LATTE,
    CAPPUCCINO
}
عظيم، لنكتب الآن الكود الخاص بالمقهى الخاص بنا:
public class CoffeeShop {

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new Americano();
                break;
            case ESPRESSO:
                coffee = new Espresso();
                break;
            case CAPPUCCINO:
                coffee = new Cappucсino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }

        coffee.grindCoffee();
        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }
}
ويمكن تقسيم الطريقة orderCoffeeإلى عنصرين:
  1. إنشاء مثيل قهوة محدد في كتلة switch-case. وهنا ما يفعله المصنع هو إنشاء نوع معين حسب الظروف.
  2. المستحضر نفسه عبارة عن طحن وطهي وصب في كوب.
من المهم معرفة ما إذا كنت بحاجة إلى إجراء تغييرات على الطريقة في المستقبل:
  1. ستبقى خوارزمية التحضير نفسها (الطحن والطهي والصب في الكوب) دون تغيير (على الأقل نأمل ذلك).
  2. لكن نطاق القهوة قد يتغير. ربما سنبدأ بصنع موكا.. موكا.. موكاتشي... الله يبارك فيه نوع جديد من القهوة.
يمكننا بالفعل أن نفترض أنه في المستقبل، مع درجة معينة من الاحتمال، سيتعين علينا إجراء تغييرات على الطريقة، على الكتلة switch-case. ومن الممكن أيضًا ألا تكون الطريقة في المقهى الخاص بنا orderCoffeeهي المكان الوحيد الذي نصنع فيه أنواعًا مختلفة من القهوة. لذلك، يجب إجراء التغييرات في عدة أماكن. ربما تفهم بالفعل ما أقصده. نحن بحاجة إلى إعادة البناء. انقل الكتلة المسؤولة عن تحضير القهوة إلى فصل منفصل لسببين:
  1. سنكون قادرين على إعادة استخدام منطق صنع القهوة في أماكن أخرى.
  2. إذا تغير النطاق، فلن نضطر إلى تعديل الكود في كل مكان حيث سيتم استخدام عملية صنع القهوة. سيكون كافيًا تغيير الرمز في مكان واحد فقط.
بمعنى آخر، حان الوقت لتقليص المصنع.

نحن ننشر مصنعنا الأول

للقيام بذلك، دعونا ننشئ فئة جديدة ستكون مسؤولة فقط عن إنشاء المثيلات الضرورية لفئات القهوة:
public class SimpleCoffeeFactory {
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new Americano();
                break;
            case ESPRESSO:
                coffee = new Espresso();
                break;
            case CAPPUCCINO:
                coffee = new Cappucino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }

        return coffee;
    }
}
تهانينا! لقد قمنا للتو بتنفيذ نمط تصميم المصنع في أبسط صوره. على الرغم من أن كل شيء يمكن أن يكون أبسط إذا جعلنا الطريقة createCoffeeثابتة. ولكن بعد ذلك سنفقد احتمالين:
  1. وراثة من SimpleCoffeeFactoryوتجاوز createCoffee.
  2. تنفيذ التنفيذ المصنعي المطلوب في فصولنا.
الحديث عن التنفيذ. نحن بحاجة إلى العودة إلى المقهى وتنفيذ مصنعنا لصنع القهوة.

إدخال مصنع إلى مقهى

دعونا نعيد كتابة فصل المقهى الخاص بنا باستخدام المصنع:
public class CoffeeShop {

    private final SimpleCoffeeFactory coffeeFactory;

    public CoffeeShop(SimpleCoffeeFactory coffeeFactory) {
        this.coffeeFactory = coffeeFactory;
    }

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = coffeeFactory.createCoffee(type);
        coffee.grindCoffee();
        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }
}
عظيم. الآن دعونا نحاول وصف هيكل نمط تصميم المصنع بشكل تخطيطي وإيجاز.

5 خطوات لفتح مصنعك الخاص

الخطوة 1. في برنامجك لديك فئة ذات فروع متعددة، كما في الصورة أدناه: نمط تصميم المصنع - 2الخطوة 2. قم بإنشاء فئة enumتحدد فيها متغير التعداد لكل فئة فرعية:
enum CatType {
    LION,
    TIGER,
    BARSIK
}
الخطوة 3. أنت تبني مصنعك. يمكنك تسميتها MyClassFactory، الكود أدناه:
class CatFactory {}
الخطوة 4. قم بإنشاء طريقة في المصنع الخاص بك createMyClassتأخذ المتغير - enum MyClassType. الرمز أدناه:
class CatFactory {
    public Cat createCat(CatType type) {

    }
}
الخطوة 5. تكتب كتلة في نص الطريقة switch-caseالتي تتكرر بها جميع قيم التعداد وتقوم بإنشاء مثيل للفئة المقابلة للقيمة enum:
class CatFactory {
        public Cat createCat(CatType type) {
            Cat cat = null;

            switch (type) {
                case LION:
                    cat =  new Barsik();
                    break;
                case TIGER:
                    cat = new Tiger();
                    break;
                case BARSIK:
                    cat =  new Lion();
                    break;
            }

            return cat;
        }
    }
مثل رئيس.

كيفية تدريب

القراءة جيدة، وكتابة التعليمات البرمجية أفضل. إذا كان اسمك يحتوي على عدد زوجي من الحروف، فحاول إنشاء مطعم بيتزا افتراضي خاص بك. إذا كان اسمك يحتوي على عدد فردي من الحروف، فحاول إنشاء بار سوشي افتراضي. إذا كنت مجهولاً، فأنت محظوظ. اليوم يمكنك الراحة.
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION