JavaRush /בלוג Java /Random-HE /דפוס עיצוב במפעל

דפוס עיצוב במפעל

פורסם בקבוצה
שלום חבר! היום נמשיך ללמוד איתך דפוסי עיצוב. בהרצאה זו נדבר על המפעל. נדון איתך באיזו בעיה נפתרת באמצעות תבנית זו, ונראה דוגמה כיצד מפעל עוזר לפתוח בית קפה. ואני גם אתן לך 5 שלבים פשוטים ליצירת מפעל. דפוס עיצוב במפעל - 1כדי להיות באותו עמוד עם כולם ולתפוס בקלות את המהות, עליך להכיר את הנושאים הבאים:
  • ירושה בג'אווה
  • צמצום והרחבת סוגי הפניות ב-Java
  • אינטראקציה בין מחלקות ואובייקטים שונים

מה זה מפעל?

תבנית העיצוב של המפעל מאפשרת לך לשלוט ביצירת אובייקטים. תהליך יצירת אובייקט חדש הוא לא כל כך פשוט, אבל הוא גם לא מסובך מדי. כולנו יודעים שכדי ליצור אובייקט חדש עלינו להשתמש ב- 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 עבור כל מחלקה צאצא:
enum CatType {
    LION,
    TIGER,
    BARSIK
}
שלב 3. אתה בונה את המפעל שלך. אתה קורא לזה MyClassFactory, הקוד נמצא למטה:
class CatFactory {}
שלב 4. אתה יוצר שיטה במפעל שלך createMyClassשלוקחת את המשתנה - enum MyClassType. קוד למטה:
class CatFactory {
    public Cat createCat(CatType type) {

    }
}
שלב 5. אתה כותב בלוק בגוף השיטה switch-caseשבה אתה חוזר על כל ערכי ה-enum ויוצר מופע של המחלקה המתאים לערך 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