设计模式第二谈:工厂方法模式

这篇文章介绍23种常用设计模式中的工厂方法 - Factory Method模式及其Python实现。

1、什么是工厂方法模式
“四人帮”编写的《设计模式-可复用面相对象软件的基础》一书中给出定义是:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。

是不是感到一头雾水,脑海中瞬间浮现出“黑人问号”?我们暂且先讲这个定义放到这,先看看下面的Python代码示例,然后回过头来理解这个定义。

2、Python代码实现考虑这样一个场景:
一家汽车生产公司分别接到宝马、奔驰的订单,开设两条汽车生产线,分别生产宝马、奔驰汽车。
以上场景如何通过面向对象的方式实现呢?了解过面向对象的童鞋们会想说,我们需要两个基类:一个是表示汽车生产工厂的工厂类,一个具有汽车通用性质的汽车类;然后定义汽车类的两个子类,分别用来实现宝马汽车和奔驰汽车的具体细节。

接下来,我们看一下如何使用Python实现上述思路。

Python实现汽车类Car.py

from abc import ABC, abstractmethod

class Car(ABC):
“”“汽车抽象类”""

@abstractmethod
def drive(self):
pass

@abstractmethod
def whistle(self):
pass
这里定义了一个抽象类Car来表示汽车,并抽象了汽车的两个操作:驾驶和鸣笛。

Python实现宝马汽车类CarBMW.py

from .Car import Car

class CarBMW(Car):
“”“宝马汽车实例类”""

def drive(self):
print(“驾驶宝马汽车”)

def whistle(self):
print(“宝马汽车鸣笛”)
Python实现奔驰汽车类BENZ.py

from .Car import Car

class CarBENZ(Car):
“”“奔驰汽车实例类”""

def drive(self):
print(“驾驶奔驰汽车”)

def whistle(self):
print(“奔驰汽车鸣笛”)
这里使用类继承的方式定义类两个类:表示宝马汽车的BMW、表示奔驰汽车的BENZ。

Python实现工厂类Factory.py

from abc import ABC, abstractmethod

class CarFactory(object):
“”“抽象工厂类:汽车工厂”""

@abstractmethod
def create(self):
pass
这里定义了一个工厂类CarFactory并定义了一个方法create.

Python实现宝马汽车工厂

from .CarBMW import CarBMW
from .CarFactory import CarFactory

class CarFactoryBMW():
“”“宝马汽车工厂”""

def create(self):
return CarBMW()
Python实现奔驰汽车工厂

from .CarBENZ import CarBENZ
from .CarFactory import CarFactory

class CarFactoryBENZ():
“”“奔驰汽车工厂”""

def create(self):
return CarBENZ()
main.py

from .CarFactoryBMW import CarFactoryBMW
from .CarFactoryBENZ import CarFactoryBENZ

if name == “main”:

实例化宝马汽车工厂

bmw_car_factory = CarFactoryBMW()

生产宝马汽车,并测试

bmw_car = bmw_car_factory.create()
bmw_car.whistle() # 宝马汽车鸣笛
bmw_car.drive() # 驾驶宝马汽车

实例化奔驰汽车工厂

benz_car_factory = CarFactoryBENZ()

生产奔驰汽车,并测试

benz_car = benz_car_factory.create()
benz_car.whistle() # 奔驰汽车鸣笛
benz_car.drive() # 驾驶奔驰汽车
这里模拟了创建一个工厂,并根据订单生产相应的汽车,最后对生产的汽车做测试。执行main.py程序将会得到如下输出。

宝马汽车鸣笛
驾驶宝马汽车
奔驰汽车鸣笛
驾驶奔驰汽车
到目前为止,我们使用Python并基于面向对象的理念实现了对场景的模拟。

你有没有注意到,上述代码是一种对工厂模式的解释呢?让我们在回顾一下工厂方法的定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,使得一个类的实例化延迟到其子类。

CarFactory类解释了定义一个用于创建对象的接口

CarFactoryBMW和CarFactoryBENZ类解释了让子类决定实例化哪一个类

看完这些解释是不是有一种”啊,原来是这样“的感觉,如果有这样的感觉,可以不忙看下面的内容,找个旁边的小伙伴,像他普及一下什么是工厂方法模式;如果没有这样的感觉,可能还需要在意会一下。

3、工厂方法模式的结构
依据上述的Python代码实现,可以总结出:工厂方法模式由抽象工厂、具体工厂、抽象产品和具体产品等4个要素组成,其中:

抽象工厂:声明工厂创建产品的抽象方法,该方法将会返回一个产品类型的对象

具体工厂:主要是实现抽象工厂定义的创建产品的抽象方法,将会完成具体产品的创建

抽象产品:声明产品的通用属性和功能,定义产品规范

具体产品:具体实现了产品的属性和功能,具体产品由具体工厂来创建

工厂方法模式的UML类图如下图所示。

在这里插入图片描述

4、工厂方法模式的适用性
工厂方法模式可应用于以下情况:

当一个类不知道它所必须创建的对象的类的时候

当一个类希望由它的子类来指定它所创建的对象的时候

当类创建对象的职责委托给多个帮助子类的某一个,并且你希望哪一个帮助子类是代理者这一信息局部化的时候

5、工厂方法模式的优缺点
优点:

用户只需要知道具体工厂的名称就可以得到产品,无需知道产品的具体创建过程

在系统增加新的产品时,只需要添加具体产品类和具体工厂类,无需对原工厂进行任何修改,满足开闭原则

缺点:

当系统增加新的产品时,就要添加具体的产品类和工厂类,增加了代码的复杂度

6、工厂方法模式的其他实现
假如提前了解到产品类型就只有固定的几个,可以使用一个具体的工厂就能完成任务时,可删除上述的抽象工厂类及其子类,仅使用一个工厂类就能完成,这时的工厂方法模式也称为简单工厂模式,这时的工厂类如下:

from .CarBMW import CarBMW
from .CarBENZ import CarBENZ

class CarFactory():
“”“工厂类”""

def create(car_type):
if car_type == “BMW”:
return CarBMW()
elif car_type == “BENZ”:
return CarBENZ()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值