工廠模式的簡單例子
當A物件需要呼叫B物件的方法是,許多初學者會選擇使用new關鍵字來建立一個B例項,然後呼叫B例項的方法。從語法角度來看,這種做法沒有任何問題,這種做法的壞處在於:A類的方法實現直接呼叫了B類的類名(這種方式也被稱為硬編碼耦合),一旦系統需要重構;需要使用C類來代替B類時,程式不得不寫A類程式碼。如果應用中有100個或10000個類以硬編碼耦合了B類,則需要重新改寫100個,10000個地方….
換一個角度來看這個問題:對於A物件而言,它只需要呼叫B物件的方法,並不關心B物件的實現、建立過程。考慮讓B類實現一個IB介面,而A類只需要IB介面耦合——A類並不直接使用new關鍵字來建立B例項,而是重新定義一個工廠類:IBFactory,由該工廠類來負責建立IB例項;而A類通過IBFactory工廠的方法得到IB的例項。
通過該用上面設計,則A類需要與IBFactory耦合,和需要與IB介面耦合,如果系統需要重構:需要使用C類代替B類,則只需要讓C類實現IB介面,並改寫IBFactory工廠中建立IB例項的實現程式碼,並讓該工廠產生C(實現IB介面)例項即可、由於所以來IB例項的物件都是通過工廠來獲取IB例項的,所以他們都將改為獲得C類例項,這就完成了系統重構。
out介面(相當抽象產品):
package com.fsti.factory.simplefactory;
public interface Output {
public final static Integer MAX_CACHE_LINE = 3;
void getData(String str);
void out();
}
Printer實現out介面(相當具體產品):
public class Printer implements Output {
private String[] printData = new String[MAX_CACHE_LINE];
// 用以記錄當前需列印的作業數
private int dataNum = 0;
public void getData(String str) {
if (dataNum >= MAX_CACHE_LINE) {
System.out.println("輸出佇列一滿,新增失敗");
} else {
printData[dataNum++] = str;
}
}
public void out() {
while (dataNum > 0) {
System.out.println("印表機列印:" + printData[0]);
// 把作業整體前移一位,並將剩下的作業數減一
System.arraycopy(printData, 1, printData, 0, --dataNum);
}
}
}
工廠類(相當簡單工廠),返回實現了Output介面的Printer的例項:
public class OutputFactory {
public Output getOutput() {
return new Printer();
}
}
// Computer類對介面Output形成依賴,將Computer與Printer實現類分離開來
public class Computer {
private Output out;
public Computer(Output out) {
this.out = out;
}
public void keyIn(String str) {
out.getData(str);
}
public void print() {
out.out();
}
public static void main(String[] args) {
OutputFactory of = new OutputFactory();
Computer c = new Computer(of.getOutput());
c.keyIn("工廠模式之");
c.keyIn("簡單工廠模式");
c.print();
}
}
如果系統需要重構,則只需要讓替換類實現Output介面,並改下OutputFactory類的getOutput方法即可。
優點
工廠類是整個模式的關鍵。包含了必要的邏輯判斷,根據外界給定的資訊,決定究竟應該建立哪個具體類的物件。通過使用工廠類,外界可以從直接建立具體產品物件的尷尬局面擺脫出來,僅僅需要負責“消費”物件就可以了。而不必管這些物件究竟如何建立及如何組織的。明確了各自的職責和權利,有利於整個軟體體系結構的優化。
缺點
由於工廠類集中了所有例項的建立邏輯,違反了高內聚責任分配原則,將全部建立邏輯集中到了一個工廠類中;它所能建立的類只能是事先考慮到的,如果需要新增新的類,則就需要改變工廠類了。
當系統中的具體產品類不斷增多時候,可能會出現要求工廠類根據不同條件建立不同例項的需求.這種對條件的判斷和對具體產品型別的判斷交錯在一起,很難避免模組功能的蔓延,對系統的維護和擴充套件非常不利;
這些缺點在工廠方法模式中得到了一定的克服。
使用場景
工廠類負責建立的物件比較少;
客戶只知道傳入工廠類的引數,對於如何建立物件(邏輯)不關心;
由於簡單工廠很容易違反高內聚責任分配原則,因此一般只在很簡單的情況下應用。