JavaRush /จาวาบล็อก /Random-TH /รูปแบบการออกแบบ: วิธีการจากโรงงาน

รูปแบบการออกแบบ: วิธีการจากโรงงาน

เผยแพร่ในกลุ่ม
สวัสดี! วันนี้เราจะมาศึกษารูปแบบการออกแบบกันต่อและพูดคุยเกี่ยวกับวิธีโรงงาน (FactoryMethod) รูปแบบการออกแบบ: วิธีการโรงงาน - 1คุณจะพบว่าเทมเพลตนี้คืออะไรและเหมาะกับงานใดบ้าง เราจะดูรูปแบบการออกแบบนี้ในทางปฏิบัติและสำรวจโครงสร้างของมัน เพื่อให้สิ่งที่กล่าวมาทั้งหมดชัดเจน คุณต้องเข้าใจหัวข้อต่อไปนี้:
  1. การสืบทอดใน Java
  2. วิธีการเชิงนามธรรมและคลาสใน Java

วิธีการของโรงงานแก้ปัญหาอะไรได้บ้าง?

ในรูปแบบการออกแบบโรงงานทั้งหมด มีผู้เข้าร่วมสองกลุ่ม - ผู้สร้าง (โรงงานเอง) และผลิตภัณฑ์ (วัตถุที่สร้างขึ้นโดยโรงงาน) ลองนึกภาพสถานการณ์: เรามีโรงงานผลิตรถยนต์ภายใต้แบรนด์ AutoRush เธอสามารถสร้างโมเดลรถยนต์ที่มีตัวถังประเภทต่างๆ ได้:
  • รถเก๋ง
  • รถสเตชั่นแวกอน
  • รถเก๋ง
สิ่งต่างๆ เป็นไปด้วยดีสำหรับเรา จนวันหนึ่งเราซึมซับข้อกังวลของ OneAuto ได้ ในฐานะผู้จัดการที่สมเหตุสมผล เราไม่ต้องการสูญเสียลูกค้า OneAuto และงานของเราคือปรับโครงสร้างการผลิตในลักษณะที่เราสามารถผลิตได้:
  • รถซีดานออโต้รัช
  • AutoRush สเตชั่นแวกอน
  • คูเป้ออโต้รัช
  • รถเก๋งวันออโต้
  • OneAuto สเตชั่นแวกอน
  • คูเป้ วันออโต้
อย่างที่คุณเห็นแทนที่จะเป็นผลิตภัณฑ์อนุพันธ์กลุ่มเดียว กลับปรากฏสองรายการซึ่งมีรายละเอียดบางอย่างแตกต่างกัน รูปแบบการออกแบบวิธีการของโรงงานช่วยแก้ปัญหาในการสร้างกลุ่มผลิตภัณฑ์ที่แตกต่างกัน โดยแต่ละกลุ่มมีความเฉพาะเจาะจงบางประการ เราจะพิจารณาหลักการของเทมเพลตนี้ในทางปฏิบัติ โดยค่อยๆ ย้ายจากง่ายไปสู่ซับซ้อน โดยใช้ตัวอย่างร้านกาแฟของเรา ซึ่งเราสร้างขึ้นในการบรรยายครั้ง ก่อน

เล็กน้อยเกี่ยวกับเทมเพลตโรงงาน

ฉันขอเตือนคุณ: เราสร้างร้านกาแฟเสมือนจริงขนาดเล็กกับคุณ ในนั้น เราได้เรียนรู้วิธีสร้างสรรค์กาแฟประเภทต่างๆ ด้วยความช่วยเหลือจากโรงงานที่เรียบง่าย วันนี้เราจะปรับแต่งตัวอย่างนี้ ลองนึกถึงร้านกาแฟที่มีโรงงานเรียบง่ายของเราดูสิ เรามีชั้นเรียนดื่มกาแฟ:
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 {}
เพื่อความสะดวกในการรับคำสั่งซื้อ เราได้แนะนำการโอนเงิน:
public enum CoffeeType {
    ESPRESSO,
    AMERICANO,
    CAFFE_LATTE,
    CAPPUCCINO
}
โรงงานผลิตกาแฟมีลักษณะดังนี้:
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 Cappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }

        return coffee;
    }
}
และสุดท้าย ร้านกาแฟนั่นเอง:
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;
    }
}

การปรับปรุงโรงงานที่เรียบง่ายให้ทันสมัย

ร้านกาแฟของเราไปได้ดี มากจนเราคิดที่จะขยาย เราต้องการเปิดจุดใหม่หลายจุด ในฐานะผู้ชายที่กล้าได้กล้าเสีย เราจะไม่ปั่นร้านกาแฟที่ซ้ำซากจำเจ ฉันอยากให้แต่ละคนมีความเป็นของตัวเอง ดังนั้นในการเริ่มต้นเราจะเปิดสองประเด็น: ในรูปแบบอิตาลีและอเมริกัน การเปลี่ยนแปลงจะไม่เพียงส่งผลต่อการตกแต่งภายในเท่านั้น แต่ยังรวมถึงเครื่องดื่มด้วย:
  • ในร้านกาแฟอิตาลี เราจะใช้กาแฟยี่ห้ออิตาลีโดยเฉพาะ ที่มีการบดและคั่วแบบพิเศษ
  • ส่วนของอเมริกาจะใหญ่กว่านี้เล็กน้อย และเราจะเสิร์ฟมาร์ชเมลโลว์ละลาย - มาร์ชเมลโลว์ในแต่ละออเดอร์
สิ่งเดียวที่จะไม่เปลี่ยนแปลงคือรูปแบบธุรกิจของเราซึ่งพิสูจน์ตัวเองได้ดี ถ้าเราพูดด้วยภาษารหัส นี่คือสิ่งที่เกิดขึ้น เรามีผลิตภัณฑ์ 4 คลาส:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
และมันกลายเป็น 8:
public class ItalianStyleAmericano extends Coffee {}
public class ItalianStyleCappucino extends Coffee {}
public class ItalianStyleCaffeLatte extends Coffee {}
public class ItalianStyleEspresso extends Coffee {}

public class AmericanStyleAmericano extends Coffee {}
public class AmericanStyleCappucino extends Coffee {}
public class AmericanStyleCaffeLatte extends Coffee {}
public class AmericanStyleEspresso extends Coffee {}
เนื่องจากเราต้องการคงรูปแบบธุรกิจปัจจุบันไว้ไม่เปลี่ยนแปลง เราจึงต้องการให้วิธีorderCoffee(CoffeeType type)การได้รับการเปลี่ยนแปลงจำนวนน้อยที่สุด ลองมาดูกัน:
public Coffee orderCoffee(CoffeeType type) {
    Coffee coffee = coffeeFactory.createCoffee(type);
    coffee.grindCoffee();
    coffee.makeCoffee();
    coffee.pourIntoCup();

    System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
    return coffee;
}
ตัวเลือกที่เรามีอะไรบ้าง? เรารู้วิธีเขียนโรงงานอยู่แล้วใช่ไหม? สิ่งที่ง่ายที่สุดที่อยู่ในใจทันทีคือเขียนโรงงานที่คล้ายกันสองแห่ง จากนั้นส่งต่อการใช้งานที่จำเป็นไปยังร้านกาแฟของเราในตัวสร้าง แล้วคลาสของร้านกาแฟก็จะไม่เปลี่ยนแปลง ขั้นแรก เราต้องสร้างคลาสโรงงานใหม่ สืบทอดจากโรงงานที่เรียบง่ายของเรา และแทนที่createCoffee (CoffeeType type). มาเขียนโรงงานสำหรับสร้างกาแฟสไตล์อิตาลีและอเมริกากัน:
public class SimpleItalianCoffeeFactory extends SimpleCoffeeFactory {

    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;
        switch (type) {
            case AMERICANO:
                coffee = new ItalianStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new ItalianStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new ItalianStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new ItalianStyleCaffeLatte();
                break;
        }
        return coffee;
    }
}

public class SimpleAmericanCoffeeFactory extends SimpleCoffeeFactory{

    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new AmericanStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new AmericanStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new AmericanStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new AmericanStyleCaffeLatte();
                break;
        }

        return coffee;
    }

}
ตอนนี้เราสามารถส่งต่อการใช้งานโรงงานที่จำเป็นไปยัง CoffeeShop ได้แล้ว มาดูกันว่าโค้ดในการสั่งกาแฟจากร้านกาแฟต่างๆ จะเป็นอย่างไร ตัวอย่างเช่น คาปูชิโน่สไตล์อิตาลีและอเมริกัน:
public class Main {
    public static void main(String[] args) {
        /*
            Закажем капучино в итальянском стиле:
            1. Создадим фабрику для приготовления итальянского кофе
            2. Создадим новую кофейню, передав ей в конструкторе фабрику итальянского кофе
            3. Закажем наш кофе
         */
        SimpleItalianCoffeeFactory italianCoffeeFactory = new SimpleItalianCoffeeFactory();
        CoffeeShop italianCoffeeShop = new CoffeeShop(italianCoffeeFactory);
        italianCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);


         /*
            Закажем капучино в американском стиле
            1. Создадим фабрику для приготовления американского кофе
            2. Создадим новую кофейню, передав ей в конструкторе фабрику американского кофе
            3. Закажем наш кофе
         */
        SimpleAmericanCoffeeFactory americanCoffeeFactory = new SimpleAmericanCoffeeFactory();
        CoffeeShop americanCoffeeShop = new CoffeeShop(americanCoffeeFactory);
        americanCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);
    }
}
เราสร้างร้านกาแฟสองแห่งที่แตกต่างกัน โดยย้ายแต่ละร้านไปยังโรงงานที่ต้องการ ในอีกด้านหนึ่ง เราบรรลุเป้าหมายของเราแล้ว แต่ในทางกลับกัน... มีบางอย่างกำลังเกาจิตวิญญาณของผู้ประกอบการที่ไม่อาจระงับได้... เรามาดูกันว่ามีอะไรผิดปกติบ้าง ประการแรก ความอุดมสมบูรณ์ของโรงงาน เป็นไปได้หรือไม่ที่จะสร้างโรงงานของคุณเองทุกครั้งสำหรับจุดใหม่ และนอกจากนี้ ตรวจสอบให้แน่ใจว่าเมื่อสร้างร้านกาแฟ โรงงานที่ต้องการจะถูกโอนไปยังผู้สร้างหรือไม่ ประการที่สอง ยังคงเป็นโรงงานที่เรียบง่าย ปรับปรุงให้ทันสมัยเพียงเล็กน้อย เรายังคงศึกษารูปแบบใหม่ที่นี่ ประการที่สาม เป็นไปไม่ได้ที่จะทำอย่างอื่นอีกหรือ? คงจะดีไม่น้อยถ้าเราสามารถตอบคำถามทั้งหมดเกี่ยวกับการชงกาแฟในห้องเรียนCoffeeShopเชื่อมโยงกระบวนการชงกาแฟและการให้บริการตามคำสั่งซื้อ แต่ในขณะเดียวกันก็รักษาความยืดหยุ่นเพียงพอในการทำกาแฟในสไตล์ที่แตกต่างกัน คำตอบคือใช่ คุณทำได้ สิ่งนี้เรียกว่ารูปแบบการออกแบบวิธีโรงงาน

จากโรงงานธรรมดาๆ สู่วิธีการแบบโรงงาน

เพื่อแก้ไขปัญหาอย่างมีประสิทธิภาพที่สุดเท่าที่จะเป็นไปได้ เรา:
  1. ลองคืนวิธีการให้กับcreateCoffee(CoffeeType type)ชั้นเรียนCoffeeShop
  2. มาทำให้วิธีนี้เป็นนามธรรมกัน
  3. ชั้นเรียนCoffeeShopจะกลายเป็นนามธรรม
  4. ชั้นCoffeeShopจะมีทายาท
ใช่เพื่อน. ร้านกาแฟอิตาเลียนไม่มีอะไรมากไปกว่าทายาทของชั้นเรียนCoffeeShopโดยใช้วิธีการcreateCoffee(CoffeeType type)ตามประเพณีที่ดีที่สุดของบาริสต้าชาวอิตาลี ดังนั้นตามลำดับ ขั้นตอนที่ 1 มาทำให้ชั้นเรียนCoffeeเป็นนามธรรมกัน ตอนนี้เรามีผลิตภัณฑ์ที่แตกต่างกันสองตระกูล เครื่องดื่มกาแฟอิตาเลียนและอเมริกันยังคงมีบรรพบุรุษร่วมกัน: Coffee. มันจะถูกต้องถ้าจะทำให้เป็นนามธรรม:
public abstract class Coffee {
    public void makeCoffee(){
        // делаем кофе
    }
    public void pourIntoCup(){
        // наливаем в чашку
    }
}
ขั้นตอนที่ 2 ทำให้เป็นCoffeeShopนามธรรมด้วยวิธีนามธรรมcreateCoffee(CoffeeType type)
public abstract class CoffeeShop {

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

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

        System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }

    protected abstract Coffee createCoffee(CoffeeType type);
}
ขั้นตอนที่ 3. สร้างร้านกาแฟสไตล์อิตาลี ซึ่งเป็นคลาสที่สืบทอดมาจากร้านกาแฟแนวนามธรรม ในนั้นเราใช้วิธีการcreateCoffee(CoffeeType type)โดยคำนึงถึงข้อมูลเฉพาะของอิตาลี
public class ItalianCoffeeShop extends CoffeeShop {

    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;
        switch (type) {
            case AMERICANO:
                coffee = new ItalianStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new ItalianStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new ItalianStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new ItalianStyleCaffeLatte();
                break;
        }
        return coffee;
    }
}
ขั้นตอนที่ 4. มาทำแบบเดียวกันกับร้านกาแฟสไตล์อเมริกันกัน
public class AmericanCoffeeShop extends CoffeeShop {
    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new AmericanStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new AmericanStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new AmericanStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new AmericanStyleCaffeLatte();
                break;
        }

        return coffee;
    }
}
ขั้นตอนที่ 5. มาดูกันว่าการสั่งลาเต้สไตล์อเมริกันและอิตาลีจะเป็นอย่างไร:
public class Main {
    public static void main(String[] args) {
        CoffeeShop italianCoffeeShop = new ItalianCoffeeShop();
        italianCoffeeShop.orderCoffee(CoffeeType.CAFFE_LATTE);

        CoffeeShop americanCoffeeShop = new AmericanCoffeeShop();
        americanCoffeeShop.orderCoffee(CoffeeType.CAFFE_LATTE);
    }
}
ยินดีด้วย. เราเพิ่งนำรูปแบบการออกแบบวิธีโรงงานมาใช้ในร้านกาแฟของเรา

วิธีการทำงานของโรงงาน

ทีนี้เรามาดูสิ่งที่เราได้รับกันดีกว่า แผนภาพด้านล่างแสดงคลาสผลลัพธ์ บล็อกสีเขียวคือคลาสผู้สร้าง บล็อกสีน้ำเงินคือคลาสผลิตภัณฑ์ รูปแบบการออกแบบ: วิธีโรงงาน - 2สามารถสรุปข้อสรุปอะไรได้บ้าง?
  1. ผลิตภัณฑ์ทั้งหมดเป็นการใช้งานของคลาสCoffeeนามธรรม
  2. CoffeeShopผู้สร้างทั้งหมดเป็นการใช้งานของคลาสนามธรรม
  3. เราสังเกตลำดับชั้นของคลาสคู่ขนานสองลำดับชั้น:
    • ลำดับชั้นของผลิตภัณฑ์ เราเห็นลูกหลานชาวอิตาลีและลูกหลานชาวอเมริกัน
    • ลำดับชั้นของผู้สร้าง เราเห็นลูกหลานชาวอิตาลีและลูกหลานชาวอเมริกัน
  4. ซูเปอร์คลาสCoffeeShopไม่มีข้อมูลเกี่ยวกับการใช้งานผลิตภัณฑ์เฉพาะ ( Coffee) ที่จะถูกสร้างขึ้น
  5. ซูเปอร์คลาสCoffeeShopมอบหมายการสร้างผลิตภัณฑ์เฉพาะให้กับลูกหลาน
  6. คลาสลูกหลานแต่ละคลาสCoffeeShopใช้วิธีการแบบโรงงานcreateCoffee()ตามลักษณะเฉพาะของมัน กล่าวอีกนัยหนึ่ง ภายในการใช้งานคลาสผู้สร้าง จะมีการตัดสินใจที่จะเตรียมผลิตภัณฑ์เฉพาะตามข้อมูลเฉพาะของคลาสผู้สร้าง
ตอนนี้คุณพร้อมที่จะกำหนด รูป แบบวิธีการของโรงงานแล้ว รูปแบบวิธีการของโรงงานกำหนดอินเทอร์เฟซสำหรับการสร้างออบเจ็กต์ แต่อนุญาตให้คลาสย่อยเลือกคลาสของอินสแตนซ์ที่จะสร้าง ดังนั้นเมธอด Factory จะมอบหมายการดำเนินการสร้างอินสแตนซ์ให้กับคลาสย่อย โดยทั่วไป การจดจำคำจำกัดความไม่สำคัญเท่ากับการทำความเข้าใจว่าสิ่งต่างๆ ทำงานอย่างไร

โครงสร้างวิธีการของโรงงาน

รูปแบบการออกแบบ: วิธีการโรงงาน - 3แผนภาพด้านบนแสดงโครงสร้างทั่วไปของรูปแบบวิธีการของโรงงาน มีอะไรสำคัญอีกที่นี่?
  1. คลาส Creator มีการนำไปใช้ของวิธีการทั้งหมดที่โต้ตอบกับผลิตภัณฑ์ ยกเว้นวิธีการจากโรงงาน
  2. วิธีการนามธรรม จะ ต้องfactoryMethod()ดำเนินการโดยผู้สืบทอดทั้งหมดของคลาสCreator
  3. ชั้นเรียนConcreteCreatorใช้วิธีการfactoryMethod()ที่สร้างผลิตภัณฑ์โดยตรง
  4. คลาสนี้มีหน้าที่สร้างผลิตภัณฑ์เฉพาะ นี่เป็นคลาสเดียวที่มีข้อมูลเกี่ยวกับการสร้างผลิตภัณฑ์เหล่านี้
  5. ผลิตภัณฑ์ทั้งหมดต้องใช้อินเทอร์เฟซทั่วไป - ต้องสืบทอดจากประเภทผลิตภัณฑ์ทั่วไป นี่เป็นสิ่งจำเป็นเพื่อให้คลาสที่ใช้ผลิตภัณฑ์สามารถทำงานได้ในระดับนามธรรมมากกว่าการใช้งานที่เป็นรูปธรรม

การบ้าน

ดังนั้น วันนี้เราจึงทำงานค่อนข้างมากและได้ศึกษารูปแบบการออกแบบวิธีโรงงาน ถึงเวลารวบรวมเนื้อหาที่คุณกล่าวถึงแล้ว! ภารกิจที่ 1. ทำงานเพื่อเปิดร้านกาแฟอีกแห่ง จะทำเป็นสไตล์อังกฤษหรือสเปนก็ได้ หรือแม้แต่ในรูปแบบของยานอวกาศ มาเติมสีผสมอาหารลงในกาแฟเพื่อให้มันดูเงางามกันดีกว่า โดยทั่วไปแล้ว กาแฟจะเป็นเพียงพื้นที่! ภารกิจที่ 2 ในการบรรยายครั้งล่าสุดคุณมีภารกิจสร้างซูชิบาร์เสมือนจริงหรือร้านพิซซ่าเสมือนจริง งานของคุณคือไม่ต้องยืนนิ่ง วันนี้คุณได้เรียนรู้วิธีใช้รูปแบบวิธีการแบบโรงงานเพื่อให้บรรลุความสำเร็จแล้ว ถึงเวลาใช้ประโยชน์จากความรู้นี้และขยายธุรกิจของคุณเอง ;)
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION