一、不使用工廠
披薩項目:要方便披薩品種的擴展、要便於維護、要能運行時擴展
披薩族的設計:
抽象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類中創建披薩的變量;