ไงเพื่อน! วันนี้เราจะศึกษารูปแบบการออกแบบกับคุณต่อไป ในการบรรยายครั้งนี้เราจะพูดถึงโรงงาน เราจะหารือกับคุณเกี่ยวกับวิธีแก้ปัญหาโดยใช้เทมเพลตนี้ และดูตัวอย่างว่าโรงงานช่วยเปิดร้านกาแฟได้อย่างไร และฉันจะให้ 5 ขั้นตอนง่ายๆ แก่คุณในการสร้างโรงงาน เพื่อให้เป็นหนึ่งเดียวกับทุกคนและเข้าใจสาระสำคัญได้ง่าย คุณควรทำความคุ้นเคยกับหัวข้อต่อไปนี้:
- การสืบทอดใน Java
- การจำกัดและขยายประเภทการอ้างอิงใน Java
- ปฏิสัมพันธ์ระหว่างคลาสและวัตถุต่างๆ
โรงงานคืออะไร?
รูปแบบการออกแบบของโรงงานช่วยให้คุณควบคุมการสร้างวัตถุได้ กระบวนการสร้างวัตถุใหม่นั้นไม่ง่ายนัก แต่ก็ไม่ได้ซับซ้อนเกินไปเช่นกัน เราทุกคนรู้ดีว่าในการสร้างวัตถุใหม่เราต้องใช้นามสกุลnew
. และอาจดูเหมือนไม่มีอะไรต้องจัดการที่นี่ แต่ก็ไม่เป็นเช่นนั้น ปัญหาอาจเกิดขึ้นเมื่อแอปพลิเคชันของเรามีคลาสที่แน่นอนซึ่งมีผู้สืบทอดจำนวนมาก และจำเป็นต้องสร้างอินสแตนซ์ของคลาสบางคลาส ขึ้นอยู่กับเงื่อนไขบางประการ โรงงานเป็นรูปแบบการออกแบบที่ช่วยแก้ปัญหาการสร้างวัตถุต่าง ๆ ขึ้นอยู่กับเงื่อนไขบางประการ นามธรรมใช่ไหม? ความเฉพาะเจาะจงและความชัดเจนมากขึ้นจะปรากฏขึ้นเมื่อเราดูตัวอย่างด้านล่าง
เราสร้างสรรค์กาแฟประเภทต่างๆ
สมมติว่าเราต้องการทำให้ร้านกาแฟเป็นแบบอัตโนมัติ เราจำเป็นต้องเรียนรู้วิธีการเตรียมกาแฟประเภทต่างๆ ในการทำเช่นนี้ในแอปพลิเคชันของเรา เราจะสร้างคลาสกาแฟและอนุพันธ์ของมัน: อเมริกาโน คาปูชิโน่ เอสเพรสโซ ลาเต้ - กาแฟประเภทนั้นที่เราจะเตรียมไว้ เริ่มจากคลาสกาแฟทั่วไปกันก่อน: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 {}
ลูกค้าของเราจะสั่งกาแฟบางประเภท และข้อมูลนี้จะต้องส่งผ่านไปยังโปรแกรม ซึ่งสามารถทำได้หลายวิธี เช่น การใช้String
. แต่เหมาะที่สุดสำหรับวัตถุประสงค์เหล่าenum
นี้ มาสร้างenum
และกำหนดประเภทของกาแฟที่เรารับคำสั่งซื้อกันดีกว่า:
public enum CoffeeType {
ESPRESSO,
AMERICANO,
CAFFE_LATTE,
CAPPUCCINO
}
เยี่ยมเลย ตอนนี้เรามาเขียนโค้ดสำหรับร้านกาแฟของเรากันดีกว่า:
public class CoffeeShop {
public Coffee orderCoffee(CoffeeType type) {
Coffee coffee = null;
switch (type) {
case AMERICANO:
coffee = new Americano();
break;
case ESPRESSO:
coffee = new Espresso();
break;
case CAPPUCCINO:
coffee = new Cappucсino();
break;
case CAFFE_LATTE:
coffee = new CaffeLatte();
break;
}
coffee.grindCoffee();
coffee.makeCoffee();
coffee.pourIntoCup();
System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
return coffee;
}
}
วิธีนี้orderCoffee
สามารถแบ่งออกเป็นสององค์ประกอบ:
switch-case
การสร้างอินสแตน ซ์กาแฟเฉพาะในบล็อก นี่คือสิ่งที่โรงงานทำคือการสร้างประเภทเฉพาะขึ้นอยู่กับเงื่อนไข- การเตรียมนั้นคือการบด ปรุง และเทลงในถ้วย
- อัลกอริธึมการเตรียมอาหาร (การบด การทำอาหาร และการเทลงในถ้วย) จะไม่เปลี่ยนแปลง (อย่างน้อยเราก็หวังเช่นนั้น)
- แต่ช่วงของกาแฟอาจมีการเปลี่ยนแปลง บางทีเราอาจจะเริ่มทำมอคค่า.. มอคค่า.. มอกคาชิ... ขอให้พระเจ้าอวยพรเขา กาแฟรูปแบบใหม่
switch-case
. อาจเป็นไปได้ว่าในร้านกาแฟของเรา วิธีการorderCoffee
จะไม่ใช่ที่เดียวที่เราสร้างสรรค์กาแฟประเภทต่างๆ จึงต้องมีการเปลี่ยนแปลงหลายจุด คุณคงเข้าใจแล้วว่าฉันกำลังทำอะไรอยู่ เราจำเป็นต้องปรับโครงสร้างใหม่ ย้ายบล็อกที่รับผิดชอบในการสร้างกาแฟไปไว้ในคลาสที่แยกจากกันด้วยเหตุผลสองประการ:
- เราจะสามารถนำตรรกะของการสร้างกาแฟจากที่อื่นกลับมาใช้ใหม่ได้
- หากช่วงมีการเปลี่ยนแปลง เราจะไม่ต้องแก้ไขโค้ดทุกที่ที่จะใช้การสร้างกาแฟ เปลี่ยนรหัสที่เดียวก็เพียงพอแล้ว
เรากำลังเห็นโรงงานแห่งแรกของเรา
เมื่อต้องการทำเช่นนี้ เรามาสร้างคลาสใหม่ที่จะรับผิดชอบเฉพาะการสร้างอินสแตนซ์ที่จำเป็นของคลาสกาแฟเท่านั้น: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 Cappucino();
break;
case CAFFE_LATTE:
coffee = new CaffeLatte();
break;
}
return coffee;
}
}
ยินดีด้วย! เราเพิ่งใช้รูปแบบการออกแบบของโรงงานในรูปแบบที่ง่ายที่สุด แม้ว่าทุกอย่างอาจจะง่ายกว่านี้อีกหากวิธีการนี้คงcreateCoffee
ที่ แต่แล้วเราจะสูญเสียความเป็นไปได้สองประการ:
- สืบทอดจาก
SimpleCoffeeFactory
และแทนที่createCoffee
. - ปรับใช้การใช้งานโรงงานที่จำเป็นในชั้นเรียนของเรา
การนำโรงงานมาเป็นร้านกาแฟ
มาเขียนคลาสร้านกาแฟของเราใหม่โดยใช้โรงงาน: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;
}
}
ยอดเยี่ยม. ตอนนี้เรามาพยายามอธิบายโครงสร้างของรูปแบบการออกแบบโรงงานในเชิงแผนผังและกระชับ
5 ขั้นตอนในการเปิดโรงงานของคุณเอง
ขั้นตอนที่ 1. ในโปรแกรมของคุณ คุณจะมีคลาสที่มีผู้สืบทอดหลายราย ดังภาพด้านล่าง: ขั้นตอนที่ 2 คุณสร้างคลาสenum
ที่คุณกำหนดตัวแปร enum สำหรับแต่ละคลาสลูกหลาน:
enum CatType {
LION,
TIGER,
BARSIK
}
ขั้นตอนที่ 3 คุณสร้างโรงงานของคุณ คุณเรียกมันMyClassFactory
ว่า รหัสอยู่ด้านล่าง:
class CatFactory {}
ขั้นตอนที่ 4 คุณสร้างวิธีการในโรงงานของคุณcreateMyClass
ที่รับตัวแปรenum
MyClassType
- รหัสด้านล่าง:
class CatFactory {
public Cat createCat(CatType type) {
}
}
ขั้นตอนที่ 5 คุณเขียนบล็อกในเนื้อความของวิธีการswitch-case
ที่คุณวนซ้ำค่าแจงนับทั้งหมดและสร้างอินสแตนซ์ของคลาสที่สอดคล้องกับenum
ค่า:
class CatFactory {
public Cat createCat(CatType type) {
Cat cat = null;
switch (type) {
case LION:
cat = new Barsik();
break;
case TIGER:
cat = new Tiger();
break;
case BARSIK:
cat = new Lion();
break;
}
return cat;
}
}
เหมือนเจ้านาย.
GO TO FULL VERSION