天天看點

工廠模式(簡單工廠、工廠方法、抽象工廠)

簡單工廠模式

      從設計模式的類型上來說,簡單工廠模式是屬于建立型模式,又叫做靜态工廠方法(StaticFactory Method)模式,但不屬于23種GOF設計模式之一。簡單工廠模式是由一個工廠對象決定建立出哪一種産品類的執行個體。簡單工廠模式是工廠模式家族中最簡單實用的模式,可以了解為是不同工廠模式的一個特殊實作。 

簡單工廠模式的一般結構,如圖所示:

工廠模式(簡單工廠、工廠方法、抽象工廠)
工廠模式(簡單工廠、工廠方法、抽象工廠)

上門2個圖檔有對簡單工廠模式的了解,來源《java與模式》

工廠類負責建立的對象比較少。

用戶端隻知道傳入工廠類的參數,對于如何建立對象并不關心。

l 工廠角色

l 抽象産品角色

l 具體産品角色

   其實角色這個詞用的比較确切,能夠讓我們了解到,每個角色的不是單純地指一個類,可能是一組類所構成了這個角色。下面對三個角色進行描述:

1. 工廠角色

  工廠角色負責産品的生産工作。在簡單工廠模式中,工廠類是一個具體的實作類,在系統設計中工廠類負責實際對象的建立工作。

  工廠類(Factory)的特點是:它知道系統中都存在哪些能夠建立對象的具體類(ConcreteProduct),也知道該如何将建立的對象,以某種能夠屏蔽具體類實作細節的方式(AbstractProduct)提供給所需要的其他角色來使用該對象提供的資料和服務。

2.抽象産品角色

  抽象産品角色是具體的産品的抽象。抽象就是将産品的共性抽取出來,可以直接暴露給用戶端(需要使用具體産品的角色),對所有的用戶端來說,從工廠中直接擷取到的原始産品的外部形态都是相同的,沒有任何的差别,包括資料和服務。這也就是說,具體用戶端應該“秘密”掌握着某一個或一些具體産品的詳細資料(具體産品類型、資料和服務),然後根據具體用戶端(任何一個需要使用某種具體産品的資料和服務的實作類)需要什麼樣的附加資料和服務,進行類類型轉換後,通過借助于對應的具體産品對象來完成其職責。

  抽象産品角色,在實際系統中可以定義為接口或者抽象類。

3.具體産品角色

  具體産品實作類一定是抽象産品類的實作或擴充。為了保證工廠類能夠建立對象,工廠類需要知道具體産品的建立方式,這就涉及到具體産品類所提供的構造方法,以便,可能工廠類會向用戶端提供具體建立服務所需要的資料。例如:某個産品類需要通過一個賬号才能構造其執行個體,是以工廠類必須根據它的建立需求,為用戶端提供一個帶賬号參數的生産方法,才能建立該具體産品類的對象。

  也就是說,工廠類依賴于具體産品實作類。同樣,用戶端類是依賴于工廠類的。

通過上述三個角色的描述,我們應該能夠了解,系統中哪些類能夠勝任上述的三個角色,并通過各類之間的關系,通過工廠模式來實作系統或者某個子產品。在實際的設計過程中,可能不存在完全與上述基本簡單工廠模式完全适應的,需要根據具體的需求來調整簡單工廠模式的應用。隻要能夠實作系統的良好設計,有時候變化才能滿足需要。

下面用一個簡單的例子來說明一下,給大家加深一下印象(例子來自于網絡):

以上就是簡單工廠模式的一個簡單執行個體,讀者應該想象不用接口不用工廠而把具體類暴露給用戶端的那種混亂情形吧(就好像沒了體育總局,各個俱樂部在市場上自己胡亂的尋找仔細需要的運動員),簡單工廠就解決了這種混亂。

工廠方法模式

工廠方法模式是類的建立模式,又叫虛拟構造子(Virtual Constructor)模式或者多态性工廠(Polymorphic Factory)模式。 工廠方法模式的用意是定義一個建立産品對象的工廠接口,将實際工作推遲到子類中。

工廠方法模式是簡單工廠模式的衍生,解決了許多簡單工廠模式的問題。首先完全實作‘開-閉 原則’,實作了可擴充。其次更複雜的層次結構,可以應用于産品結果複雜的場合。工廠方法模式的對簡單工廠模式進行了抽象。有一個抽象的Factory類(可以是抽象類和接口),這個類将不在負責具體的産品生産,而是隻制定一些規範,具體的生産工作由其子類去完成。在這個模式中,工廠類和産品類往往可以依次對應。即一個抽象工廠對應一個抽象産品,一個具體工廠對應一個具體産品,這個具體的工廠就負責生産對應的産品。 

工廠方法模式角色與結構

1.抽象工廠(Creator)角色:是工廠方法模式的核心,與應用程式無關。任何在模式中建立的對象的工廠類必須實作這個接口。  

2.具體工廠(Concrete Creator)角色:這是實作抽象工廠接口的具體工廠類,包含與應用程式密切相關的邏輯,并且受到應用程式調用以建立産品對象。

3.抽象産品(Product)角色:工廠方法模式所建立的對象的超類型,也就是産品對象的共同父類或共同擁有的接口。

4.具體産品(Concrete Product)角色:這個角色實作了抽象産品角色所定義的接口。某具體産品有專門的具體工廠建立,它們之間往往一一對應。

工廠方法模式的一般結構,如圖所示:

工廠模式(簡單工廠、工廠方法、抽象工廠)

我們在不改變産品類(“足球運動員”類和“籃球運動員”類)的情況下,寫一下工廠方法模式的例子:

很明顯可以看到,“體育協會”工廠類變成了“體育協會”接口,而實作此接口的分别是“足球協會”“籃球協會”等等具體的工廠類。

這樣做有什麼好處呢?很明顯,這樣做就完全OCP了。如果需要再加入(或擴充)産品類(比如加多個“乒乓球運動員”)的話就不再需要修改工廠類了,而隻需相應的再添加一個實作了工廠接口(“體育協會”接口)的具體工廠類。

抽象工廠模式

       抽象工廠模式是所有形态的工廠模式中最為抽象和最具一般性的一種形态。抽象工廠模式是指當有多個抽象角色時,使用的一種工廠模式。抽象工廠模式可以向用戶端提供一個接口,使用戶端在不必指定産品的具體的情況下,建立多個産品族中的産品對象。根據LSP原則,任何接受父類型的地方,都應當能夠接受子類型。是以,實際上系統所需要的,僅僅是類型與這些抽象産品角色相同的一些執行個體,而不是這些抽象産品的執行個體。換言之,也就是這些抽象産品的具體子類的執行個體。工廠類負責建立抽象産品的具體子類的執行個體。

     先來認識下什麼是産品族: 位于不同産品等級結構中,功能相關聯的産品組成的家族。還是讓我們用一個例子來形象地說明一下吧。

抽象工廠模式中的有以下的四種角色:

抽象工廠(Abstract Factory)角色:擔任這個角色的是工廠方法模式的核心,它是與應用系統商業邏輯無關的。 

具體工廠(Concrete Factory)角色:這個角色直接在用戶端的調用下建立産品的執行個體。這個角色含有選擇合适的産品對象的邏輯,而這個邏輯是與應用系統的商業邏輯緊密相關的。

 抽象産品(Abstract Product)角色:擔任這個角色的類是工廠方法模式所建立的對象的父類,或它們共同擁有的接口。

具體産品(Concrete Product)角色:這個角色用以代表具體的産品。

 Abstract Factory模式的結構:

工廠模式(簡單工廠、工廠方法、抽象工廠)
工廠模式(簡單工廠、工廠方法、抽象工廠)
工廠模式(簡單工廠、工廠方法、抽象工廠)
工廠模式(簡單工廠、工廠方法、抽象工廠)

在以下情況下應當考慮使用抽象工廠模式:

· 一個系統不應當依賴于産品類執行個體如何被建立、組合和表達的細節,這對于所有形态的工廠模式都是重要的。

· 這個系統有多于一個的産品族,而系統隻消費其中某一産品族。

· 同屬于同一個産品族的産品是在一起使用的,這一限制必須在系統的設計中展現出來。

· 系統提供一個産品類的庫,所有的産品以同樣的接口出現,進而使用戶端不依賴于實作。

繼續閱讀