上篇我們已經完成工廠跟Pizza的抽象類別,現在來看看子類別要如何實現Pizza()
,在這之前要先完成食材的類別(這邊以Cheese()
示範,完整程式碼點文章最後連結):
public interface Cheese{
public String getName();
}
public class CheddarCheese implements Cheese{
protected String name;
public CheddarCheese(){
this.name = "CheddarCheese";
}
public String getName(){
return this.name;
}
}
public class MozzarellaCheese implements Cheese{
protected String name;
public MozzarellaCheese(){
this.name = "MozzarellaCheese";
}
public String getName(){
return this.name;
}
}
public class CheesePizza extends Pizza{
IngredientFactory factory;
public CheesePizza(IngredientFactory factory){
this.factory = factory;
}
public void prepare(){
System.out.println("Preparing "+ this.name);
//用特定工廠的食材
dough = factory.createDough();
sauce = factory.createSauce();
cheese = factory.createCheese();
}
}
public class SeafoodPizza extends Pizza{
IngredientFactory factory;
public SeafoodPizza(IngredientFactory factory){
this.factory = factory;
}
public void prepare(){
System.out.println("Preparing "+ this.name);
//用特定工廠的食材
dough = factory.createDough();
sauce = factory.createSauce();
cheese = factory.createCheese();
seafood = factory.createSeafood();
}
}
即使都是CheesePizza()
,若是由不同工廠生產的,利用不同子類別去繼承同種食材的介面,就可以有一些地區差異的彈性,,而食材的製造過程由工廠實行。
public class ChicagoPizzaFactory implements IngredientFactory{
public Dough createDough(){
Dough dough = new ThickDough();
return dough;
}
public Sauce createSauce(){
//醬汁的子類別是茄汁
Sauce sauce = new Ketchup();
return sauce;
}
public Cheese createCheese(){
Cheese cheese = new MozzarellaCheese();
return cheese;
}
public Seafood createSeafood(){
Seafood clam = new Clam();
return clam;
}
public Veggies createVeggies() {
Veggies onion = new Onion();
return onion;
}
}
public class NYPizzaFactory implements IngredientFactory{
public Dough createDough(){
Dough dough = new ThinDough();
return dough;
}
public Sauce createSauce(){
//醬汁的子類別是白醬
Sauce sauce = new WhiteSauce();
return sauce;
}
public Cheese createCheese(){
Cheese cheese = new CheddarCheese();
return cheese;
}
public Seafood createSeafood(){
Seafood shrimp = new FrozenShrimp();
return shrimp;
}
public Veggies createVeggies() {
Veggies onion = new Pea();
return onion;
}
}
最後可以從PizzaStore()
子類別去了解整個流程,客人點餐以後,orderPizza()
會呼叫createPizza()
。
由指定的工廠去生產某個口味的Pizza食材,pizza.prepare()
把食材組成Pizza,再送回店裡做剩下的 bake()
cut()
box()
。
public abstract class PizzaStore {
abstract protected Pizza createPizza(String item);
abstract void orderPizza(String item);
}
public class NYPizzaStore extends PizzaStore{
protected Pizza createPizza(String item){
Pizza pizza = null;
IngredientFactory NYFactory = new NYPizzaFactory();
if(item.equals("cheese")){
pizza = new CheesePizza(NYFactory);
pizza.setName("NY Cheese Pizza");
}
else if(item.equals("vegan")){
pizza = new VeganPizza(NYFactory);
pizza.setName("NY Vegan Pizza");
}
else if(item.equals("seafood")){
pizza = new SeafoodPizza(NYFactory);
pizza.setName("NY forzen seafood Pizza :))");
}
else{
pizza = new ComboPizza(NYFactory);
pizza.setName("NY style mix favor combo pizza");
}
return pizza;
}
public void orderPizza(String item){
Pizza pizza = createPizza(item);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
pizza.getName();
System.out.println("Your order is ready! ");
}
}
public class FactoryPattern {
public static void main(String[] args) {
PizzaStore nyPizzaStore = new NYPizzaStore();
nyPizzaStore.orderPizza("seafood");
System.out.println("_________________________");
PizzaStore chicagoPizzaStore = new ChicagoPizzaStore();
chicagoPizzaStore.orderPizza("seafood");
}
}
輸出結果可以看到不同分店的同樣口味使用子類別的食材不同
https://github.com/changtintin/Design-Pattern/tree/master/Ch4/Java/FactoryPattern
Disclaimer
因為讀的是原文版,所以難免會有翻譯詞不達意或是專有名詞上的差異,有錯誤的話歡迎在留言區一起交流!