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

- มรดกใน Java
- วิธีการนามธรรมและคลาสในภาษาจาวา
วิธีการของโรงงานแก้ปัญหาอะไรได้บ้าง?
รูปแบบการออกแบบโรงงานทั้งหมดมีผู้เข้าร่วมสองประเภท: ผู้สร้าง (ตัวโรงงานเอง) และผลิตภัณฑ์ (วัตถุที่สร้างโดยโรงงาน) ลองนึกภาพสถานการณ์ต่อไปนี้: เรามีโรงงานที่ผลิตรถยนต์ยี่ห้อ CodeGym รู้วิธีสร้างโมเดลรถยนต์ด้วยตัวถังประเภทต่างๆ:- รถเก๋ง
- เกวียนสถานี
- รถเก๋ง
- รถเก๋ง CodeGym
- CodeGym สเตชันแวกอน
- CodeGym คูเป้
- OneAuto รถเก๋ง
- OneAuto สเตชั่นแวกอน
- วันออโต้ คูเป้
เล็กน้อยเกี่ยวกับรูปแบบโรงงาน
ฉันขอเตือนคุณว่าก่อนหน้านี้เราสร้างร้านกาแฟเสมือนจริงเล็กๆ ด้วยความช่วยเหลือของโรงงานที่เรียบง่าย เราได้เรียนรู้วิธีสร้างกาแฟประเภทต่างๆ วันนี้เราจะทำตัวอย่างนี้ใหม่ ลองนึกดูว่าร้านกาแฟของเรามีลักษณะอย่างไร ด้วยโรงงานที่เรียบง่าย เรามีชั้นเรียนกาแฟ:
public class Coffee {
public void grindCoffee(){
// Grind the coffee
}
public void makeCoffee(){
// Brew the coffee
}
public void pourIntoCup(){
// Pour into a cup
}
}
และชั้นเรียนย่อยอีกหลายชั้นที่สอดคล้องกับประเภทกาแฟเฉพาะที่โรงงานของเราสามารถผลิตได้:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
เราสร้าง enum เพื่อให้ง่ายต่อการสั่งซื้อ:
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("Here's your coffee! Thanks! Come again!");
return coffee;
}
}
การปรับปรุงโรงงานที่เรียบง่ายให้ทันสมัย
ร้านกาแฟของเรากำลังไปได้สวย มากจนเรากำลังพิจารณาที่จะขยาย เราต้องการเปิดสถานที่ใหม่ เรากล้าหาญและกล้าได้กล้าเสีย ดังนั้นเราจะไม่สร้างร้านกาแฟที่น่าเบื่อ เราต้องการให้แต่ละร้านมีความพิเศษ ดังนั้น ในการเริ่มต้น เราจะเปิดสถานที่สองแห่ง: หนึ่งแห่งในอิตาลีและหนึ่งแห่งในอเมริกา การเปลี่ยนแปลงเหล่านี้จะส่งผลต่อการออกแบบภายในไม่เพียงเท่านั้น แต่ยังรวมถึงเครื่องดื่มที่นำเสนอด้วย:- ในร้านกาแฟอิตาลี เราจะใช้กาแฟแบรนด์อิตาลีโดยเฉพาะ มีการบดและคั่วแบบพิเศษ
- สถานที่ในอเมริกาจะมีปริมาณที่มากกว่า และเราจะเสิร์ฟมาร์ชเมลโล่ทุกครั้งที่สั่ง
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("Here's your coffee! Thanks! Come again!");
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) {
/*
Order an Italian-style cappuccino:
1. Create a factory for making Italian coffee
2. Create a new coffee shop, passing the Italian coffee factory to it through the constructor
3. Order our coffee
*/
SimpleItalianCoffeeFactory italianCoffeeFactory = new SimpleItalianCoffeeFactory();
CoffeeShop italianCoffeeShop = new CoffeeShop(italianCoffeeFactory);
italianCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);
/*
Order an American-style cappuccino
1. Create a factory for making American coffee
2. Create a new coffee shop, passing the American coffee factory to it through the constructor
3. Order our coffee
*/
SimpleAmericanCoffeeFactory americanCoffeeFactory = new SimpleAmericanCoffeeFactory();
CoffeeShop americanCoffeeShop = new CoffeeShop(americanCoffeeFactory);
americanCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);
}
}
เราสร้างร้านกาแฟที่แตกต่างกัน 2 แห่ง โดยส่งต่อโรงงานที่ต้องการไปยังแต่ละแห่ง ในแง่หนึ่ง เราได้บรรลุวัตถุประสงค์ของเราแล้ว แต่อีกทางหนึ่ง... สิ่งนี้ไม่เหมาะกับผู้ประกอบการ... มาดูกันว่าอะไรผิด ประการแรก ความอุดมสมบูรณ์ของโรงงาน อะไร ตอนนี้สำหรับสถานที่ใหม่ทุกแห่ง เราควรจะสร้างโรงงานของตัวเอง และยิ่งไปกว่านั้น ตรวจสอบให้แน่ใจว่าได้ส่งโรงงานที่เกี่ยวข้องไปยังตัวสร้างเมื่อสร้างร้านกาแฟ ประการที่สองยังคงเป็นโรงงานที่เรียบง่าย ปรับปรุงให้ทันสมัยเพียงเล็กน้อย แต่เรามาที่นี่เพื่อเรียนรู้รูปแบบใหม่ ประการที่สาม แนวทางอื่นเป็นไปได้หรือไม่ จะดีมากถ้าเราสามารถใส่ประเด็นทั้งหมดที่เกี่ยวข้องกับการเตรียมกาแฟลงในCoffeeShop
คลาสโดยเชื่อมโยงกระบวนการสร้างกาแฟและการเสิร์ฟตามออร์เดอร์ โดยยังคงความยืดหยุ่นเพียงพอในการชงกาแฟรูปแบบต่างๆ คำตอบคือใช่ เราทำได้ สิ่งนี้เรียกว่ารูปแบบการออกแบบโรงงาน
จากโรงงานธรรมดาสู่วิธีการโรงงาน
เพื่อแก้ปัญหาอย่างมีประสิทธิภาพที่สุด:- เราคืน
createCoffee(CoffeeType type)
วิธีการให้กับCoffeeShop
ชั้นเรียน - เราจะทำให้วิธีนี้เป็นนามธรรม
- ชั้น
CoffeeShop
เรียนจะกลายเป็นนามธรรม - ชั้น
CoffeeShop
เรียนจะมีชั้นเรียนเด็ก
CoffeeShop
ชั้นเรียนซึ่งใช้createCoffee(CoffeeType type)
วิธีการตามประเพณีที่ดีที่สุดของบาริสต้าชาวอิตาลี ตอนนี้ทีละขั้นตอน ขั้นตอนที่ 1 ทำให้Coffee
ชั้นเรียนเป็นนามธรรม เรามีผลิตภัณฑ์ที่แตกต่างกันทั้งหมดสองตระกูล ถึงกระนั้น กาแฟของอิตาลีและอเมริกาก็มีบรรพบุรุษร่วมกัน นั่นคือCoffee
คลาส เป็นการเหมาะสมที่จะทำให้เป็นนามธรรม:
public abstract class Coffee {
public void makeCoffee(){
// Brew the coffee
}
public void pourIntoCup(){
// Pour into a cup
}
}
ขั้นตอนที่ 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("Here's your coffee! Thanks! Come again!");
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);
}
}
ยินดีด้วย. เราเพิ่งใช้รูปแบบการออกแบบโรงงานโดยใช้ตัวอย่างร้านกาแฟของเรา
หลักการเบื้องหลังวิธีการของโรงงาน
ตอนนี้เรามาพิจารณารายละเอียดเพิ่มเติมเกี่ยวกับสิ่งที่เราได้รับ แผนภาพด้านล่างแสดงคลาสผลลัพธ์ บล็อกสีเขียวคือคลาสผู้สร้าง และบล็อกสีน้ำเงินคือคลาสผลิตภัณฑ์
- ผลิตภัณฑ์ทั้งหมดเป็นการใช้งานของ
Coffee
คลาส นามธรรม CoffeeShop
ผู้สร้างทั้งหมดเป็นการนำ คลาสนามธรรมไปใช้- เราเห็นลำดับชั้นของคลาสคู่ขนานสองลำดับ:
- ลำดับชั้นของผลิตภัณฑ์ เราเห็นลูกหลานชาวอิตาลีและลูกหลานชาวอเมริกัน
- ลำดับชั้นของผู้สร้าง เราเห็นลูกหลานชาวอิตาลีและลูกหลานชาวอเมริกัน
- ซู
CoffeeShop
เปอร์คลาสไม่มีข้อมูลเกี่ยวกับผลิตภัณฑ์เฉพาะ (Coffee
) ที่จะถูกสร้างขึ้น - ซู
CoffeeShop
เปอร์คลาสมอบหมายการสร้างผลิตภัณฑ์เฉพาะให้กับผู้สืบทอด - ผู้สืบทอดของ
CoffeeShop
คลาสแต่ละคนใช้createCoffee()
วิธีการโรงงานตามคุณสมบัติเฉพาะของตนเอง กล่าวอีกนัยหนึ่ง การดำเนินการของคลาสผู้ผลิตจะเตรียมผลิตภัณฑ์เฉพาะตามลักษณะเฉพาะของคลาสผู้ผลิต
โครงสร้างของวิธีการในโรงงาน

- คลาส Creator ใช้เมธอดทั้งหมดที่โต้ตอบกับผลิตภัณฑ์ ยกเว้นเมธอดโรงงาน
- วิธี การนามธรรม
factoryMethod()
จะต้องดำเนินการโดยลูกหลานของCreator
ชั้นเรียน ทั้งหมด - คลาส
ConcreteCreator
ใช้factoryMethod()
วิธีการซึ่งสร้างผลิตภัณฑ์โดยตรง - คลาสนี้มีหน้าที่สร้างผลิตภัณฑ์เฉพาะ นี่เป็นคลาสเดียวที่มีข้อมูลเกี่ยวกับการสร้างผลิตภัณฑ์เหล่านี้
- ผลิตภัณฑ์ทั้งหมดต้องใช้อินเทอร์เฟซร่วมกัน นั่นคือผลิตภัณฑ์เหล่านี้ต้องสืบทอดมาจากคลาสผลิตภัณฑ์ทั่วไป นี่เป็นสิ่งจำเป็นเพื่อให้คลาสที่ใช้ผลิตภัณฑ์สามารถดำเนินการกับมันได้ในลักษณะที่เป็นนามธรรม แทนที่จะนำไปใช้เฉพาะ
GO TO FULL VERSION