简单工厂模式
在工厂模式中,我们创建对象时不会对客户端暴露创建逻辑,并且提供一个「工厂类」去创建对象,只需要告诉工厂我需要什么,比如需要一辆汽车,去工厂提货,不用去关心汽车是怎么做出来的。
适用场景:创建复杂对象 & 希望隐藏「创建类的代码逻辑」 优点:无需关心对象内部实现逻辑,需要则通过工厂创建即可 缺点:违背开闭原则,有新的产品加入时,就需要修改工厂类,具体产品和工厂耦合高,扩展性低。
参考文档:https://blog.csdn.net/qq_27825451/article/details/84235974
以生产三种水果为例,定义三类水果,分别是:苹果、香蕉、橘子
首先定义一个工厂类FactorySimple,创建一个静态方法,根据输入的类型,返回不同的对象
# 定义三类水果
class Apple(object):
"""苹果"""
def __repr__(self):
# 具体实现逻辑
return "苹果"
class Banana(object):
"""香蕉"""
def __repr__(self):
# 具体实现逻辑
return "香蕉"
class Orange(object):
"""橘子"""
def __repr__(self):
# 具体实现逻辑
return "橘子"
class FactorySimple:
"""简单工厂模式"""
@staticmethod
def get_fruit(fruit_name):
if 'a' == fruit_name:
return Apple()
if 'b' == fruit_name:
return Banana()
if 'c' == fruit_name:
return Orange()
else:
print("没有这种水果")
if __name__ == '__main__':
# 简单工厂
instance_a = FactorySimple.get_fruit('a')
instance_b = FactorySimple.get_fruit('b')
instance_c = FactorySimple.get_fruit('c')
print(instance_a)
print(instance_b)
print(instance_c)
工厂方法模式
相比简单工厂模式,工厂方法则是提供了一系列的工厂创建类,每个「产品」都有一个工厂,这些工厂又遵循一个工厂「接口」(总工厂),只不过是重写了「接口」中的方法。
优点:解决了简单工厂模式 违背闭开原则的 缺点 实现套路:
- 定义每个产品类
- 定义一个创建产品类的「抽象接口」,实现「生产方法」
- 分别定义每个产品的工厂类,并重写「抽象接口」的「生产方法」
参考文章:https://blog.csdn.net/qq_27825451/article/details/84246759
首先定义三类水果Apple、Banana、Orange,创建一个抽象公共工厂类AbstractFactory,并定义一个生产方法get_fruit,接着,创建抽象工厂类的3个子类AppleFactory、BananaFactory、OrangoFactory,并重写方法,创建一个实例对象并返回。
# 工厂方法
import abc
# 定义三类水果
class Apple(object):
"""苹果"""
def __repr__(self):
return "苹果"
class Banana(object):
"""香蕉"""
def __repr__(self):
return "香蕉"
class Orange(object):
"""橘子"""
def __repr__(self):
return "橘子"
class AbstractFactory(object):
"""公共抽象工厂"""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def get_fruit(self):
# 公共抽象方法
pass
# 工厂子类创建对象,不修改原有代码,需要生产不同产品则创建不同工厂子类
class AppleFactory(AbstractFactory):
"""生产苹果"""
def get_fruit(self):
return Apple()
class BananaFactory(AbstractFactory):
"""生产香蕉"""
def get_fruit(self):
return Banana()
class OrangoFactory(AbstractFactory):
"""生产橘子"""
def get_fruit(self):
return Orange()
if __name__ == '__main__':
# 工厂方法
instance_apple = AppleFactory().get_fruit()
instance_banana = BananaFactory().get_fruit()
instance_orange = OrangoFactory().get_fruit()
print(instance_apple,instance_banana,instance_orange)
工厂方法练习:
from abc import ABC, abstractmethod
"""
工厂方法
eg:
需求:生产手机,手机类型有苹果、小米、华为等等
需要什么? 工厂-->手机生产线(一个具体的工厂对应一个具体类型的手机生产线)
"""
# 1、创建一个抽象工厂,可以有生产手机的功能(具体生产啥类型不知道)
class AbstractFactory(ABC):
@abstractmethod
def product_phone(self):
"""有生产手机功能"""
pass
# 2、创建生产线
class ProductionLine(ABC):
@abstractmethod
def make_phone(self):
"""制作手机"""
pass
# 3-1、创建苹果工厂,只生产苹果手机
# 3-2、创建华为工厂,只生产华为手机
class IphoneFactory(AbstractFactory):
def product_phone(self):
return Iphone().make_phone()
class HuaWeiFactory(AbstractFactory):
def product_phone(self):
return HuaWei().make_phone()
# 4-1、创建苹果生产线
# 4-2、创建华为生产线
class Iphone(ProductionLine):
def make_phone(self):
print("产出苹果手机")
class HuaWei(ProductionLine):
def make_phone(self):
print("产出华为手机")
def client(factory):
return factory
if __name__ == "__main__":
iphone = client(IphoneFactory()) # 选择苹果工厂
iphone.product_phone() # 产出手机(只能是苹果手机) output:产出苹果手机
huawei = client(HuaWeiFactory()) # 选择华为工厂
huawei.product_phone() # 产出手机(只能是华为手机) output:产出苹果手机
抽象工厂
如果出现很多产品,即会出现很多类的时候,并且这些类可以进行很好的分组,最为合适使用抽象工厂模式。 根据各个类的信息进行分组,每个组由一个工厂类实现。
实现四步法:
- 定义产品类(只定义方法,不具体实现,抽象产品)
- 定义具体的产品类,重写类方法(业务逻辑)
- 定义抽象工厂(定义生产方法,不具体实现)以及每个产品的工厂,重写「抽象工厂」的生产方法
- 定义一个生产工厂类(超级工厂)去决定生产哪个类的实例
"""
场景:假如生产一台手机,需要触摸屏、机壳、充电线,不同型号的手机有不同的触摸屏、不同的机壳、不同的充电线
抽象工厂模式结构
1、抽象产品:抽象触摸屏类、机壳类、充电线类
2、具体产品:具体的触摸屏、机壳、充电线
3、抽象工厂:创造手机工厂类
4、具体工厂:创造不同型号的手机使用不同的具体工厂
5、客户端
相比工厂方法模式,抽象工厂模式生产的是 「一套对象」 比如生成手机需要触摸屏、机壳...等一套对象, 工厂方法生产的是 「一个对象」
"""
from abc import ABCMeta, abstractmethod
# 第一步:定义不同产品的抽象类,通过抽象产品来创建具体的产品类
class ChuMoPing():
"""定义触摸屏抽象类"""
def show_chumoping(self):
pass
# 第二步:定义具体的产品类,这里我们定义了部分产品类:苹果触摸屏、苹果机壳、安卓触摸屏
class IhponeChuMoPing(ChuMoPing):
"""苹果触摸屏"""
def __init__(self, size=11):
self.size = size
def show_chumoping(self):
if self.size > 11:
print("这屏幕是最新的苹果屏幕")
print("这屏幕是苹果11的屏幕")
class AndroidChuMoPing(ChuMoPing):
""" 安卓触摸屏 """
def __init__(self, version = 10):
self.version = version
def show_chumoping(self):
if self.version > 10:
print("这屏幕是最新的苹果屏幕")
print("这屏幕是安卓版本10的屏幕")
# 第三步:定义抽象工厂类,来创建这些手机,不管你要创建什么型号的手机,都继承自这个类
class MakePhoneFactory(metaclass=ABCMeta):
"""生产手机的抽象工厂类"""
@abstractmethod
def make_chumoping(self):
"""创造触摸屏抽象方法"""
pass
# 第四步:定义具体工厂类,在这个类中,我们分别实现抽象父类的「创造」方法,为不用手机机型选不用的产品
class MakeChuMoPingFactory(MakePhoneFactory):
"""触摸屏具体工厂"""
def make_chumoping(self, name):
if name == "iphone":
return IhponeChuMoPing()
elif name == "android":
return AndroidChuMoPing()
# 第五步: 定义一个生产工厂的类(超级工厂)
class MyIphoneProducer(object):
def get_factory(self, name):
if name == "chumoping":
return MakeChuMoPingFactory()
if __name__ == "__main__":
print("###############################")
# 做一部苹果手机
phone = MyIphoneProducer()
# 制作产品:苹果手机零件
chumoping = phone.get_factory('chumoping')
make_chumoping = chumoping.make_chumoping(name="iphone")
# 展示新创建的手机
make_chumoping.show_chumoping()
工厂模式总结
抽象工厂是对一个系列的集中式生产,对不同系列的分散式生产,类型的创建式围绕「超级工厂」创建的
工厂方法模式 | 抽象工厂模式 |
---|---|
针对一个产品 | 针对多个产品 |
一个抽象产品类 | 多个抽象产品类 |
派生出多个具体产品类 | 每个抽象产品可以派生出多个具体产品类 |
一个抽象工厂类,可以派生出多个具体工厂类 | 一个抽象工厂类,可以派生出多个具体工厂类 |
每个具体工厂类只能创建一个具体产品类实例 | 每个具体工厂类可以创建多个具体产品类的实例 |