設計模式學習-工廠方法模式

  在上文(設計模式學習-簡單工廠模式)的模擬場景中,我們用簡單工廠模式實現了VISA和MASTERARD卡的刷卡處理,系統成功上線並運行良好,突然有一天老大跑來說,我們的系統需要升級,提供對一般銀聯卡的支持。怎麼辦?有需求總是要改的,苦B的程序員傷不起啊....

  怎麼改?增加一個銀聯卡處理類?然後在工廠類的靜態方法裏增加Case處理?前幾天剛讀了面向對象的核心設計原則-“開放封閉原則”,這樣改下去不是完全違背了這個設計原則?
 

  開放封閉原則(OCP,Open Closed Principle)是所有面向對象原則的核心。軟件設計本身所追求的目標就是封裝變化、降低耦合,而開放封閉原則正是對這一目標的最直接體現。其他的設計原則,很多時候是爲實現這一目標服務的,例如以Liskov替換原則實現最佳的、正確的繼承層次,就能保證不會違反開放封閉原則。開放封閉原則,其核心的思想是:軟件實體應該是可擴展,而不可修改的。也就是說,對擴展是開放的,而對修改是封閉的


於是,我決定重構之前的簡單工廠模式實現的方法,首先我們找出變化點,增加銀聯卡處理類是不可避免,這屬於擴展,對工廠類增加CASE條件的處理,這裏屬於修改原業務,屬於修改,OCP告訴我們,對修改應該是關閉的。

  OK,順利找到變化點,由於我們不知道將來需要實例化出什麼對象,所以將產品工廠抽象出來,讓對象的實例化在子類實現:

View Code 
    abstract class HandleFactory
    {
        public abstract BankCardHandle CreateBankCardHandle();

  接着,我們實現生成VISA及MASTERARD刷卡對象的實際工廠:

View Code 
    class VisaHandleFactory : HandleFactory 
    {
        public override BankCardHandle CreateBankCardHandle()
        {
            return new VisaHandle();
        }
    }

    class MasterCardHandleFactory : HandleFactory
    {
        public override BankCardHandle CreateBankCardHandle()
        {
            return new MasterCardHandle();
        }
  BankCardHandle、VisaHandle、MasterCardHandle類見上一篇(設計模式學習-簡單工廠模式)。

  不知不覺,我們用工廠方法模式重構了我們的系統,下面我們看看工廠方法模式的介紹。

模式概述:

  工廠方法模式又稱工廠模式,屬於類的創建型模式。在工廠方法模式中,父類負責定義創建對象的公共接口,而子類則負責生成具體的對象,這樣做的目的是將類的實例化操作延遲到子類中完成,即由子類決定究竟應該實例化哪一個類。
UML類圖:


其中的類或對象之間的關係爲:

  • 產品角色(Product)
    定義產品的相關接口。

  • 真實的的產品角色(ConcreteProduct)
    實現接口Product。

  • 工廠角色(Factory)
    聲明工廠方法(FactoryMethod),返回一個產品(Product)。

  • 真實的工廠(ConcreteFactory)
    實現FactoryMethod工廠方法,由客戶調用,返回一個Product實例。

  經過上面我們用工廠方法模式重構刷卡系統後,老大提出的增加一個銀聯卡的處理就比較好辦了,先增加一個銀聯卡處理類,同時增加一個生產銀聯卡處理類的工廠類:

View Code 
    class UnionPayCardHandle : BankCardHandle
    {
        public override void HandleProcess()
        {
            Console.WriteLine("銀聯卡處理中");
        }
    }

    class UnionPayCardHandleFactory : HandleFactory
    {
        public override BankCardHandle CreateBankCardHandle()
        {
            return new UnionPayCardHandle();
        }

客戶端調用代碼如下:
View Code 
            HandleFactory hd = new UnionPayCardHandleFactory();
            BankCardHandle bk = hd.CreateBankCardHandle();

我們以後增加卡處理方式,只需要增加相應的卡處理類和生成卡處理類的工廠,然後修改一下客戶端代碼就好了,如果連客戶端代碼都不想修改,在客戶端獲取配置文件,用反射處理就OK了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章