Design 抽象工厂模式

基本介绍

抽象工厂模式指在其他普通工厂模式的2个分支基础上,能够控制产品的类型。

例如,在普通工厂模式中,造一辆车时如果不对其零部件来源加以控制,可能发现装上了一个不属于该车范畴的配件。

特定:对外隐藏,可搭配普通工厂模式或者工厂方法模式来指定接口,但在此基础上管控了生成产品的零部件来源

案例图示

在抽象工厂模式下,必须严格控制配件的来源:

image-20210411192726601

优缺点

优点:

  • 将客户端与类的具体实现相分离
  • 每个工厂创建了一个完整的产品系列,使得易于交换产品系列
  • 有利于产品的一致性

缺点:

  • 难以支持新种类的抽象产品,扩展困难

Python实现

用Python实现抽象工厂模式:

#! /usr/local/bin/python3
# -*- coding:utf-8 -*-

from abc import ABCMeta, abstractmethod


# --------- 零部件相关 -------------

# 定义一个轮胎的抽象基类
class Tires(metaclass=ABCMeta):
    @abstractmethod
    def show_info(self):
        pass


# 定义一个底盘的抽象基类
class Chassis(metaclass=ABCMeta):
    @abstractmethod
    def show_info(self):
        pass


# 定义一个其他零部件的抽象基类
class Other(metaclass=ABCMeta):
    @abstractmethod
    def show_info(self):
        pass


# 生产奔驰轮胎的厂商
class BenzTires(Tires):
    def show_info(self):
        return "奔驰轮胎"


# 生产奔驰底盘的厂商
class BenzChassis(Chassis):
    def show_info(self):
        return "奔驰底盘"


# 生产奔驰其他零部件的厂商
class BenzOther(Other):
    def show_info(self):
        return "奔驰其他"


# 生产宝马轮胎的厂商
class BMWTires(Tires):
    def show_info(self):
        return "宝马轮胎"


# 生产宝马底盘的厂商
class BMWChassis(Chassis):
    def show_info(self):
        return "宝马底盘"


# 生产宝马其他零部件的厂商
class BMWOther(Other):
    def show_info(self):
        return "宝马其他"


# --------- 车的厂商相关 -----------

# 定义一个车工厂的抽象基类
class Car(metaclass=ABCMeta):

    @abstractmethod
    def build_car(self):
        """造车"""
        pass

    @abstractmethod
    def get_car(self):
        """提车"""
        pass

    @abstractmethod
    def show_car_info(self):
        """查看车辆状况"""
        pass

    @abstractmethod
    def make_tires(self, tires_type):
    	"""造轮胎"""
        pass

    @abstractmethod
    def make_chassis(self, tires_type):
    	"""造底盘"""
        pass

    @abstractmethod
    def make_other(self, other_type):
    	"""造其他"""
        pass


class Benz(Car):
    """奔驰"""

    def __init__(self, name, color):
        self.name = name
        self.color = color
        self.__result = None
        self.tires_type = None
        self.chassis_type = None
        self.other_type = None

    def build_car(self, tires_type, chassis_type, other_type):
        self.make_tires(tires_type)
        self.make_chassis(chassis_type)
        self.make_other(other_type)

        self.__result = "一辆奔驰的车造好了,%s的车身上有一个炫酷的喷漆:%s" % (self.color, self.name)

    def get_car(self):
        print(self.__result)
        return self

    @property
    def show_car_info(self):
        return """
             外观信息:%s\n
             喷漆信息:%s\n
             轮胎信息:%s\n
             底盘信息:%s\n
             其他信息:%s\n
         """ % (self.color, self.name, self.tires_type, self.chassis_type, self.other_type)

    def make_tires(self, tires_type):
        tires = tires_type()
        self.tires_type = tires.show_info()

    def make_chassis(self, tires_type):
        chassis = tires_type()
        self.chassis_type = chassis.show_info()

    def make_other(self, other_type):
        other = other_type()
        self.other_type = other.show_info()


class BMW(Car):
    """宝马"""

    def __init__(self, name, color):
        self.name = name
        self.color = color
        self.__result = None

    def build_car(self, tires_type, chassis_type, other_type):
        self.make_tires(tires_type)
        self.make_chassis(chassis_type)
        self.make_other(other_type)
        self.__result = "一辆宝马的车造好了,%s的车身上有一个炫酷的喷漆:%s" % (self.color, self.name)

    def get_car(self):
        print(self.__result)
        return self

    @property
    def show_car_info(self):
        return """
            外观信息:%s\n
            喷漆信息:%s\n
            轮胎信息:%s\n
            底盘信息:%s\n
            其他信息:%s\n
        """ % (self.color, self.name, self.tires_type, self.chassis_type, self.other_type)

    def make_tires(self, tires_type):
        tires = tires_type()
        self.tires_type = tires.show_info()

    def make_chassis(self, tires_type):
        chassis = tires_type()
        self.chassis_type = chassis.show_info()

    def make_other(self, other_type):
        other = other_type()
        self.other_type = other.show_info()


# --------- 专卖店相关 -----------

# 定义一个专卖店的抽象基类
class Shop(metaclass=ABCMeta):
    """每个专卖店都应该具有提车的功能"""

    @abstractmethod
    def get_car(self, name, color):
        pass


class BenzShop(Shop):
    """奔驰专卖店"""

    def get_car(self, name, color):
        self.brand = Benz(name, color)

        # 通知造车,并指定零件厂商
        self.brand.build_car(tires_type=BenzTires, chassis_type=BenzChassis, other_type=BenzOther)
        # 通知取车
        return self.brand.get_car()


class BMWShop(Shop):
    """宝马专卖店"""

    def get_car(self, name, color):
        self.brand = BMW(name, color)
        # 通知造车,并指定零件厂商
        self.brand.build_car(tires_type=BMWTires, chassis_type=BMWChassis, other_type=BMWOther)
        # 通知取车
        return self.brand.get_car()


if __name__ == '__main__':
    # 奔驰专卖店
    benz_shop = BenzShop()

    # 宝马专卖店
    bmw_shop = BMWShop()

    car01 = benz_shop.get_car("牛逼", "黑色")
    print(car01.show_car_info)

    car02 = bmw_shop.get_car("霸气", "红色")
    print(car02.show_car_info)

执行结果:

一辆奔驰的车造好了,黑色的车身上有一个炫酷的喷漆:牛逼

             外观信息:黑色

             喷漆信息:牛逼

             轮胎信息:奔驰轮胎

             底盘信息:奔驰底盘

             其他信息:奔驰其他

         
一辆宝马的车造好了,红色的车身上有一个炫酷的喷漆:霸气

            外观信息:红色

            喷漆信息:霸气

            轮胎信息:宝马轮胎

            底盘信息:宝马底盘

            其他信息:宝马其他

Golang实现

用Golang实现抽象工厂模式:

...
posted @ 2021-04-11 20:06  云崖君  阅读(50)  评论(0编辑  收藏  举报