设计模式(2):工厂方法模式(Factory Method Pattern)
1.接著簡單工廠模式談起
在簡單工廠模式(靜態工廠模式)中,有一個負責創建對象的工廠類,在這個工廠類里負責所有對象的創建,為了根據用戶的不同需求創建不同的對象,工廠類需要進行檢查與判斷:
public class ListFactory {public static List createList(String which) {if(which.equals("ArrayList")) return new ArrayList();else if(which.equals("LinkedList")) return new LinkedList();else if(which.equals("MagicList")) return new MagicList();else //oops, no Concrete List you want} }在介紹簡單工廠模式的時候已經說過,這個模式的缺點就是當增加產品的時候需要修改這個工廠類,這就導致這個模式違背了開-閉原則(所謂的開-閉原則,就是說對擴展開放,對修改關閉)。即,增加新產品的時候,下圖中圈出來的部分就要修改了:
為了彌補簡單工廠模式的這個不足,引入了工廠方法模式(Factory Method Pattern)。
2. 工廠方法模式的結構
為了能夠應對將來新產品的增加,我們可以這樣考慮,每個工廠類只負責生產一種產品,這樣,當增加新的產品的時候,創建一個新的工廠類,這個新的工廠類負責創建這個新的產品。這樣就滿足了對擴展開放;同時,由于每個工廠類只負責一種產品的生產,原有的工廠類就不需要修改了,滿足了對修改關閉。
如果按照這個思路進行的話,那么我們有多少種產品,就需要對應數量的工廠類。如何組織這些工廠類呢?就是使用和簡單工廠模式中產品的形式,即有一個抽象工廠,然后有多個具體工廠。也就是說,面相抽象。
這個抽象工廠既可以是接口,也可以是抽象類,這取決于具體的邏輯了。如果所有的產品都需要某個或某些共同的操作的話,使用抽象類就比較好。
下圖就是工廠方法模式的結構圖:
這里面有四個角色,除了簡單工廠模式介紹的三種角色外,多了一個抽象工廠的角色。下面是代碼框架:
(1)抽象工廠
(2)具體工廠
public class ConcreteFactory1 implements Factory {//工廠方法public Product createProduct() {return new ConcreteProduct1();} }public class ConcreteFactory2 implements Factory {//工廠方法public Product createProduct() {return new ConcreteProduct2();} }(3)抽象產品
public interface Product {//something }(4)具體產品
public class ConcreteProduct1 implements Product {//something }public class ConcreteProduct2 implements Product {//something }這樣,客戶使用的時候,會是這樣:
public class Client {public static void main(String[] args) {Factory factory1=new ConcreteFactory1();Factory factory2=new ConcreteFactory2();Product product1=factory1.createProduct();//ConcreteProduct1Product product2=factory2.createProduct();//ConcreteProduct2//do something} }3.舉個例子
我們以制作披薩的披薩店為例。披薩店制作披薩,可以看做是一個簡單工廠模式。但是當在別的地方開分店的時候,由于不同的地方有不同的風味,那么披薩店也需要有不同的制作披薩的方法。但所有的披薩店還是有相同點的,就是它們都創建披薩。但是披薩連鎖店將來的發展可能會更好,也就是說會在被的地方開新的風味的披薩店。為了滿足這個需求,就可以使用工廠方法模式。
(1)披薩
不同風味的披薩都是披薩,所以可以創建一個抽象披薩:
現在,我們在New York和Chicago開了兩家分店,分別有各自風味的披薩:
public class NewYorkStylePizza implements Pizza {public String info() {return "New York style pizza.";} }public class ChicagoStylePizza implements Pizza {public String info() {return "Chicago style pizza.";} }以后可能會有新風味的披薩,但是只需要創建新的披薩類并實現Pizza接口就好了。
(2)披薩店
同樣,我們定義一個抽象的披薩店(使用接口,抽象類也可以):
現在有兩家分店:
public class NewYorkStylePizzaStore implements PizzaStore {public Pizza orderPizza() {return new NewYorkStylePizza();} }public class ChicagoStylePizzaStore implements PizzaStore {public Pizza orderPizza() {return new ChicagoStylePizza();} }好了,需要訂餐的時候就這樣:
PizzaStore nyStylePizzaStore=new NewYorkPizzaStore(); PizzaStore cgStylePizzaStore=new ChicagoPizzaStore();Pizza nyStylePizza=nyStylePizzaStore.orderPizza(); Pizza cgStylePizza=cgStylePizzaStore.orderPizza();//enjoy yourself然后,如果生意紅火,在北京也開了一家分店,制作北京風味的披薩:
public class BeijingStylePizza implements Pizza {public String info() {return "Beijing style pizza.";} }public class BeijingStylePizzaStore implements PizzaStore {public Pizza orderPizza() {return new BeijingStylePizza();} }然后,在北京就可以這樣點餐了:
PizzaStore bjStylePizzaStore=new BeijingStylePizzaStore(); Pizza bjStylePizza=bjStylePizzaStore.orderPizza();//enjoy yourself這樣,即使再多風味的分店,只需要創建新的披薩類和新的披薩店類就可以了。
4.Java中的工廠方法模式
Java集合框架中最重要的就是Collection接口。這個接口聲明了一個iterator()方法,要求所有實現這個接口的類都實現這個方法并返回一個Iterator對象。所以,這就是一個工廠方法。
參考資料:《Java與模式》,閻宏
總結
以上是生活随笔為你收集整理的设计模式(2):工厂方法模式(Factory Method Pattern)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1千多块LED家用投影仪好用吗
- 下一篇: 设计模式(3):抽象工厂模式(Abstr