สวัสดี! วันนี้เราจะมาศึกษารูปแบบการออกแบบและพูดคุยเกี่ยวกับโรงงานเชิงนามธรรม กัน ต่อ สิ่งที่เราจะทำในระหว่างการบรรยาย:
- เรามาพูดคุยกันว่าโรงงานเชิงนามธรรมคืออะไร และรูปแบบนี้ช่วยแก้ปัญหาอะไร
- เราจะสร้างกรอบการทำงานของแอปพลิเคชันข้ามแพลตฟอร์มสำหรับการสั่งกาแฟด้วยอินเทอร์เฟซผู้ใช้
- เรามาศึกษาคำแนะนำในการใช้รูปแบบนี้ด้วยไดอะแกรมและโค้ด
- โบนัสมีไข่อีสเตอร์ซ่อนอยู่ในการบรรยายซึ่งคุณจะได้เรียนรู้การกำหนดชื่อของระบบปฏิบัติการโดยใช้ Java และดำเนินการอย่างใดอย่างหนึ่งหรืออย่างอื่นขึ้นอยู่กับผลลัพธ์
- การสืบทอดใน Java;
- คลาสนามธรรมและวิธีการใน Java
รูปแบบโรงงานเชิงนามธรรมแก้ปัญหาอะไรได้บ้าง
โรงงานเชิงนามธรรมก็เหมือนกับรูปแบบโรงงานอื่นๆ ที่ช่วยเราจัดระเบียบการสร้างวัตถุใหม่ๆ ได้อย่างถูกต้อง ด้วยความช่วยเหลือนี้ เราจึงจัดการ "การเผยแพร่" ของตระกูลต่างๆ ของอ็อบเจ็กต์ที่เชื่อมต่อถึงกัน ตระกูลต่างๆ ของวัตถุที่สัมพันธ์กัน...มันคืออะไร? ไม่ต้องกังวล: ในทางปฏิบัติทุกอย่างจะง่ายกว่าที่คิด เริ่มจากกลุ่มของวัตถุที่เกี่ยวข้องกันก่อน สมมติว่าคุณและฉันกำลังพัฒนากลยุทธ์และมีหน่วยรบหลายหน่วยอยู่ในนั้น:- ทหารราบ;
- ทหารม้า;
- นักธนู
เรายังคงดำเนินการร้านกาแฟแบบอัตโนมัติต่อไป
ในการบรรยายครั้งล่าสุดเราได้ศึกษารูปแบบวิธีการของโรงงาน ซึ่งช่วยให้เราขยายธุรกิจกาแฟและเปิดจุดจำหน่ายกาแฟแห่งใหม่ได้หลายแห่ง วันนี้เราจะทำงานต่อไปเพื่อปรับปรุงธุรกิจของเราให้ทันสมัย เราจะวางรากฐานสำหรับแอปพลิเคชันเดสก์ท็อปใหม่สำหรับการสั่งกาแฟออนไลน์โดยใช้รูปแบบโรงงานแบบนามธรรม เมื่อเราเขียนแอปพลิเคชันสำหรับเดสก์ท็อป เราควรคิดถึงข้ามแพลตฟอร์มเสมอ แอปพลิเคชันของเราควรทำงานได้ทั้งบน 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 gui factory 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 gui factory 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 OrderCoffeeForm {
private final TextField customerNameTextField;
private final Select coffeTypeSelect;
private final Button orderButton;
public OrderCoffeeForm(GUIFactory factory) {
System.out.println("Creating order coffee form");
customerNameTextField = factory.createTextField();
coffeTypeSelect = factory.createSelect();
orderButton = factory.createButton();
}
}
โรงงานนามธรรมจะถูกส่งผ่านไปยังตัวสร้างแบบฟอร์ม ซึ่งสร้างองค์ประกอบอินเทอร์เฟซ เราจะส่งการใช้งานจากโรงงานที่จำเป็นไปยังตัวสร้าง เพื่อให้เราสามารถสร้างองค์ประกอบอินเทอร์เฟซสำหรับระบบปฏิบัติการเฉพาะได้
public class Application {
private OrderCoffeeForm orderCoffeeForm;
public void drawOrderCoffeeForm() {
// Определим Name операционной системы, получив meaning системной проперти через System.getProperty
String osName = System.getProperty("os.name").toLowerCase();
GUIFactory guiFactory;
if (osName.startsWith("win")) { // Для windows
guiFactory = new WindowsGUIFactory();
} else if (osName.startsWith("mac")) { // Для mac
guiFactory = new MacGUIFactory();
} else {
System.out.println("Unknown OS, can't draw form :( ");
return;
}
orderCoffeeForm = new OrderCoffeeForm(guiFactory);
}
public static void main(String[] args) {
Application application = new Application();
application.drawOrderCoffeeForm();
}
}
หากเรารันแอปพลิเคชันบน Windows เราจะได้ผลลัพธ์ดังต่อไปนี้:
Creating gui factory for Windows OS
Creating order coffee form
Creating TextField for Windows OS
Creating Select for Windows OS
Creating Button for Windows OS
บน Mac ผลลัพธ์จะเป็นดังนี้:
Creating gui factory for macOS
Creating order coffee form
Creating TextField for macOS
Creating Select for macOS
Creating Button for macOS
บนลินุกซ์:
Unknown OS, can't draw form :(
คุณและฉันได้ข้อสรุปดังต่อไปนี้ เราเขียนเฟรมเวิร์กสำหรับแอปพลิเคชัน GUI ที่สร้างองค์ประกอบอินเทอร์เฟซที่เหมาะสมสำหรับระบบปฏิบัติการที่กำหนด ให้เราทำซ้ำสิ่งที่เราสร้างขึ้น:
- ตระกูลผลิตภัณฑ์: ช่องป้อนข้อมูล ช่องเลือก และปุ่ม
- การใช้งานต่างๆ ของผลิตภัณฑ์ตระกูลนี้ สำหรับ Windows และ macOS
- โรงงานเชิงนามธรรม ซึ่งภายในเราได้กำหนดอินเทอร์เฟซสำหรับการสร้างผลิตภัณฑ์ของเรา
- การใช้งานโรงงานของเราสองครั้ง โดยแต่ละขั้นตอนมีหน้าที่รับผิดชอบในการสร้างกลุ่มผลิตภัณฑ์ที่เฉพาะเจาะจง
- แบบฟอร์มคลาส Java ซึ่งมีฟิลด์เป็นองค์ประกอบอินเทอร์เฟซแบบนามธรรมที่เริ่มต้นในตัวสร้างด้วยค่าที่ต้องการโดยใช้โรงงานแบบนามธรรม
- คลาสแอปพลิเคชัน ภายในนั้น เราสร้างแบบฟอร์มที่เราส่งต่อการดำเนินการที่จำเป็นของโรงงานของเราไปยังผู้สร้าง
โรงงานบทคัดย่อ: คำแนะนำสำหรับการใช้งาน
Abstract Factory คือรูปแบบการออกแบบสำหรับจัดการการสร้างตระกูลผลิตภัณฑ์ที่แตกต่างกัน โดยไม่เชื่อมโยงกับประเภทผลิตภัณฑ์เฉพาะ เมื่อใช้เทมเพลตนี้ คุณต้อง:- กำหนดกลุ่มผลิตภัณฑ์ด้วยตนเอง สมมติว่าเรามีสองอัน:
SpecificProductA1
,SpecificProductB1
SpecificProductA2
,SpecificProductB2
- สำหรับแต่ละผลิตภัณฑ์ภายในกลุ่ม ให้กำหนดคลาสนามธรรม (อินเทอร์เฟซ) ในกรณีของเราคือ:
ProductA
ProductB
- ภายในแต่ละตระกูลผลิตภัณฑ์ แต่ละผลิตภัณฑ์ต้องใช้อินเทอร์เฟซที่กำหนดไว้ในขั้นตอนที่ 2
- สร้างโรงงานเชิงนามธรรม ด้วยการสร้างวิธีการสำหรับแต่ละผลิตภัณฑ์ที่กำหนดไว้ในขั้นตอนที่ 2 ในกรณีของเรา วิธีการเหล่านี้จะเป็น:
ProductA createProductA();
ProductB createProductB();
- สร้างการใช้งานโรงงานนามธรรมเพื่อให้การใช้งานแต่ละครั้งควบคุมการสร้างผลิตภัณฑ์ในตระกูลเดียวกัน ในการทำเช่นนี้ ภายในการใช้งานโรงงานเชิงนามธรรมแต่ละครั้ง จำเป็นต้องใช้วิธีการสร้างทั้งหมด เพื่อให้มีการสร้างและส่งคืนการใช้งานที่เป็นรูปธรรมของผลิตภัณฑ์
// Определим общие интерфейсы продуктов
public interface ProductA {}
public interface ProductB {}
// Создадим различные реализации (семейства) наших продуктов
public class SpecificProductA1 implements ProductA {}
public class SpecificProductB1 implements ProductB {}
public class SpecificProductA2 implements ProductA {}
public class SpecificProductB2 implements ProductB {}
// Создадим абстрактную фабрику
public interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
// Создадим реализацию абстрактной фабрики для создания продуктов семейства 1
public class SpecificFactory1 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new SpecificProductA1();
}
@Override
public ProductB createProductB() {
return new SpecificProductB1();
}
}
// Создадим реализацию абстрактной фабрики для создания продуктов семейства 1
public class SpecificFactory2 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new SpecificProductA2();
}
@Override
public ProductB createProductB() {
return new SpecificProductB2();
}
}
การบ้าน
หากต้องการรวมเนื้อหา คุณสามารถทำได้ 2 สิ่ง:- ปรับปรุงแอปพลิเคชั่นสั่งกาแฟให้ทำงานบน Linux
- สร้างโรงงานเชิงนามธรรมของคุณเองเพื่อผลิตหน่วยกลยุทธ์ต่างๆ นี่อาจเป็นกลยุทธ์ทางประวัติศาสตร์ที่มีกองทัพจริงหรือแฟนตาซีกับออร์ค คนแคระ และเอลฟ์ สิ่งสำคัญคือคุณพบว่ามันน่าสนใจ สร้างสรรค์ โพสต์หมุดบนคอนโซล และสนุกไปกับการเรียนรู้รูปแบบ!
GO TO FULL VERSION