adamans

# 工厂模式是对简单工厂中的工厂类进一步解耦,解决了简单工厂方法中的如果有新的产品而硬编码问题。
# 工厂模式,如有新增新的对象,只要再实现一个对应的工厂类,就完成了扩展,无需修改以前的代码。
# 抽象工厂的核心: 普通工厂产出是一个产品(奥迪,宝马,奔驰的小汽车实例),抽象工厂产出是一个抽象(接口, 接口1: 宝马、奥迪小汽车, 接口2: 宝马、奥迪SUV)。

1.  简单工厂模式

class Car(object):

    @staticmethod
    def make(self):
        pass


class Benz(Car):
    """梅赛德斯
    """

    def __repr__(self):
        return "Mercedes-Benz"

    def make(self):
        print(\'make benz\')


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

    def __repr__(self):
        return "BMW"

    def make(self):
        print(\'make bmw\')


class SimpleCarFactory(object):
    """简单工厂
    """

    @staticmethod
    def product(name):
        if name == \'benz\':
            return Benz()
        elif name == \'bmw\':
            return BMW()


if __name__ == \'__main__\':
    # 通过给工厂传参的方式,就能生产一辆车
    scf = SimpleCarFactory().product(\'bmw\')
    scf.make()

   


问题: 如果我要增加生产一辆奥迪车,我需要增加一个Audi类,并且要修改简单工厂, 这样违反了单一职责和开闭原则

解决: 在简单工厂的基础上把SimpleCarFactory抽象成不同的工厂,每个工厂对应生成自己的产品,这就是工厂方法。

2. 工厂模式

# coding=utf-8
import abc


# 各种车的类
class Car(object):

    @staticmethod
    def make(self):
        pass


class Benz(Car):
    """梅赛德斯
    """

    def __repr__(self):
        return "Mercedes-Benz"

    def make(self):
        print(\'make benz\')


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

    def __repr__(self):
        return "BMW"

    def make(self):
        print(\'make bmw\')


class Audi(Car):
    """奥迪
    """

    def __repr__(self):
        return "Audi"

    def make(self):
        print(\'make audi\')


# 抽象工厂类
class AbstractFactory(object):
    """抽象工厂
    """
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def product_car(self):
        pass


class BenzFactory(AbstractFactory):
    """梅赛德斯工厂
    """

    def product_car(self):
        return Benz()


class BMWFactory(AbstractFactory):
    """宝马工厂
    """

    def product_car(self):
        return BMW()


class AudiFactory(AbstractFactory):
    """奥迪工厂
    """

    def product_car(self):
        return Audi()


if __name__ == \'__main__\':
    # 从简单工厂过度过来, 解决了单一开闭违反的问题, 只需要增加新的工厂类就可以解决新增的代码问题
    a = AudiFactory().product_car()
    a.make()

   

  

问题: 宝马不只生产car, 还要生产SUV怎么办? 我现在都是小汽车, 因此有宝马小汽车类, 奔驰小汽车类,我以后增加宝马SUV, 奔驰SUV怎么办? 我要继续增加各种汽车的响应SUV类, 如果后期又来了各种品牌的轮胎、方向盘等等, 每一个都再建一个类是不是太多了?
解决: 我要在宝马工厂中再增加生产suv的方法, 这样就行了===>这样就是抽象工厂的模式么?是的。

3. 抽象工厂模式

import abc


# 各种车的类
class Car(object):

    @staticmethod
    def make(self):
        pass


class CarSuv(object):

    @staticmethod
    def make(self):
        pass


class Benz(Car):
    """梅赛德斯
    """

    def __repr__(self):
        return "Mercedes-Benz"

    def make(self):
        print(\'make benz\')


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

    def __repr__(self):
        return "BMW"

    def make(self):
        print(\'make bmw\')


class Audi(Car):
    """奥迪
    """

    def __repr__(self):
        return "Audi"

    def make(self):
        print(\'make audi\')


class BenzSuv(CarSuv):
    """梅赛德斯
    """

    def __repr__(self):
        return "Mercedes-Benz"

    def make(self):
        print(\'make benz suv\')


class BMWSuv(CarSuv):
    """宝马
    """

    def __repr__(self):
        return "BMW"

    def make(self):
        print(\'make bmw suv\')


class AudiSuv(CarSuv):
    """奥迪
    """

    def __repr__(self):
        return "Audi"

    def make(self):
        print(\'make audi suv\')


# 抽象工厂类
class AbstractFactory(object):
    """抽象工厂
    """
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def product_car(self):
        pass

    @abc.abstractmethod
    def product_suv(self):
        pass


class BenzFactory(AbstractFactory):
    """梅赛德斯工厂
    """

    def product_car(self):
        return Benz()

    def product_suv(self):
        return BenzSuv()


class BMWFactory(AbstractFactory):
    """宝马工厂
    """

    def product_car(self):
        return BMW()

    def product_suv(self):
        return BMWSuv()


class AudiFactory(AbstractFactory):
    """奥迪工厂
    """

    def product_car(self):
        return Audi()

    def product_suv(self):
        return AudiSuv()


if __name__ == \'__main__\':
   
    car = AudiFactory().product_car()
    suv = AudiFactory().product_suv()
    car.make()
    suv.make()

   

抽象工厂模式与工厂方法模式最大的区别在于,抽象工厂中的一个工厂对象可以负责多个不同产品对象的创建 ,这样比工厂方法模式更为简单、有效率。

从工厂模式过渡过来, 抽象工厂就是对一个工厂不同产品族的封装, 其实抽象工厂模式就是咱们一般使用的抽象、继承的正常的类的使用啊!!!!一般不都是这么写的么!

4. 三者的主要特点

# 初学设计模式时会对三种工厂模式的实际应用比较困惑,其实三种模式各有优缺点,应用的场景也不尽相同:
# 简单工厂模式: 适用于需创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂的情况下,而且用户只关心那种类型的实例被创建,并不关心其初始化过程时,
# 比如多种数据库(MySQL/MongoDB)的实例,多种格式文件的解析器(XML/JSON)等。

# 工厂方法模式: 继承了简单工厂模式的优点又有所改进,其不再通过一个工厂类来负责所有产品的创建,而是将具体创建工作交给相应的子类去做,
# 这使得工厂方法模式可以允许系统能够更高效的扩展。实际应用中可以用来实现系统的日志系统等,
# 比如具体的程序运行日志,网络日志,数据库日志等都可以用具体的工厂类来创建。

# 抽象工厂模式: 在工厂方法基础上扩展了工厂对多个产品创建的支持,更适合一些大型系统,
# 比如系统中有多于一个的产品族,且这些产品族类的产品需实现同样的接口,像很多软件系统界面中不同主题下不同的按钮、文本框、字体等等。

 

分类:

技术点:

相关文章: