這一篇博文來介紹工廠模式中的第二種工廠方法模式。
介紹
工廠方法模式(Factory Method Pattern)又稱為工廠模式,也叫虛擬構造器(Virtual Constructor)模式或者多態(tài)工廠(Polymorphic Factory)模式,它屬于類創(chuàng)建型模式。在工廠方法模式中,工廠父類負責定義創(chuàng)建產品對象的公共接口,而工廠子類則負責生成具體的產品對象,這樣做的目的是將產品類的實例化操作延遲到工廠子類中完成,即通過工廠子類來確定究竟應該實例化哪一個具體產品類。
優(yōu)點
在工廠方法模式中,工廠方法用來創(chuàng)建客戶所需要的產品,同時還向客戶隱藏了哪種具體產品類將被實例化這一細節(jié),用戶只需要關心所需產品對應的工廠,無須關心創(chuàng)建細節(jié),甚至無須知道具體產品類的類名。
基于工廠角色和產品角色的多態(tài)性設計是工廠方法模式的關鍵。它能夠使工廠可以自主確定創(chuàng)建何種產品對象,而如何創(chuàng)建這個對象的細節(jié)則完全封裝在具體工廠內部。工廠方法模式之所以又被稱為多態(tài)工廠模式,是因為所有的具體工廠類都具有同一抽象父類。
使用工廠方法模式的另一個優(yōu)點是在系統(tǒng)中加入新產品時,無須修改抽象工廠和抽象產品提供的接口,無須修改客戶端,也無須修改其他的具體工廠和具體產品,而只要添加一個具體工廠和具體產品就可以了。這樣,系統(tǒng)的可擴展性也就變得非常好,完全符合“開閉原則”。
缺點
在添加新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統(tǒng)中類的個數將成對增加,在一定程度上增加了系統(tǒng)的復雜度,有更多的類需要編譯和運行,會給系統(tǒng)帶來一些額外的開銷。
由于考慮到系統(tǒng)的可擴展性,需要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增加了系統(tǒng)的抽象性和理解難度,且在實現時可能需要用到DOM、反射等技術,增加了系統(tǒng)的實現難度。
案例
這一篇博文也采用上一篇支付的案例進行說明。
支付抽象類
public abstract class Pay {
public void init(){
System.out.println("支付方式初始化");
}
public abstract void orderPay();
}
支付寶支付類
public class AliPay extends Pay {
@Override
public void orderPay() {
System.out.println("支付寶支付");
}
}
微信支付類
public class WechatPay extends Pay {
@Override
public void orderPay() {
System.out.println("微信支付");
}
}
銀聯(lián)支付類
public class UnionPay extends Pay {
@Override
public void orderPay() {
System.out.println("銀聯(lián)支付");
}
}
抽象工廠類
public abstract class PayFactory {
public abstract Pay createFactory();
}
支付寶工廠類
public class AliPayFactory extends PayFactory {
@Override
public Pay createFactory() {
return new AliPay();
}
}
微信工廠類
public class WechatPayFactory extends PayFactory {
@Override
public Pay createFactory() {
return new WechatPay();
}
}
銀聯(lián)工廠類
public class UnionPayFactory extends PayFactory {
@Override
public Pay createFactory() {
return new UnionPay();
}
}
具體代碼見Github地址
總結
工廠方法模式可以說是簡單工廠模式的進一步優(yōu)化,解決了對修改開放的問題,又保持了簡單工廠模式的優(yōu)點。唯一的缺點就是增加新產品的同時需要增加新的工廠,導致系統(tǒng)類的個數成對增加,在一定程度上增加了系統(tǒng)的復雜性。
類似的案例有日志記錄器(選擇記錄文件、數據庫。。。)、數據庫連接(連接不同的數據庫)