6.設計模式之四:抽象工廠模式【建立型模式】

前面介紹的工廠方法模式中考慮的是一類產品的生產,如畜牧場只養動物、電視機廠只生產電視機、計算機軟件學院只培養計算機軟件專業的學生等。java

同種類稱爲同等級,也就是說:工廠方法模式只考慮生產同等級的產品,可是在現實生活中許多工廠是綜合型的工廠,能生產多等級(種類) 的產品,如農場裏既養動物又種植物,電器廠既生產電視機又生產洗衣機或空調,大學既有軟件專業又有生物專業等。
抽象工廠模式將考慮多等級產品的生產,將同一個具體工廠所生產的位於不一樣等級的一組產品稱爲一個產品族,圖所示的是海爾工廠和 TCL 工廠所生產的電視機與空調對應的關係圖。python

定義與特色

抽象工廠(AbstractFactory)模式的定義:是一種爲訪問類提供一個建立一組相關或相互依賴對象的接口,且訪問類無須指定所要產品的具體類就能獲得同族的不一樣等級的產品的模式結構。spa

抽象工廠模式是工廠方法模式的升級版本,工廠方法模式只生產一個等級的產品,而抽象工廠模式可生產多個等級的產品。
使用抽象工廠模式通常要知足如下條件。操作系統

  • 系統中有多個產品族,每一個具體工廠建立同一族但屬於不一樣等級結構的產品。
  • 系統一次只可能消費其中某一族產品,即同族的產品一塊兒使用。

抽象工廠模式除了具備工廠方法模式的優勢外,其餘主要優勢以下。設計

  • 能夠在類的內部對產品族中相關聯的多等級產品共同管理,而沒必要專門引入多個新的類來進行管理。
  • 當增長一個新的產品族時不須要修改原代碼,知足開閉原則。

其缺點是:當產品族中須要增長一個新的產品時,全部的工廠類都須要進行修改。code

結構與實現

抽象工廠模式同工廠方法模式同樣,也是由抽象工廠、具體工廠、抽象產品和具體產品等 4 個要素構成,但抽象工廠中方法個數不一樣,抽象產品的個數也不一樣。如今咱們來分析其基本結構和實現方法。對象

1. 模式的結構

抽象工廠模式的主要角色以下。blog

  1. 抽象工廠(Abstract Factory):提供了建立產品的接口,它包含多個建立產品的方法 newProduct(),能夠建立多個不一樣等級的產品。
  2. 具體工廠(Concrete Factory):主要是實現抽象工廠中的多個抽象方法,完成具體產品的建立。
  3. 抽象產品(Product):定義了產品的規範,描述了產品的主要特性和功能,抽象工廠模式有多個抽象產品。
  4. 具體產品(ConcreteProduct):實現了抽象產品角色所定義的接口,由具體工廠來建立,它 同具體工廠之間是多對一的關係。

 

2. 模式的實現

從上圖能夠看出抽象工廠模式的結構同工廠方法模式的結構類似,不一樣的是其產品的種類不止一個,因此建立產品的方法也不止一個。下面給出抽象工廠和具體工廠的代碼。接口

class AbstractFactory(object):
    def new_product1(self):
        pass

    def new_product2(self):
        pass

class ConcreteFactory(AbstractFactory):
    def new_product1(self):
        print("具體工廠 1 生成-->具體產品 11...")
        return  ConcreteProduct11()

    def new_product2(self):
        print("具體工廠 1 生成-->具體產品 21...")
        return  ConcreteProduct21()

class ConcreteProduct11():
    pass

class ConcreteProduct21():
    pass

模式的應用實例

【例1】用抽象工廠模式設計農場類。

分析:農場中除了像畜牧場同樣能夠養動物,還能夠培養植物,如養馬、養牛、種菜、種水果等,因此本實例比前面介紹的畜牧場類複雜,必須用抽象工廠模式來實現。

本例用抽象工廠模式來設計兩個農場,一個是韶關農場用於養牛和種菜,一個是上饒農場用於養馬和種水果,能夠在以上兩個農場中定義一個生成動物的方法 newAnimal() 和一個培養植物的方法 newPlant()。產品

class Farm(object):
    def new_animal(self):
        pass
    def new_plant(self):
        pass

class SRFarm(Farm):
    def new_animal(self):
        print("建立SrFarm的animal")
        return Horse()

    def new_plant(self):
        print("建立SrFarm的animal")
        return Potato()

class SGFarm(Farm):
    def new_animal(self):
        print("建立SgFarm的animal")
        return Cattle()

    def new_plant(self):
        print("建立S給Farm的animal")
        return Tomato()

class Animal(object):
    def show(self):
        pass

class Horse(Animal):
    def show(self):
        print("i am an animal from SR -- horse")

class Cattle(Animal):
    def show(self):
        print("i am an animal from SG -- cattle")

class Plant(object):
    def show(self):
        pass

class Potato(Plant):
    def show(self):
        print('i am a plant from SR -- potato')

class Tomato(Plant):
    def show(self):
        print('i am a plant from SG -- tomato')


if __name__ == '__main__':
    sg_f = SGFarm()
    sg_a = sg_f.new_animal()
    sg_a.show()
    
    sr_f = SRFarm()
    sr_p = sr_f.new_plant()
    sr_p.show()
建立SgFarm的animal
i am an animal from SG -- cattle
建立SrFarm的animal
i am a plant from SR -- potato

模式的應用場景

抽象工廠模式最先的應用是用於建立屬於不一樣操做系統的視窗構件。如 java 的 AWT 中的 Button 和 Text 等構件在 Windows 和 UNIX 中的本地實現是不一樣的。

抽象工廠模式一般適用於如下場景:

  1. 當須要建立的對象是一系列相互關聯或相互依賴的產品族時,如電器工廠中的電視機、洗衣機、空調等。
  2. 系統中有多個產品族,但每次只使用其中的某一族產品。若有人只喜歡穿某一個品牌的衣服和鞋。
  3. 系統中提供了產品的類庫,且全部產品的接口相同,客戶端不依賴產品實例的建立細節和內部結構。

模式的擴展

抽象工廠模式的擴展有必定的「開閉原則」傾斜性:

  1. 當增長一個新的產品族時只需增長一個新的具體工廠,不須要修改原代碼,知足開閉原則。
  2. 當產品族中須要增長一個新種類的產品時,則全部的工廠類都須要進行修改,不知足開閉原則。

另外一方面,當系統中只存在一個等級結構的產品時,抽象工廠模式將退化到工廠方法模式。

相關文章
相關標籤/搜索