3、工厂模式

mac2025-10-12  6

一、工厂模式

工厂模式主要用于简化对象的创建。通常工厂模式有三中表现形式:1、简单工厂,2、工厂方法,3、抽象工厂

1、简单工厂示例

首先,我们先看一个简单工厂的例子:

#coding=utf-8 class Mercedes(object): """梅赛德斯 """ def __repr__(self): return "Mercedes-Benz" class BMW(object): """宝马 """ def __repr__(self): return "BMW"

假设我们有两个“产品”分别是**Mercedes**和**BMW**的汽车,如果没有“工厂”来生产它们,我们就要在代码中自己进行实例化,如:

mercedes = Mercedes() bmw = BMW()

但现实中,你可能会面对很多汽车产品,而且每个产品的构造参数还不一样,这样在创建实例时会遇到麻烦。这时就可以构造一个“简单工厂”把所有汽车实例化的过程封装在里面。

class SimpleCarFactory(object): """简单工厂 """ @staticmethod def product_car(name): if name == 'mb': return Mercedes() elif name == 'bmw': return BMW()

有了**SimpleCarFactory**类后,就可以通过向固定的接口传入参数获得想要的对象实例,如下:

c1 = SimpleCarFactory.product_car('mb') c2 = SimpleCarFactory.product_car('bmw')

2、工厂方法

虽然有了一个简单的工厂,但在实际使用工厂的过程中,我们会发现新问题:如果我们要新增一个“产品”,例如Audi的汽车,我们除了新增一个Audi类外还要修改SimpleCarFactory内的product_car方法。所以我们在简单工厂的基础上把**SimpleCarFactory**抽象成不同的工厂,每个工厂对应生成自己的产品,这就是工厂方法。

#coding=utf-8 import abc class AbstractFactory(object): """抽象工厂 """ __metaclass__ = abc.ABCMeta @abc.abstractmethod def product_car(self): pass class MercedesFactory(AbstractFactory): """梅赛德斯工厂 """ def product_car(self): return Mercedes() class BMWFactory(AbstractFactory): """宝马工厂 """ def product_car(self): return BMW()

我们把工厂抽象出来用abc模块实现了一个抽象的基类**AbstractFactory**,这样就可以通过特定的工厂来获得特定的产品实例了:

c1 = MercedesFactory().product_car() c2 = BMWFactory().product_car()

每个工厂负责生产自己的产品也避免了我们在新增产品时需要修改工厂的代码,而只要增加相应的工厂即可。如新增一个Audi产品,只需新增一个Audi类和**AudiFactory**类。

3、抽象工程

工厂方法虽然解决了我们“修改代码”的问题,但如果我们要生产很多产品,就会发现我们同样需要写很多对应的工厂类。比如如果MercedesFactory和BMWFactory不仅生产小汽车,还要生产SUV,那我们用工厂方法就要再多构造两个生产SUV的工厂类。所以为了解决这个问题,我们就要再更进一步的抽象工厂类,让一个工厂可以生产同一类的多个产品,这就是抽象工厂。具体实现如下:

#coding=utf-8 import abc # 两种小汽车 class Mercedes_C63(object): """梅赛德斯 C63 """ def __repr__(self): return "Mercedes-Benz: C63" class BMW_M3(object): """宝马 M3 """ def __repr__(self): return "BMW: M3" # 两种SUV class Mercedes_G63(object): """梅赛德斯 G63 """ def __repr__(self): return "Mercedes-Benz: G63" class BMW_X5(object): """宝马 X5 """ def __repr__(self): return "BMW: X5" class AbstractFactory(object): """抽象工厂 可以生产小汽车外,还可以生产SUV """ __metaclass__ = abc.ABCMeta @abc.abstractmethod def product_car(self): pass @abc.abstractmethod def product_suv(self): pass class MercedesFactory(AbstractFactory): """梅赛德斯工厂 """ def product_car(self): return Mercedes_C63() def product_suv(self): return Mercedes_G63() class BMWFactory(AbstractFactory): """宝马工厂 """ def product_car(self): return BMW_M3() def product_suv(self): return BMW_X5()

我们让基类**AbstractFactory同时可以生产汽车和SUV,然后令MercedesFactory和BMWFactory继承AbstractFactory**并重写product_car和product_suv方法即可。

c1 = MercedesFactory().product_car() s1 = MercedesFactory().product_suv() print(c1, s1) s2 = BMWFactory().product_suv() c2 = BMWFactory().product_car() print(c2, s2)

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

二、工厂模式的优点和应用

工厂模式、抽象工厂模式的优点: 1、工厂模式巨有非常好的封装性,代码结构清晰;在抽象工厂模式中,其结构还可以随着需要进行更深或者更浅的抽象层级调整,非常灵活; 2、屏蔽产品类,使产品的被使用业务场景和产品的功能细节可以分而开发进行,是比较典型的解耦框架。 工厂模式、抽象工厂模式的使用场景: 1、当系统实例要求比较灵活和可扩展时,可以考虑工厂模式或者抽象工厂模式实现。比如, 在通信系统中,高层通信协议会很多样化,同时,上层协议依赖于下层协议,那么就可以对应建立对应层级的抽象工厂,根据不同的“产品需求”去生产定制的实例。

三、工厂类模式的不足

1、工厂模式相对于直接生成实例过程要复杂一些,所以,在小项目中,可以不使用工厂模式; 2、抽象工厂模式中,产品类的扩展比较麻烦。毕竟,每一个工厂对应每一类产品,产品扩展,就意味着相应的抽象工厂也要扩展。

参考文献:

https://segmentfault.com/a/1190000013053013

最新回复(0)