工廠模式主要負責将大量有共通接口的類執行個體化,工場模式有以下幾種形态
簡單工廠(Simple Factory) 又稱 靜态工廠方法(Static Factory Method)
工廠方法(Factory Method) 又稱 多态性工廠(Polymorphic Factory)
抽象工廠(Abstract Factory) 又稱 工具箱(Kit or Toolkit)
先說簡單工廠模式:
需求:一個水果工廠,為任何來的客人提供水果,現有水果Apple ,Banana,Orange
實作:
定義三個類Apple,Banana,Orange 讓他們都實作Fruit接口
----------------------- list 1 --------------------------------
public class FruitFactory
{
public static Fruit factory(String which)
{
if (which.equalsIgnoreCase( " apple " )
{
returnnewApple();
} else if (which equalsIgnoreCase( " banana " ))
{
returnnewBanana();
} else if (which equalsIgnoreCase( " orange " ))
{
returnnewOrange();
} else
{
throw RuntimeException( " no this fruit " );
}
}
}
----------------------- list 1 --------------------------------
客人的需求實作
1
try
{2
FruitFactory.factory( " apple " );3
FruitFactory.factory( " banana " );4
FruitFactory.factory( " orange " );5
}catch (Exception e)
{6
7
}8
優點:分開了生産者和消費者的責任
缺點:所有的産品都出自一個工廠
造成問題:
1,當這個工廠出現問題時,損失慘重,不利于分散風險
2,當出現不同種類的水果(有不同接口的水果),工場内部既須要判斷種類,又須要判斷具體的産品。
比如這種結構:
1,水果接口Fruit
2,兩個種類水果實作了Fruit接口 有籽水果 /無籽水果
3,所有有籽水果繼承自有籽水果類 ,所有無籽水果繼承自無籽水果類
這事如果客戶要有籽西瓜,無籽西瓜 工廠類的實作
1
----------------------- list 2 -------------------------------- 2
public class FruitFactory
{3
public static Fruit factory(String which, boolean hasSeed )
{4
if (hasSeed)
{5
if (which.equalsIgnoreCase( " watermelon " )
{6
return new WatermelonOne();7
}else if (which equalsIgnoreCase( " orange " ))
{8
return new OrangeOne();9
else
{10
throw RuntimeException( " no this fruit " );11
}12
}else
{13
if (which.equalsIgnoreCase( " watermelon " )
{14
return new WatermelonTwo();15
}else if (which equalsIgnoreCase( " orange " ))
{16
return new OrangeTwo();17
else
{18
throw RuntimeException( " no this fruit " );19
}20
}21
}22
}23
----------------------- list 2 -------------------------------- 24
接着試想一下,我有20個大分類,複雜的層次結構,那麼這個工廠模式怎麼維護。
總結一下:簡單工廠方法,在一定程度上支援了開閉原則,當增加一種水果的時候符合開閉原則
但當增加一類水果(多種有共通特點的水果)時候,出現維護困難的問題。
這個時候引入工廠方法,工廠方法利用繼承,解決了上邊的問題。看看它是如何解決的。
簡單來說:工廠方法就是為沒一大類水果實作一個"簡單工廠",這些"簡單工廠"都實作一個共通的接口。
這樣當然就解決了問題,添加一個大類的話,就添加一個簡單工廠
在我們的日常生活中經常會遇到這樣的情況,如要生産IBM-PC或者Apple ,每一台計算計又有Cpu和記憶體
IBM-PC Apple,Cpu 記憶體Ram 不是一類東西,這個時候如果簡單的建立四個工廠類是不對的。解決辦法:
1
----------------------- list 3 -------------------------------- 2
public IbmPcFactory
{3
public Cpu CpuFactory(String cpuType)
{4
return new IbmPcCpu(cpuType);5
}6
public Ram RamFactory(String ramType)
{7
return new IbmPcRam(ramType);8
}9
}10
public AppleFactory()
{11
public Cpu CpuFactory(String cpuType)
{12
return new AppleCpu(cpuType);13
}14
public Ram RamFactory(String ramType)
{15
return new AppleRam(ramType);16
}17
}18
----------------------- list 3 -------------------------------- 19
這個就使抽象工廠了,不過抽象工廠對開閉原則的支援不夠好,隻在機型的增加上支援開閉,在配件上就不行了。
對比三個工廠模式,<>的作者的比喻更能讓人明白問題。
1,話說女娲造人,開始用手捏,感覺太慢
2,是以女娲想出了辦法,用一條繩子(簡單工廠,告訴繩子怎麼造人),放到泥堆裡邊,然後一抖,就出來一批人
(簡單工廠須要一個接口,interface 人)
3,接着女娲想要男人和女人之分,是以造了兩條繩子,陽繩和陰繩(工廠方法,兩個工廠,告訴陽繩怎麼造男人,
女繩怎麼造女人),然後一下出來一批男人,一批女人
(工廠方法須要多個接口,interface 人 interface 繩 陽繩-陰繩實作繩 男人-女人實作人)
4,可女娲還想造點動物,而且動物也想分男女(其實應改是雌雄),那怎麼辦,改造兩條繩子,讓繩子也學會怎麼
造動物(抽象工廠),這個時候抖一下繩子,陽繩出來的東西,長的像人的是男人,長的像動物的是雄動物,
(抽象工廠須要再多的接口 interface 人 interface 獸 interface 繩
陽繩-陰繩實作繩 男人-女人實作人 雌動物-雄動物實作獸)
陰繩出來的東西,長的像人的是女人,長的像動物的是雌動物
最後再回到實作上,看到在list 1中,出現了大量的
if(which.equalsIgnoreCase("xxx"){
return new Xxx();
}
試想如果産品上千,上萬呢。那這個将是不可想想的。Java的動态load正好解決了這個問題
看看實作
1
public class FruitFactory
{2
public static Fruit factory(String which)
{3
try
{4
Class clazz = Class.forName(which);5
return (Fruit)clazz.newInstance();6
}catch (Exception e)
{7
8
}9
}10
}11
好了,這個時候無論增加多少類的産品都不是問題了,你隻要讓所有的産品實作Fruit接口,同時為每個産品
編寫自己的類。完全符合開閉原則。
posted on 2006-11-07 15:02 dreamstone 閱讀(3295) 評論(3) 編輯 收藏 所屬分類: 設計模式