简单工厂模式
在工厂模式中,我们创建对象时不会对客户端暴露创建逻辑,并且提供一个「工厂类」去创建对象,只需要告诉工厂我需要什么,比如需要一辆汽车,去工厂提货,不用去关心汽车是怎么做出来的。
适用场景:创建复杂对象 & 希望隐藏「创建类的代码逻辑」 优点:无需关心对象内部实现逻辑,需要则通过工厂创建即可 缺点:违背开闭原则,有新的产品加入时,就需要修改工厂类,具体产品和工厂耦合高,扩展性低。
参考文档: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:"""简单工厂模式"""@staticmethoddef 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.abstractmethoddef 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):@abstractmethoddef product_phone(self):"""有生产手机功能"""pass# 2、创建生产线class ProductionLine(ABC):@abstractmethoddef 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 factoryif __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 = sizedef show_chumoping(self):if self.size > 11:print("这屏幕是最新的苹果屏幕")print("这屏幕是苹果11的屏幕")class AndroidChuMoPing(ChuMoPing):""" 安卓触摸屏 """def __init__(self, version = 10):self.version = versiondef show_chumoping(self):if self.version > 10:print("这屏幕是最新的苹果屏幕")print("这屏幕是安卓版本10的屏幕")# 第三步:定义抽象工厂类,来创建这些手机,不管你要创建什么型号的手机,都继承自这个类class MakePhoneFactory(metaclass=ABCMeta):"""生产手机的抽象工厂类"""@abstractmethoddef 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()
工厂模式总结
抽象工厂是对一个系列的集中式生产,对不同系列的分散式生产,类型的创建式围绕「超级工厂」创建的
| 工厂方法模式 | 抽象工厂模式 |
|---|---|
| 针对一个产品 | 针对多个产品 |
| 一个抽象产品类 | 多个抽象产品类 |
| 派生出多个具体产品类 | 每个抽象产品可以派生出多个具体产品类 |
| 一个抽象工厂类,可以派生出多个具体工厂类 | 一个抽象工厂类,可以派生出多个具体工厂类 |
| 每个具体工厂类只能创建一个具体产品类实例 | 每个具体工厂类可以创建多个具体产品类的实例 |
