CodeGym /จาวาบล็อก /สุ่ม /รูปแบบการออกแบบ: โรงงานนามธรรม
John Squirrels
ระดับ
San Francisco

รูปแบบการออกแบบ: โรงงานนามธรรม

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

โรงงานนามธรรมแก้ปัญหาอะไรได้บ้าง?

โรงงานนามธรรม เช่นเดียวกับรูปแบบโรงงานทั้งหมด ช่วยให้เรามั่นใจได้ว่าวัตถุใหม่จะถูกสร้างขึ้นอย่างถูกต้อง เราใช้มันเพื่อจัดการ "การผลิต" ของตระกูลต่างๆ ของวัตถุที่เชื่อมต่อถึงกัน ตระกูลต่าง ๆ ของวัตถุที่เชื่อมต่อถึงกัน... หมายความว่าอย่างไร? ไม่ต้องกังวล: ในทางปฏิบัติ ทุกสิ่งนั้นง่ายกว่าที่คิด เริ่มต้นด้วย ครอบครัวของวัตถุที่เชื่อมต่อถึงกันคืออะไร? สมมติว่าเรากำลังพัฒนากลยุทธ์ทางทหารที่เกี่ยวข้องกับหน่วยหลายประเภท:
  • ทหารราบ
  • ทหารม้า
  • นักธนู
หน่วยประเภทนี้มีความเชื่อมโยงกันเนื่องจากทำหน้าที่ในกองทัพเดียวกัน เราสามารถพูดได้ว่าหมวดหมู่ที่แสดงด้านบนเป็นกลุ่มของวัตถุที่เชื่อมต่อถึงกัน เราเข้าใจสิ่งนี้ แต่รูปแบบโรงงานเชิงนามธรรมนั้นใช้เพื่อจัดเตรียมการสร้างตระกูลต่าง ๆ ของวัตถุที่เชื่อมต่อถึงกัน ที่นี่ก็ไม่มีอะไรซับซ้อนเช่นกัน มาดูตัวอย่างกลยุทธ์ทางทหารกันต่อ โดยทั่วไปแล้ว หน่วยทหารเป็นของหลายฝ่ายที่ทำสงครามกัน ขึ้นอยู่กับว่าพวกเขาอยู่ฝ่ายใด หน่วยทหารอาจมีรูปร่างหน้าตาที่แตกต่างกันไปอย่างมาก พลเดินเท้า พลม้า และพลธนูของกองทัพโรมันไม่เหมือนกับพลเดินเท้า พลม้า และพลธนูของไวกิ้ง ในกลยุทธ์ทางทหาร ทหารของกองทัพต่าง ๆ เป็นตระกูลต่าง ๆ ของวัตถุที่เชื่อมต่อถึงกัน คงจะตลกดีถ้าเป็นโปรแกรมเมอร์' ความผิดพลาดของทหารทำให้ทหารในเครื่องแบบฝรั่งเศสยุคนโปเลียนพร้อมปืนคาบศิลาเดินอยู่ในแถวทหารราบโรมัน รูปแบบการออกแบบโรงงานเชิงนามธรรมเป็นสิ่งจำเป็นอย่างยิ่งสำหรับการแก้ปัญหานี้ ไม่ ไม่ใช่ปัญหาของความลำบากใจที่อาจเกิดขึ้นจากการเดินทางข้ามเวลา แต่เป็นปัญหาของการสร้างกลุ่มของวัตถุที่เชื่อมต่อถึงกัน โรงงานนามธรรมมีส่วนต่อประสานสำหรับการสร้างผลิตภัณฑ์ที่มีอยู่ทั้งหมด (ตระกูลของวัตถุ) โรงงานนามธรรมมักมีการใช้งานหลายอย่าง แต่ละคนมีหน้าที่รับผิดชอบในการสร้างผลิตภัณฑ์ของตระกูลใดตระกูลหนึ่ง กลยุทธ์ทางทหารของเราจะรวมถึงโรงงานนามธรรมที่สร้างพลเดินเท้า นักธนู และทหารม้าที่เป็นนามธรรม รวมถึงการใช้งานโรงงานแห่งนี้ ตัวอย่างเช่น, โรงงานที่สร้างกองทหารโรมันและโรงงานที่สร้างทหาร Carthaginian นามธรรมเป็นหลักการชี้นำที่สำคัญที่สุดของรูปแบบนี้ ลูกค้าของโรงงานทำงานกับโรงงานและผลิตภัณฑ์ผ่านส่วนต่อประสานเชิงนามธรรมเท่านั้น ดังนั้น คุณไม่ต้องคิดเลยว่ากำลังสร้างทหารคนไหนอยู่ แต่คุณส่งต่อความรับผิดชอบนี้ไปยังการนำโรงงานนามธรรมไปปฏิบัติอย่างเป็นรูปธรรม

เรามาทำให้ร้านกาแฟของเราเป็นอัตโนมัติกันต่อไป

ในบทเรียนสุดท้ายเราศึกษารูปแบบวิธีการของโรงงาน เราใช้มันเพื่อขยายธุรกิจกาแฟของเราและเปิดสาขาใหม่หลายแห่ง วันนี้เราจะปรับปรุงธุรกิจของเราให้ทันสมัยต่อไป เราจะวางรากฐานสำหรับแอปพลิเคชันเดสก์ท็อปใหม่สำหรับการสั่งกาแฟออนไลน์โดยใช้รูปแบบโรงงานนามธรรม เมื่อเขียนแอปพลิเคชันบนเดสก์ท็อป เราควรคิดถึงการสนับสนุนข้ามแพลตฟอร์มเสมอ แอปพลิเคชันของเราต้องใช้งานได้ทั้งบน macOS และ Windows (สปอยล์: เหลือการรองรับ Linux ไว้ให้คุณทำการบ้าน) ใบสมัครของเราจะเป็นอย่างไร? ค่อนข้างเรียบง่าย: จะเป็นรูปแบบที่ประกอบด้วยช่องข้อความ ช่องเลือก และปุ่ม หากคุณมีประสบการณ์ในการใช้ระบบปฏิบัติการที่แตกต่างกัน คุณจะสังเกตเห็นอย่างแน่นอนว่าปุ่มต่างๆ บน Windows แสดงผลแตกต่างจากบน Mac เช่นเดียวกับอย่างอื่น... เอาล่ะ มาเริ่มกันเลย
  • ปุ่ม
  • ช่องข้อความ
  • เขตข้อมูลการเลือก
ข้อจำกัดความรับผิดชอบ: ในแต่ละ อินเทอร์เฟซ เราสามารถกำหนดวิธีการเช่นonClick, onValueChanged, หรือ onInputChangedกล่าวอีกนัยหนึ่ง เราสามารถกำหนดวิธีการที่จะช่วยให้เราจัดการกับเหตุการณ์ต่างๆ (การกดปุ่ม การป้อนข้อความ การเลือกค่าในกล่องตัวเลือก) ทั้งหมดนี้จงใจละไว้ที่นี่เพื่อไม่ให้เกินตัวอย่างและเพื่อให้ชัดเจนขึ้นเมื่อเราศึกษารูปแบบโรงงาน มากำหนดอินเทอร์เฟซเชิงนามธรรมสำหรับผลิตภัณฑ์ของเรากัน:

public interface Button {}
public interface Select {}
public interface TextField {}
สำหรับแต่ละระบบปฏิบัติการ เราต้องสร้างองค์ประกอบอินเทอร์เฟซในรูปแบบระบบปฏิบัติการ เรากำลังเขียนโค้ดสำหรับ Windows และ MacOS มาสร้างการใช้งานสำหรับ Windows:

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();

}
สุดยอด อย่างที่คุณเห็น เรายังไม่ได้ทำอะไรที่ซับซ้อนเลย ทุกสิ่งที่ตามมาก็เรียบง่ายเช่นกัน ด้วยการเปรียบเทียบกับผลิตภัณฑ์ เราสร้างการใช้งานโรงงานที่หลากหลายสำหรับแต่ละระบบปฏิบัติการ เริ่มต้นด้วย 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();
    }
}
โปรดทราบว่าลายเซ็นเมธอดแต่ละเมธอดระบุว่าเมธอดส่งคืนประเภทนามธรรม แต่ภายในวิธีการ เรากำลังสร้างการใช้งานเฉพาะของผลิตภัณฑ์ นี่เป็นที่เดียวที่เราควบคุมการสร้างอินสแตนซ์เฉพาะ ตอนนี้ได้เวลาเขียนคลาสสำหรับแบบฟอร์มแล้ว นี่คือคลาส Java ที่มีฟิลด์เป็นองค์ประกอบอินเตอร์เฟส:

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();
    }
}
โรงงานนามธรรมที่สร้างองค์ประกอบอินเทอร์เฟซจะถูกส่งผ่านไปยังตัวสร้างของแบบฟอร์ม เราจะส่งต่อการดำเนินการที่จำเป็นจากโรงงานไปยังตัวสร้างเพื่อสร้างองค์ประกอบอินเทอร์เฟซสำหรับระบบปฏิบัติการเฉพาะ

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();
    }
}
หากเราเรียกใช้แอปพลิเคชันบน Windows เราจะได้ผลลัพธ์ต่อไปนี้:

Creating GUIFactory for Windows OS
Creating coffee order form
Creating TextField for Windows OS
Creating Select for Windows OS
Creating Button for Windows OS
บน Mac ผลลัพธ์จะเป็นดังนี้:

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 ซึ่งองค์ประกอบอินเทอร์เฟซถูกสร้างขึ้นโดยเฉพาะสำหรับระบบปฏิบัติการที่เกี่ยวข้อง เราจะทำซ้ำสิ่งที่เราสร้างขึ้นอย่างรัดกุม:
  • ตระกูลผลิตภัณฑ์ประกอบด้วยช่องป้อนข้อมูล ช่องเลือก และปุ่ม
  • การใช้งานที่แตกต่างกันของตระกูลผลิตภัณฑ์สำหรับ 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. สร้างโรงงานนามธรรมของคุณเองสำหรับการผลิตหน่วยที่เกี่ยวข้องกับกลยุทธ์ทางทหารใดๆ นี่อาจเป็นได้ทั้งกลยุทธ์ทางทหารตามประวัติศาสตร์ที่เกี่ยวข้องกับกองทัพจริง หรือกลยุทธ์แฟนตาซีที่มีออร์ค โนมส์ และเอลฟ์ สิ่งสำคัญคือการเลือกสิ่งที่คุณสนใจ สร้างสรรค์ พิมพ์ข้อความบนคอนโซล และสนุกกับการเรียนรู้เกี่ยวกับรูปแบบ!
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION