สวัสดี! วันนี้เราจะศึกษารูปแบบการออกแบบต่อไปและเราจะหารือเกี่ยวกับรูปแบบ โรงงานนามธรรม นี่คือสิ่งที่เราจะกล่าวถึงในบทเรียน:
- เราจะคุยกันว่าโรงงานนามธรรมคืออะไรและรูปแบบนี้แก้ปัญหาอะไรได้บ้าง
- เราจะสร้างโครงร่างของแอปพลิเคชันข้ามแพลตฟอร์มสำหรับการสั่งกาแฟผ่านอินเทอร์เฟซผู้ใช้
- เราจะศึกษาคำแนะนำในการใช้รูปแบบนี้ รวมถึงการดูไดอะแกรมและโค้ด
- และเพื่อเป็นโบนัส บทเรียนนี้มีไข่อีสเตอร์ที่ซ่อนอยู่ซึ่งจะช่วยให้คุณเรียนรู้วิธีใช้ 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 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) ที่มีฟิลด์เป็นองค์ประกอบอินเทอร์เฟซนามธรรมที่เริ่มต้นด้วยค่าที่จำเป็นในตัวสร้างโดยใช้โรงงานนามธรรม
- คลาสแอ็พพลิเคชัน ภายในคลาสนี้ เราสร้างฟอร์มโดยส่งการดำเนินการจากโรงงานที่ต้องการไปยังคอนสตรัคเตอร์
โรงงานบทคัดย่อ: วิธีใช้
โรงงานนามธรรมเป็นรูปแบบการออกแบบสำหรับการจัดการการสร้างตระกูลผลิตภัณฑ์ต่างๆ โดยไม่ผูกติดกับประเภทผลิตภัณฑ์ที่เป็นรูปธรรม เมื่อใช้รูปแบบนี้ คุณต้อง:- กำหนดตระกูลผลิตภัณฑ์ สมมติว่าเรามีสองคน:
SpecificProductA1
,SpecificProductB1
SpecificProductA2
,SpecificProductB2
- สำหรับแต่ละผลิตภัณฑ์ภายในตระกูล ให้กำหนดคลาสนามธรรม (อินเทอร์เฟซ) ในกรณีของเรา เรามี:
ProductA
ProductB
- ภายในแต่ละตระกูลผลิตภัณฑ์ แต่ละผลิตภัณฑ์ต้องใช้อินเทอร์เฟซที่กำหนดไว้ในขั้นตอนที่ 2
- สร้างโรงงานนามธรรม โดยมีวิธีการสร้างแต่ละผลิตภัณฑ์ที่กำหนดไว้ในขั้นตอนที่ 2 ในกรณีของเรา วิธีการเหล่านี้จะเป็น:
ProductA createProductA();
ProductB createProductB();
- สร้างแอ็บสแตรกต์แฟคตอรี่อิมพลีเมนต์ เพื่อให้แต่ละอิมพลีเมนต์ควบคุมการสร้างผลิตภัณฑ์ของครอบครัวเดียว ในการทำเช่นนี้ ในการใช้งานโรงงานนามธรรมแต่ละครั้ง คุณต้องใช้วิธีการสร้างทั้งหมดเพื่อสร้างและส่งคืนการใช้งานผลิตภัณฑ์เฉพาะ
// 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 สิ่ง:- ปรับแต่งแอปพลิเคชันสั่งกาแฟเพื่อให้ทำงานบน Linux ได้ด้วย
- สร้างโรงงานนามธรรมของคุณเองสำหรับการผลิตหน่วยที่เกี่ยวข้องกับกลยุทธ์ทางทหารใดๆ นี่อาจเป็นได้ทั้งกลยุทธ์ทางทหารตามประวัติศาสตร์ที่เกี่ยวข้องกับกองทัพจริง หรือกลยุทธ์แฟนตาซีที่มีออร์ค โนมส์ และเอลฟ์ สิ่งสำคัญคือการเลือกสิ่งที่คุณสนใจ สร้างสรรค์ พิมพ์ข้อความบนคอนโซล และสนุกกับการเรียนรู้เกี่ยวกับรูปแบบ!
GO TO FULL VERSION