# 工厂模式是对简单工厂中的工厂类进一步解耦,解决了简单工厂方法中的如果有新的产品而硬编码问题。
# 工厂模式,如有新增新的对象,只要再实现一个对应的工厂类,就完成了扩展,无需修改以前的代码。
# 抽象工厂的核心: 普通工厂产出是一个产品(奥迪,宝马,奔驰的小汽车实例),抽象工厂产出是一个抽象(接口, 接口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)等。
# 工厂方法模式: 继承了简单工厂模式的优点又有所改进,其不再通过一个工厂类来负责所有产品的创建,而是将具体创建工作交给相应的子类去做,
# 这使得工厂方法模式可以允许系统能够更高效的扩展。实际应用中可以用来实现系统的日志系统等,
# 比如具体的程序运行日志,网络日志,数据库日志等都可以用具体的工厂类来创建。
# 抽象工厂模式: 在工厂方法基础上扩展了工厂对多个产品创建的支持,更适合一些大型系统,
# 比如系统中有多于一个的产品族,且这些产品族类的产品需实现同样的接口,像很多软件系统界面中不同主题下不同的按钮、文本框、字体等等。