JavaRush /จาวาบล็อก /Random-TH /ปัญหาร้านพิซซ่า ช่างก่อสร้าง VS ช่างตกแต่ง
CynepHy6
ระดับ
Великий Новгород

ปัญหาร้านพิซซ่า ช่างก่อสร้าง VS ช่างตกแต่ง

เผยแพร่ในกลุ่ม

คำอธิบายของปัญหา

เราจำเป็นต้องเขียนโปรแกรม สำหรับร้านพิซซ่าที่ต้องการเตรียมพิซซ่าประเภทต่างๆ: ไก่, อเมริกัน, เนื้อ, ฮาวายเอี้ยน, เปปเปอโรนี ฯลฯ เรามาดูกันว่าเทมเพลตใดและในสถานการณ์ใดที่เหมาะกับการแก้ปัญหานี้ ตามเนื้อผ้า เทมเพลต Builder ใช้เพื่อแก้ปัญหา “ปัญหาพิซซ่า” นอกจากนี้ยังมีตัวอย่างการใช้รูปแบบมัณฑนากรซึ่งทั้งสองรูปแบบถูกต้องแต่มีความแตกต่างในการใช้งาน Builder เป็นเทมเพลตสำหรับสร้างวัตถุ ในขณะที่ Decorator ใช้เพื่อแก้ไขวัตถุที่เสร็จแล้วได้ทันที ลองทำความเข้าใจสิ่งนี้ด้วยตัวอย่าง:

1. เครื่องมือสร้างเทมเพลต:

ในกรณีนี้ พิซซ่าจะเตรียมส่วนผสมทั้งหมดพร้อมกัน
คลาสพิซซ่า:
public class Pizza{ private float totalPrice = 0; private Size size; private Topping topping; private Crust crust; private Cheese cheese; public Size getSize(){ return size; } public void setSize(Size size){ this.size = size; } public Topping getTopping(){ return topping; } public void setTopping(Topping topping){ this.topping = topping; } public Crust getCrust(){ return crust; } public void setCrust(Crust crust){ this.crust = crust; } public Cheese getCheese(){ return cheese; } public void setCheese(Cheese cheese){ this.cheese = cheese; } public float getTotalPrice(){ return totalPrice; } public void addToPrice(float price){ this.totalPrice = totalPrice + price; } }
4 คลาสแจกแจง:
public enum Cheese { AMERICAN{ public float getCost(){ return 40; } }, ITALIAN { public float getCost(){ return 60; } }; public abstract float getCost(); } public enum Crust { THIN{ public float getCost(){ return 70; } } , STUFFED{ public float getCost(){ return 90; } }; public abstract float getCost(); } public enum Size { MEDIUM { public float getCost() { return 100; } }, LARGE { public float getCost() { return 160; } }; public abstract float getCost(); } public enum Topping { PEPPERONI { public float getCost(){ return 30; } }, CHICKEN{ public float getCost(){ return 35; } }, MUSHROOM{ public float getCost(){ return 20; } }; public abstract float getCost(); }
คลาส PizzaBuilder:
public class PizzaBuilder { Pizza pizza = new Pizza(); public PizzaBuilder withTopping(Topping topping) { pizza.setTopping(topping); pizza.addToPrice(topping.getCost()); return this; } public PizzaBuilder withSize(Size size) { pizza.setSize(size); pizza.addToPrice(size.getCost()); return this; } public PizzaBuilder withCrust(Crust crust) { pizza.setCrust(crust); pizza.addToPrice(crust.getCost()); return this; } public Pizza build() { return pizza; } public double calculatePrice() { return pizza.getTotalPrice(); } }
การทดสอบในชั้นเรียน:
public class PizzaBuilderTest { @Test public void shouldBuildThinCrustChickenPizza(){ Pizza pizza = new PizzaBuilder().withCrust(Crust.THIN).withTopping(Topping.CHICKEN).withSize(Size.LARGE).build(); assertEquals(Topping.CHICKEN,pizza.getTopping()); assertEquals(Size.LARGE,pizza.getSize()); assertEquals(Crust.THIN,pizza.getCrust()); assertEquals(265.0,pizza.getTotalPrice(),0); } }

2. เทมเพลตมัณฑนากร:

รูปแบบมัณฑนากรใช้เพื่อเพิ่มหรือลบฟังก์ชันเพิ่มเติมให้กับวัตถุแบบไดนามิกโดยไม่ส่งผลกระทบต่อวัตถุต้นฉบับ ใช้เมื่อเตรียมฐานพิซซ่าก่อนแล้วจึงเติมส่วนผสมต่างๆ ที่นี่เราต้องการอินเทอร์เฟซ (Pizza) สำหรับ BasePizza (ส่วนประกอบพื้นฐาน) ที่เราต้องการตกแต่งและคลาส PizzaDecorator ที่ใช้อินเทอร์เฟซจริง
อินเตอร์เฟซพิซซ่า:
public interface Pizza { public String bakePizza(); public float getCost(); }
การใช้งานใน BasePizza:
public class BasePizza implements Pizza{ public String bakePizza() { return "Basic Pizza"; } public float getCost(){ return 100; } }
คลาส PizzaDecorator:
public class PizzaDecorator implements Pizza { Pizza pizza; public PizzaDecorator(Pizza newPizza) { this.pizza = newPizza; } public String bakePizza() { return pizza.bakePizza(); } @Override public float getCost() { return pizza.getCost(); } }
ตกแต่ง 2 อย่าง: เห็ดและเปปเปอโรนี
public class Mushroom extends PizzaDecorator { public Mushroom(Pizza newPizza) { super(newPizza); } @Override public String bakePizza() { return super.bakePizza() + " with Mushroom Topings"; } @Override public float getCost() { return super.getCost()+80; } } public class Pepperoni extends PizzaDecorator { public Pepperoni(Pizza newPizza) { super(newPizza); } @Override public String bakePizza() { return super.bakePizza() + " with Pepperoni Toppings"; } @Override public float getCost() { return super.getCost()+110; } }
การทดสอบในชั้นเรียน:
public class PizzaDecoratorTest { @Test public void shouldMakePepperoniPizza(){ Pizza pizza = new Pepperoni(new BasePizza()); assertEquals("Basic Pizza with Pepperoni Toppings",pizza.bakePizza()); assertEquals(210.0,pizza.getCost(),0); } }

ความแตกต่าง

รูปแบบเช่น Builder และ Factory (และ Abstract Factory) ถูกนำมาใช้ในการสร้างวัตถุใหม่ และรูปแบบต่างๆ เช่น มัณฑนากร (หรือที่เรียกว่ารูปแบบการออกแบบโครงสร้าง) ใช้สำหรับการขยายหรือเพื่อให้การเปลี่ยนแปลงโครงสร้างกับวัตถุที่สร้างขึ้นแล้ว รูปแบบทั้งสองประเภทส่งเสริมองค์ประกอบผ่านการสืบทอดเป็นหลัก และความแตกต่างไม่มีนัยสำคัญเพียงพอที่จะรับประกันว่าต้องใช้ตัวสร้างแทนตัวตกแต่ง ทั้งสองให้พฤติกรรมของตนเองเมื่อดำเนินการ แทนที่จะสืบทอดมัน ในกรณีหนึ่ง ควรใช้ Builder ดีกว่า - หากเราต้องการจำกัดการสร้างอ็อบเจ็กต์ที่มีคุณสมบัติ/ฟังก์ชันบางอย่าง ตัวอย่างเช่น มีแอตทริบิวต์ 4-5 ที่ต้องตั้งค่าก่อนที่จะสร้างวัตถุ หรือเราต้องการหยุดการสร้างวัตถุจนกว่าจะมีการตั้งค่าแอตทริบิวต์บางอย่าง พูดง่ายๆ ก็คือ ใช้มันแทน Constructor - ตามที่ Joshua Bloch เขียนใน Java: Effective Programming, 2nd ed ตัวสร้างจัดเตรียมคุณลักษณะที่วัตถุที่สร้างขึ้นควรมีแต่ซ่อนวิธีการตั้งค่าไว้ มัณฑนากรใช้เพื่อเพิ่มคุณสมบัติใหม่ให้กับวัตถุที่มีอยู่เมื่อสร้างวัตถุใหม่ตามนั้น ไม่มีข้อจำกัดในการแช่แข็งวัตถุในขณะที่กำลังเพิ่มคุณสมบัติทั้งหมด เทมเพลตทั้งสองใช้การจัดองค์ประกอบและอาจดูคล้ายกัน ความแตกต่างที่สำคัญคือการใช้งาน
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION