基本概念:
1) Simple Factory模式屬於創建型模式,
2) 簡單工廠模式是由一個工廠(注意是一個!)對象決定創建出哪一種產品類的實例(例如你到肯德基說你要雞腿,要薯條,要飲料還是,,,這時肯德基是一
個工廠,客戶端只需要點明自己要什麼就行)
3)實現方式的實質:由一個工廠類根據傳入的參數,動態決定應該創建哪一個產品類(這些產品類繼承自一個父類或接口)的實例。
下面來看一個例子:
音樂盒接口IMusicBox:
package SimpleFactory;
public interface IMusicBox {
public void play();
}
兩種不同的音樂盒播放方式:ViolinBox(小提琴)和 PianoBox(鋼琴):
package SimpleFactory;
public class ViolinBox implements IMusicBox {
public void play() {
System.out.println("撥放小提琴音樂^_^");
}
}
package SimpleFactory;
public class PianoBox implements IMusicBox {
public void play() {
System.out.println("撥放鋼琴音樂:)");
}
}
下面是一個工廠MusicBoxFactory(Simple Factory的核心,在工廠中根據客戶端指定的參數動態創建不同的對象):
package SimpleFactory;
public class MusicBoxFactory {
public static IMusicBox createMusicBox(String name)
throws InstantiationException,
IllegalAccessException,
ClassNotFoundException{
// 這邊使用的是Java的Reflection機制來產生實例
// 不過客戶端不用管啦
// 以後就算改變了這邊的程式,客戶端程式是不用更改的
return (IMusicBox) Class.forName(name).newInstance();
}
}
下面客戶端就可以利用工廠模式:(利用工廠模式,客戶端只需要對工廠指定你要創建的對象的名字(參數),工廠就可以根據你指定的參數動態創建不同的對象)
package SimpleFactory;
public class MusicBoxDemo {
public static void main(String[] args) throws Exception {
// playMusicBox(MusicBoxFactory.createMusicBox("PianoBox"));
// playMusicBox(MusicBoxFactory.createMusicBox("ViolinBox"));
//利用工廠模式,客戶端只需要對工廠指定你要創建的對象的名字(參數),工廠就可以根據你指定的參數動態
//創建不同的對象。當然,這些不同的對象就有不同的表現(在本例中通過play表示)
playMusicBox(MusicBoxFactory.createMusicBox("SimpleFactory.PianoBox"));
playMusicBox(MusicBoxFactory.createMusicBox("SimpleFactory.ViolinBox"));
}
public static void playMusicBox(IMusicBox musicBox) {
musicBox.play();
}
}
結果:
撥放鋼琴音樂:)
撥放小提琴音樂^_^
上面例子的關係用下圖表示:
-------------------------------------------------------------------------------------------------------------------------------------------------
分析:
工廠角色:被客戶端直接調用,根據客戶端指定傳入的參數,動態創建客戶端需要的對象
抽象產品角色:所有對象的父類(接口)
具體產品角色:即工廠的創建目標,工廠創建的對象就是這些具體類的對象。
可以看出,客戶端只面對工廠,不用管產品的具體細節,客戶只需向工廠要求你需要什麼,其他的事情都交給工廠了。
優點:
通過使用工廠類,外界可以從直接創建具體產品對象的尷尬局面擺脫出來,僅僅需要負責“消費”對象就可以了。而不必管這些對象究竟如何創建及如何組織的.明確了各
自的職責和權利。(簡單地說,你到肯德基去只需要說你要雞腿還是雞翅就行了,不需要去管雞腿和雞翅是怎麼做出來的,工廠爲你提供了這樣一個界面)
不足:
由於工廠類集中了所有實例的創建邏輯,違反了高內聚責任分配原則,將全部創建邏輯集中到了一個工廠類中;它所能創建的類只能是事先考慮到的,如果需要添加新
的類,則就需要改變工廠類了。
當系統中的具體產品類不斷增多時候,可能會出現要求工廠類根據不同條件創建不同實例的需求.這種對條件的判斷和對具體產品類型的判斷交錯在一起,很難避免模
塊功能的蔓延,對系統的維護和擴展非常不利;
使用場景
工廠類負責創建的對象比較少;
客戶只知道傳入工廠類的參數,對於如何創建對象(邏輯)不關心;
由於簡單工廠很容易違反高內聚責任分配原則,因此一般只在很簡單的情況下應用。
從上面的例子也可以看出來,工廠類往往是用反射機制來產生具體對象的。(因爲不同類都繼承自同一接口),故其擴展性很有限,產品種類必須是事先就知道的哪幾
種,什麼時候你想要添加一個不是公共接口下的具體類就不行了。
另外,如果你不用反射機制,也不要公共接口,在工廠中使用其他邏輯(例如判斷傳入的字符串)來根據用戶參數創建對象也行,那樣擴展性也是很糟糕的,邏輯和添
加只會越來多。