轉載請註明出處:http://blog.csdn.net/singwhatiwanna/article/details/17428923
說明:博主虛心接受大家的抨擊,批評,指正
前言
我一直想介紹下工廠模式,我曾經搞過J2EE,用的是輕量級SSH框架,其中Spring有IOC概念,可以稱之爲控制反轉或者依賴注入,在系統開發中,IOC可以很好的替代工廠模式。若干年前,我只用過IOC,並沒有用過工廠模式,但是工廠模式這個概念卻是給我留下了深深的印象,畢竟,它是我所聽說過第一個設計模式,我想它應該是很強大的吧。但是,事情不是我想的那個樣子的,在我之前所參與的項目(Android)中幾乎沒有工廠模式的身影,僅僅是有一個項目採用了簡單工廠模式去管理所有的業務管理器。後來,我開始仔細研究工廠模式,發現工廠模式是讓我失望的。工廠模式有三種實現方式:簡單工廠、工廠方法和抽象廣場,除了簡單工廠我還發現了一點使用價值外,後兩者我基本沒發現有啥可使用價值。也許我的理解還不夠透徹,但是目前網上存在的大部分介紹工廠模式的文章都體現了一點:華而不實,難以實際應用。一篇文章不能清晰的介紹一個概念,不能清晰的說明爲什麼要使用這個東西以及如何使用這個東西,那麼這篇文章不算好文章的。我目前所看到的關於工廠模式的介紹都是不充分的,包括我寫的這篇,期待真正的好文章出現。下面將介紹簡單工廠模式以及一個實際項目中使用的例子,後面我將會簡單闡述我的觀點:爲什麼工廠模式是華而不實的。
簡單工廠模式
1.爲什麼要使用工廠模式
直接目的:避免在代碼中出現大量的new關鍵字
根本目的:將對象的創建統一起來便於維護和整體把控
這一點可以理解,加入你在項目中new了某個對象100次,一年後由於業務邏輯變更,構造方法多了一個參數,你會怎麼辦?你應該會這麼做:找到這100個對象new的地方,用新的構造方法來創建對象,你重複勞動了100次,假如採用工廠模式,你只用改一次:把創建工廠給改一下就好了。這就是工廠模式最簡單最直接的好處。
2.工廠模式的示例
下面是最常見的一個示範,其實它的原理就是面向對象中的多態+接口編程,雖然返回的都是Car類型,但是drive的時候會調用真正的實例中的對應方法。按照抽象類和接口的意義歸屬,Car應該被定義成抽象類,因爲Benz、Bmw和Car的關係是繼承關係,而接口表示的一組行爲。但是,爲什麼這裏還要定義成接口,是因爲Java和.NET不支持多繼承,如果繼承了Car,就無法繼承其他類,有時候業務需要必須繼承其他類,這個時候代碼就不能用了。當然,C++中支持多繼承,因此可以在C++中使用抽象類,另外C++沒接口的概念,但你可以模擬接口。這裏只介紹簡單工廠模式,至於剩下兩種工廠模式,我覺得更沒有使用價值。
interface Car {
void drive();
}
class Benz implements Car {
@Override
public void drive() {
System.out.println("drive Benz");
}
}
class Bmw implements Car {
@Override
public void drive() {
System.out.println("drive Bmw");
}
}
class CarFactory {
public static Car creator(String carType) {
if (carType.equals("Benz")) {
return new Benz();
} else if (carType.equals("Bmw")) {
return new Bmw();
} else {
throw new UnsupportedOperationException("car with type" + carType
+ " is not supported.");
}
}
}
public class A {
public static void main(String args[]) {
Car benz = CarFactory.creator("Benz");
benz.drive();
Car bmw = CarFactory.creator("Bmw");
bmw.drive();
}
}
上述代碼是沒啥用的,看一個實際使用的例子。下面這個工廠模式的意義在於能夠統一管理所有的業務管理器,僅此而已。
/**
* 管理器的工程,初始化所有業務的管理器
*/
public class ManagerFactory {
// 緩存管理器實例的集合
private transient Map<Byte, IManager> mManagerMap = null;
private static ManagerFactory sIntance = new ManagerFactory();
private ManagerFactory() {
mManagerMap = new HashMap<Byte, IManager>();
}
public ManagerFactory getInstance() {
return sInstance;
}
/**
* 獲取管理器實例
*
* @param context 上下文
* @param id 管理器ID
* @return 管理器實例
*/
protected IManager getManager(final Context context, final byte id) {
IManager manager = mManagerMap.get(mId);
if (manager == null) {
switch (id) {
case DB_ID:
manager = new DBManager(context);
break;
case DOWNLOAD_ID:
manager = new DownloadManager(context);
break;
case NETWORK_ID:
manager = new NetworkManager();
break;
case IMAGE_ID:
manager = new ImageManager();
break;
default:
break;
}
mManagerMap.put(id, manager);
}
return manager;
}
}
工廠模式爲什麼沒有太大價值
1.有利有弊
優點:將對象的創建統一起來便於維護和整體把控,對擴展開放,對修改封閉
缺點:耦合性提高,由於工廠類集中了所有實例的創建邏輯,違反了高內聚責任分配原則,將全部創建邏輯集中到了一個工廠類中,這種對條件的判斷和對具體產品類型的判斷交錯在一起,很難避免模塊功能的蔓延,對系統的維護和擴展非常不利。
2.使用有限制
從工廠模式的示例可以看出:工廠模式需要類實現它的接口並且在業務內部存在明顯的繼承關係,比如汽車和奔馳寶馬的關係。而繼承關係往往存在於模型之間,業務之間很難存在繼承關係,因此如果業務內部或者業務之間沒有這種顯式的繼承關係該咋辦?就算業務內部有繼承關係,各個業務交給你統一管理,這樣就會提高代碼的耦合性,當創建邏輯複雜的時候,工廠方法就很複雜,容易產生干擾。
3.其開閉性優點很容易被替代
可以通過高度層次化和模塊化來提高系統的開閉性,而不必生硬地去套用工廠模式。
————————————————
版權聲明:本文爲CSDN博主「singwhatiwanna」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/singwhatiwanna/java/article/details/17428923