設計模式之工廠模式---物件的例項化部分提取出來---三種不同的提取方法
阿新 • • 發佈:2018-12-16
一、不使用工廠
披薩專案:要方便披薩品種的擴充套件、要便於維護、要能執行時擴充套件
披薩族的設計:
抽象Pizza類,有四個方法:prepare()、bake(),cut(),box()
實際的披薩:GreekPizza和CheesePizza
披薩工廠設計:if…else … if …else
1、抽象Pizza類
package com.java.jikexueyuan.pizzastore.pizza; public abstract class Pizza { protected String name; public abstract void prepare(); public void bake() { System.out.println(name+" baking;"); } public void cut() { System.out.println(name+" cutting;"); } public void box() { System.out.println(name+" boxing;"); } public void setname(String name) { this.name=name; } }
2、實際的披薩類
1)、CheesePizza
package com.java.jikexueyuan.pizzastore.pizza;
public class CheesePizza extends Pizza {
@Override
public void prepare() {
// TODO Auto-generated method stub
super.setname("CheesePizza");
System.out.println(name+" preparing;");
}
}
2)、GreekPizza
package com.java.jikexueyuan.pizzastore.pizza; public class GreekPizza extends Pizza { @Override public void prepare() { // TODO Auto-generated method stub super.setname("GreekPizza"); System.out.println(name+" preparing;"); } }
3、一般OrderPizza實現類
package com.java.jikexueyuan.pizzastore; public class OrderPizza { public OrderPizza() { Pizza pizza = null; String ordertype; do { ordertype = gettype(); //控制檯輸入 if (ordertype.equals("cheese")) { pizza = new CheesePizza(); } else if (ordertype.equals("greek")) { pizza = new GreekPizza(); } else if (ordertype.equals("pepper")) { pizza = new PepperPizza(); } else if (ordertype.equals("chinese")) { pizza = new ChinesePizza(); } else { break; } pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } while (true); } }
簡單工廠總結:如果要擴充套件新的pizza,就要將OrderPizza這個簡單工廠停下來修改其中程式碼。
4、怎麼改進呢?
將變化的地方抽取出來,使用簡單工廠來封裝,這樣就不用停止orderPizza的執行,如下:
二、簡單工廠(從主類提取例項化(變化)部分)
定義一個例項化披薩物件的類,封裝建立物件的程式碼
1、SimplePizzaFactory類
public class SimplePizzaFactory {
public Pizza CreatePizza(String ordertype) {
Pizza pizza = null;
if (ordertype.equals("cheese")) {
pizza = new CheesePizza();
} else if (ordertype.equals("greek")) {
pizza = new GreekPizza();
} else if (ordertype.equals("pepper")) {
pizza = new PepperPizza();
}
return pizza;
}
}
2、新的OrderPizza類
public class OrderPizza {
SimplePizzaFactory mSimplePizzaFactory;
public OrderPizza(SimplePizzaFactory mSimplePizzaFactory) {
setFactory(mSimplePizzaFactory);
}
public void setFactory(SimplePizzaFactory mSimplePizzaFactory) {
Pizza pizza = null;
String ordertype;
this.mSimplePizzaFactory = mSimplePizzaFactory;
do {
ordertype = gettype();
pizza = mSimplePizzaFactory.CreatePizza(ordertype);
if (pizza != null) {
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
} while (true);
}
三、工廠方法模式
將物件的例項化推遲到子類
困惑:披薩專案加盟店
解決:將披薩物件例項化功能抽象成抽象方法,在不同加盟店具體實現功能;
1、抽象的OrderPizza
package com.java.jikexueyuan.pizzastore.method;
public abstract class OrderPizza {
public OrderPizza() {
Pizza pizza = null;
String ordertype;
do {
ordertype = gettype();
pizza = createPizza(ordertype);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} while (true);
}
// 方法抽象出來
abstract Pizza createPizza(String ordertype);
}
2、實際的OrderPizza
1)、紐約的NYOrderPizza
package com.java.jikexueyuan.pizzastore.method;
public class NYOrderPizza extends OrderPizza {
@Override
Pizza createPizza(String ordertype) {
Pizza pizza = null;
if (ordertype.equals("cheese")) {
pizza = new NYCheesePizza();
} else if (ordertype.equals("pepper")) {
pizza = new NYPepperPizza();
}
return pizza;
}
}
2)、倫敦的LDOrderPizza
public class LDOrderPizza extends OrderPizza {
@Override
Pizza createPizza(String ordertype) {
Pizza pizza = null;
if (ordertype.equals("cheese")) {
pizza = new LDCheesePizza();
} else if (ordertype.equals("pepper")) {
pizza = new LDPepperPizza();
}
return pizza;
}
}
四、抽象工廠模式
定義一個介面,用於建立相關或有依賴關係的物件族,而無需明確指定具體類。
1、抽象AbsFactory類
package com.java.jikexueyuan.pizzastore.absfactory;
public interface AbsFactory {
public Pizza CreatePizza(String ordertype) ;
}
2、具體實現類
1)、倫敦LDFactory
package com.java.jikexueyuan.pizzastore.absfactory;
public class LDFactory implements AbsFactory {
@Override
public Pizza CreatePizza(String ordertype) {
Pizza pizza = null;
if (ordertype.equals("cheese")) {
pizza = new LDCheesePizza();
} else if (ordertype.equals("pepper")) {
pizza = new LDPepperPizza();
}
return pizza;
}
}
2)紐約NYFactory
package com.java.jikexueyuan.pizzastore.absfactory;
public class NYFactory implements AbsFactory {
@Override
public Pizza CreatePizza(String ordertype) {
Pizza pizza = null;
if (ordertype.equals("cheese")) {
pizza = new NYCheesePizza();
} else if (ordertype.equals("pepper")) {
pizza = new NYPepperPizza();
}
return pizza;
}
}
3、OrderPizza類(AbsFactory的具體工廠傳進來建立pizza物件)
package com.java.jikexueyuan.pizzastore.absfactory;
public class OrderPizza {
AbsFactory mFactory;
public OrderPizza(AbsFactory mFactory) {
setFactory(mFactory);
}
public void setFactory(AbsFactory mFactory) {
Pizza pizza = null;
String ordertype;
this.mFactory = mFactory;
do {
ordertype = gettype();
pizza = mFactory.CreatePizza(ordertype);
if (pizza != null) {
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
} while (true);
}
}
五、依賴抽象原則
1、變數不要持有具體類的引用
例如,OrderPizza類中建立披薩的變數;