廢話不多說,直接上代碼。
Pizza orderPizza(String type){
Pizza pizza;
if("chesse".equals(type)){
pizza = new ChessePizza();
}else if("clam".equals(type)){
? ?pizza = new ClamPizza();
}else if("veggle".equals(type)){
pizza = new VegglePizza();
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
假設上面就是orderPizza()方法就是根據不同type生產不同pizza(或者說處理訂單), 這樣的代碼很不好,當加入新的pizza類型后,又要修改上面的if else代碼,就是沒有對修改關閉,這也是變化的地方,我們可以把它們提前出來。
public class SimplePizzaFactory{
public Pizza createPizza(String type){
Pizza pizza;
if("chesse".equals(type)){
pizza = new ChessePizza();
}else if("clam".equals(type)){
? ?pizza = new ClamPizza();
}else if("veggle".equals(type)){
pizza = new VegglePizza();
}
return pizza;
}
}
這個SimplePizzaFactory類就是一個簡單比薩工廠,負責生產pizza.這和上面比較適合只是把問題搬到另一個類而已,也要修改if else,其實這個類目前看來只能提供pizza,但它可以擴展,不同用戶可以通過這個類獲取pizza,而且以后添加新pizza類修改時只要修改這個類而已。
這樣修改過后的代碼是這樣
public class PizzaStore(){
? ?SimplePizzaStroreFactory factory;
public PizzaStore(SimplePizzaStroreFactory factory){
this.factory = factory;
}
Pizza orderPizza(String type){
Pizza pizza;
pizza = factory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
//上面就展示了簡單工廠模式。(也有人說這不算真正工廠模式,更像是一種編程習慣)
假設現在有很多加盟商,他們利用SimplePizzaFactory,寫出了三種不同的工廠,分別是NYPizzaFactory,ChicagoPizzaFactory,CaliforniaPizzaFactory.
現在代碼就變成下面
NYPizzaFactoty nyFactory = new NyPizzaFactory();
PizzaStore nyStory = new PizzaStory(nyFactory);
nyStory.orderPizza("veggie");
//別的省略了
如果你希望pizza做法都相同,或者使用統一的包裝,那么該什么辦呢,
public abstract class PizzaStore(){//抽象類
Pizza orderPizza(String type){
Pizza pizza;
pizza = createPizza(type);//createPizza()從工廠對象中移回PizzaStore
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
abstract Pizza createPizza(String type);//現在把工廠對象移到這個方法中。
}
現在PizzaStore 作為超類,讓每個地域store繼承PizzaStore,每個子類決定如何制造pizza.
現在就是我們開的一家pizza店
public class NYPizzaStore extends PizzaStore{
Pizza createPizza(String item){
if("chesse".equals(type)){
return new NYChessePizza();
}else if("clam".equals(type)){
? ?return new NYClamPizza();
}else if("veggle".equals(type)){
return new NYVegglePizza();
}else{
return null;
}
}
}
//注意超類OrderPizza()方法,并不知道正在創建的比薩是哪一種,它只知道比薩可以被preapare(),bake(),box()等處理
這里是Pizza類
public abstract class Pizza(){
String name;
String dough;
String sauce;
ArrayList toppings = new ArrayList();
}
void prepare(){
System.out.println("------prepare----);
}
void bake(){
System.out.println("------bake----);
}
void box(){
System.out.println("------box----);
}
//省略getSet方法
}
//紐約風味的比薩
public class NYStylePizza extends Pizza{
public?NYStylePizza(){
name = "NYStylePizza";
dough = "thin crus dough";
sauce = "sauce";
?toppings.add(“chesse”)
}
}
//測試類
public class PizzaTestDrive(){
public static void main(String[] args){
PizzaStore nyStore= new NYPizzaStore();
PizzaStore chicagoStore= new ChicagoPizzaStore();
Pizza pizza = nyStore.oderPizza("chesse");
Pizza pizza = chicagoStore.oderPizza("chesse");
}
?}
抽象工廠方法模式
ps:設計原則 要依賴抽象,不要依賴具體類(依賴倒置原則Depemdency Inversion Principle)
回到比薩店,每個加盟店可能會對原料進行偷工減料,或者使用低價原料,我們如何保證他們用高質量原料?
我們可以建立原料工廠,不同區域有不同原料廠。原料家族包過面團、醬料、香料等,下面就是定于原料工廠
public interface PizzaIngredientFactory{
?public Dough createDough();
public Sauce createSauce();
public Chesse createChesse();
public Clams createClams();
}
現在不同區域建立不同的原料工廠,比如紐約原料工廠
public class NYPizzaIngredientFactory implements PizzaIngredientFactory{
public? Dough createDough(){
return new ThinCrustDough();
}
public Sauce createSauce(){
return new MarinaraSauce();
}
public Clams createClams(){
return new FreshClams();
}
}
現在的pizza抽象類如下
public abstract class Pizza{
String name;
Dough dough;
Sauce sauce;
Clams clams;
abstract void prepare();//這個方法聲明為抽象類在這個方法中,我們要收集比薩所需原料,這些原料來源于原料工廠。
void bake(){
System.out.println("bake");
}
//其它方法也是一樣就省略了。
}
直接來看比薩店吧
public class NYPizzaStore extends PizzaStore(){
protected Pizza createPizza(String item){
Pizza pizza = null;
PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
if(item.equals("chessse")){
pizza = new CheesePizza(ingreduentFactory);
pizza.setName("new york style cheesse Pizza")
}else if(item.equals("vegglie")){
pizza = new VeggliePizza(ingreduentFactory);
pizza.setName("new york style vegglie Pizza")
}else?if(item.equals("clam")){
pizza = new ClamPizza(ingreduentFactory);
pizza.setName("new york style clam Pizza")
}
return pizza;
}
下面是抽象工廠類圖