ไงเพื่อน! วันนี้เราจะมาศึกษารูปแบบการออกแบบกันต่อนะครับ ในบทเรียนนี้ เราจะพูดถึงโรงงาน เราจะหารือเกี่ยวกับปัญหาที่รูปแบบนี้แก้ไขได้ และดูตัวอย่างว่าโรงงานสามารถช่วยคุณเปิดร้านกาแฟได้อย่างไร นอกจากนี้ ฉันจะให้ 5 ขั้นตอนง่ายๆ ในการสร้างโรงงานแก่คุณ เพื่อให้แน่ใจว่าเราทุกคนอยู่ในช่วงความยาวคลื่นเดียวกัน และคุณจะเข้าใจแนวคิดนี้ได้อย่างรวดเร็ว คุณควรคุ้นเคยกับหัวข้อต่อไปนี้:
- มรดกใน Java
- การจำกัดและการขยายประเภทการอ้างอิงใน Java
- ปฏิสัมพันธ์ระหว่างคลาสและวัตถุต่างๆ
โรงงานคืออะไร?
รูปแบบการออกแบบจากโรงงานช่วยให้คุณควบคุมการสร้างวัตถุได้ กระบวนการสร้างวัตถุใหม่นั้นไม่ง่ายนัก แต่ก็ไม่ซับซ้อนจนเกินไป เราทุกคนรู้ว่าเราต้องการnew
ตัวดำเนินการเพื่อสร้างวัตถุใหม่ บางทีดูเหมือนว่าไม่มีอะไรจะควบคุมที่นี่ แต่นั่นไม่เป็นความจริง สมมติว่าแอปพลิเคชันของเรามีคลาสหนึ่งที่มีลูกหลานจำนวนมาก ความยากลำบากอาจเกิดขึ้นเมื่อจำเป็นต้องสร้างอินสแตนซ์ของคลาสเฉพาะโดยขึ้นอยู่กับเงื่อนไขบางประการ โรงงานเป็นรูปแบบการออกแบบที่ช่วยแก้ปัญหาในการสร้างวัตถุต่าง ๆ ขึ้นอยู่กับเงื่อนไขบางประการ เป็นอย่างไรสำหรับแนวคิดเชิงนามธรรม? สิ่งนี้จะชัดเจนและเฉพาะเจาะจงมากขึ้นเมื่อเราดูตัวอย่างด้านล่าง
มาเตรียมกาแฟประเภทต่างๆ กันเถอะ
สมมติว่าเราต้องการทำให้ร้านกาแฟเป็นแบบอัตโนมัติ เราต้องสอนโปรแกรมของเราถึงวิธีการชงกาแฟประเภทต่างๆ ในการทำเช่นนี้ เราจะสร้างคลาสกาแฟและคลาสอนุพันธ์สองสามคลาสเพื่อแสดงถึงประเภทของกาแฟที่เราจะเตรียม: อเมริกาโน คาปูชิโน เอสเพรสโซ และลาเต้ เริ่มต้นด้วยคลาสกาแฟทั่วไป:
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 {}
ลูกค้าของเราสามารถสั่งกาแฟชนิดใดก็ได้ คำสั่งของพวกเขาจะต้องถูกส่งไปยังโปรแกรม ทำได้หลายวิธี เช่นString
ใช้ แต่สิ่งenum
ที่ดีที่สุดสำหรับสิ่งนี้ เราจะสร้าง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("Here's your coffee! Thanks! Come again!");
return coffee;
}
}
วิธี การorderCoffee
สามารถแบ่งออกเป็นสองส่วน:
- การสร้างตัวอย่างเฉพาะของกาแฟใน
switch
แถลงการณ์ นี่คือสิ่งที่โรงงานทำ - สร้างประเภทเฉพาะขึ้นอยู่กับเงื่อนไข - การเตรียม — นี่คือการบด การต้ม และการเทลงในถ้วย
- ขั้นตอนที่เกี่ยวข้องในการเตรียม (การบด การชง และการเทใส่ถ้วย) จะไม่เปลี่ยนแปลง (อย่างน้อยเราก็คาดหวังในเรื่องนี้)
- แต่ประเภทของกาแฟอาจมีการเปลี่ยนแปลง บางทีเราอาจจะเริ่มทำมอคค่า... แฟรปปุ... มอคค่าชี่... อะไรก็ตามที่เป็นกาแฟรูปแบบใหม่
switch
คำสั่ง ของวิธีการ อาจเป็นไปได้ว่าในร้านกาแฟของเรา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("Here's your coffee! Thanks! Come again!");
return coffee;
}
}
ยอดเยี่ยม. ตอนนี้เราจะให้คำอธิบายสั้น ๆ เกี่ยวกับโครงสร้างทั่วไปของรูปแบบการออกแบบโรงงาน
5 ขั้นตอนในการเปิดโรงงานของคุณเอง
ขั้นตอนที่ 1 โปรแกรมของคุณมีคลาสที่มีลูกหลานหลายคลาส ดังแผนภาพด้านล่าง: ขั้นตอนที่ 2 คุณสร้าง anenum
ด้วยฟิลด์สำหรับแต่ละคลาสย่อย:
enum CatType {
LION,
TIGER,
FLUFFY
}
ขั้นตอนที่ 3 สร้างโรงงานของคุณ โทรCatFactory
เลย นี่คือรหัส:
class CatFactory {}
ขั้นตอนที่ 4 ในโรงงานของคุณ สร้างcreateCat
วิธีการที่จะCatType
โต้แย้ง นี่คือรหัส:
class CatFactory {
public Cat createCat(CatType type) {
}
}
ขั้นตอนที่ 5 ในเนื้อหาของเมธอด ให้เขียนswitch
คำสั่งที่ระบุฟิลด์ enum และสร้างอินสแตนซ์ของคลาสที่สอดคล้องกับenum
ค่าที่ส่งผ่าน:
class CatFactory {
public Cat createCat(CatType type) {
Cat cat = null;
switch (type) {
case LION:
cat = new Fluffy();
break;
case TIGER:
cat = new Tiger();
break;
case FLUFFY:
cat = new Lion();
break;
}
return cat;
}
}
ตอนนี้คุณสามารถบริหารโรงงานได้เหมือนเจ้านาย :)
GO TO FULL VERSION