在上文(設計模式學習-簡單工廠模式)的模擬場景中,我們用簡單工廠模式實現了VISA和MASTERARD卡的刷卡處理,系統成功上線並運行良好,突然有一天老大跑來說,我們的系統需要升級,提供對一般銀聯卡的支持。怎麼辦?有需求總是要改的,苦B的程序員傷不起啊....
怎麼改?增加一個銀聯卡處理類?然後在工廠類的靜態方法裏增加Case處理?前幾天剛讀了面向對象的核心設計原則-“開放封閉原則”,這樣改下去不是完全違背了這個設計原則?
於是,我決定重構之前的簡單工廠模式實現的方法,首先我們找出變化點,增加銀聯卡處理類是不可避免,這屬於擴展,對工廠類增加CASE條件的處理,這裏屬於修改原業務,屬於修改,OCP告訴我們,對修改應該是關閉的。
OK,順利找到變化點,由於我們不知道將來需要實例化出什麼對象,所以將產品工廠抽象出來,讓對象的實例化在子類實現:
{
public abstract BankCardHandle CreateBankCardHandle();
接着,我們實現生成VISA及MASTERARD刷卡對象的實際工廠:
{
public override BankCardHandle CreateBankCardHandle()
{
return new VisaHandle();
}
}
class MasterCardHandleFactory : HandleFactory
{
public override BankCardHandle CreateBankCardHandle()
{
return new MasterCardHandle();
}
不知不覺,我們用工廠方法模式重構了我們的系統,下面我們看看工廠方法模式的介紹。
模式概述:
其中的類或對象之間的關係爲:
- 產品角色(Product)
定義產品的相關接口。
- 真實的的產品角色(ConcreteProduct)
實現接口Product。
- 工廠角色(Factory)
聲明工廠方法(FactoryMethod),返回一個產品(Product)。
- 真實的工廠(ConcreteFactory)
實現FactoryMethod工廠方法,由客戶調用,返回一個Product實例。
經過上面我們用工廠方法模式重構刷卡系統後,老大提出的增加一個銀聯卡的處理就比較好辦了,先增加一個銀聯卡處理類,同時增加一個生產銀聯卡處理類的工廠類:
{
public override void HandleProcess()
{
Console.WriteLine("銀聯卡處理中");
}
}
class UnionPayCardHandleFactory : HandleFactory
{
public override BankCardHandle CreateBankCardHandle()
{
return new UnionPayCardHandle();
}
客戶端調用代碼如下:
BankCardHandle bk = hd.CreateBankCardHandle();
我們以後增加卡處理方式,只需要增加相應的卡處理類和生成卡處理類的工廠,然後修改一下客戶端代碼就好了,如果連客戶端代碼都不想修改,在客戶端獲取配置文件,用反射處理就OK了。