Python笔记之工厂模式


Posted in Python onNovember 20, 2019

工厂模式: “工厂”即表示一个负责创建其他类型的对象的类,通常情况下,一个工厂的对象会有一个或多个方法与之关联,这些方法用于创建不同类型的对象,工厂对象会根据客户端给方法传递的不同的参数或者客户端调用不同的方法返回不同的对象。

优点:对象的创建是可以根据需要单独创建的,但是使用工厂模式来创建对象有以下优点:

  • 松耦合,对象的创建是根据工厂类来进行的,与类本身的实现是独立开来的。
  • 对于客户端来说,不需要知道类的具体实现,只需要调用相应接口就可以得到需要的对象了,这其实是简化了客户端的相关实现。
  • 对于对象的修改只需要在工厂里面进行即可,包括添加新的对象,客户端只需要更改少量的代码,甚至可以不修改代码就可以达到要求。
  • 使用工厂接口,还可以重用已有的对象,不用去别处调用已有的对象或者重新创建一个对象。

工厂模式的3种实现形式(或者说3中变体):

  • 简单工厂模式:工厂类会提供一个接口,并根据客户端传入参数来创建相应的实例对象。(创建一个对象)
  • 工厂方法模式:需要定义一个基类,不同的子类则代表着不同类型的对象。相对于简单工厂模式而言,工厂方法模式具有更强的可定制性。(创建一个对象)
  • 抽象工厂模式:需要定义一个抽象工厂类,然后由不同的子类来创建不同系列的对象,一个系列即代表一组对象。(创建一组对象)

简单工厂模式示例:

from abc import ABCMeta, abstractmethod


class Flower(metaclass=ABCMeta):
 @abstractmethod
 def show_price(self):
  pass


class Rose(Flower):
 def show_price(self):
  print('Rose price: $99')


class Tulip(Flower):
 def show_price(self):
  print('Tulip price: $66')


class FlowerSimpleFactory:
 def get_flower(self, flower_type):
  return eval(flower_type)()


if __name__ == '__main__':
 flower_factory = FlowerSimpleFactory()
 rose = flower_factory.get_flower('Rose')
 tulip = flower_factory.get_flower('Tulip')
 rose.show_price()
 tulip.show_price()
Rose price: $99
Tulip price: $66

特点:接口根据客户端传入的参数即可返回对应的实例对象,甚至不用返回它的对象就可以进行对应的操作(比如示例中的工厂FlowerSimpleFactory中可以直接定义一个print_price方法来打印各种花的价格,而不是先返回对象,再由对象调用show_price方法来打印),即不会暴露对象的创建逻辑,客户端直接使用接口即可完成对象的创建,甚至创建对象之后的一些操作。

工厂方法模式示例:

from abc import ABCMeta, abstractmethod


class Flower(metaclass=ABCMeta):
 @abstractmethod
 def show_price(self):
  pass


class Rose(Flower):
 def show_price(self):
  print('Rose price: $99')


class Tulip(Flower):
 def show_price(self):
  print('Tulip price: $66')


class Lily(Flower):
 def show_price(self):
  print('Lily price: $33')


class FlowerShopFactory(metaclass=ABCMeta):
 def __init__(self):
  self.flowers = []
  self.stock_flowers()

 @abstractmethod
 def stock_flowers(self):
  pass

 def get_flowers(self):
  return self.flowers

 def add_flower(self, flower):
  self.flowers.append(flower)


class FlowerShop1(FlowerShopFactory):
 def stock_flowers(self):
  self.add_flower(Rose())
  self.add_flower(Tulip())


class FlowerShop2(FlowerShopFactory):
 def stock_flowers(self):
  self.add_flower(Rose())
  self.add_flower(Tulip())
  self.add_flower(Lily())


if __name__ == '__main__':
 flower_shop1 = FlowerShop1()
 for flower in flower_shop1.get_flowers():
  flower.show_price()

 flower_shop2 = FlowerShop2()
 for flower in flower_shop2.get_flowers():
  flower.show_price()
Rose price: $99
Tulip price: $66
Rose price: $99
Tulip price: $66
Lily price: $33

特点:工厂方法可以根据基类来定义不同的子类,如示例中的FlowerShop1和FlowerShop2,每个子类则代表“工厂”可以创建的一个“产品”。即对象的创建是通过继承的子类来完成的。

抽象工厂模式示例:

from abc import ABCMeta, abstractmethod


class MiniCar(metaclass=ABCMeta):
 @abstractmethod
 def show_size(self):
  pass


class SedanCar(metaclass=ABCMeta):
 @abstractmethod
 def show_price(self):
  pass


# 国产车
class DomesticMiniCar(MiniCar):
 def show_size(self):
  print('Domestic mini car size: 111')


class DomesticSedanCar(SedanCar):
 def show_price(self):
  print('Domestic sedan car price: 10W')


# 英国车
class EnglishMiniCar(MiniCar):
 def show_size(self):
  print('English mini car size: 222')
  

class EnglishSedanCar(SedanCar):
 def show_price(self):
  print('English sedan car price: 30w')


# 抽象工厂类
class CarFactory(metaclass=ABCMeta):
 @abstractmethod
 def create_mini_car(self):
  pass

 @abstractmethod
 def create_sedan_car(self):
  pass


# 国产车工厂类
class DomesticCarFactory(CarFactory):
 def create_mini_car(self):
  return DomesticMiniCar()
 
 def create_sedan_car(self):
  return DomesticSedanCar()


# 英国车
class EnglishCarFactory(CarFactory):
 def create_mini_car(self):
  return EnglishMiniCar()
 
 def create_sedan_car(self):
  return EnglishSedanCar()

特点:需要定义一个接口(如示例的抽象工厂类)来创建一系列的相关对象,如示例中的两个子类分别创建两个系列的对象(国产车和英国车),即对象的创建也是由子类来完成。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python函数式编程指南(三):迭代器详解
Jun 24 Python
python中ImageTk.PhotoImage()不显示图片却不报错问题解决
Dec 06 Python
Python基于Tkinter模块实现的弹球小游戏
Dec 27 Python
Django框架首页和登录页分离操作示例
May 28 Python
Python 使用matplotlib模块模拟掷骰子
Aug 08 Python
Numpy对数组的操作:创建、变形(升降维等)、计算、取值、复制、分割、合并
Aug 28 Python
Python 闭包,函数分隔作用域,nonlocal声明非局部变量操作示例
Oct 14 Python
SpringBoot实现登录注册常见问题解决方案
Mar 04 Python
python实现UDP协议下的文件传输
Mar 20 Python
Python基于百度AI实现OCR文字识别
Apr 02 Python
解决python脚本中error: unrecognized arguments: True错误
Apr 20 Python
iPython pylab模式启动方式
Apr 24 Python
Python常用模块logging——日志输出功能(示例代码)
Nov 20 #Python
将python2.7添加进64位系统的注册表方式
Nov 20 #Python
10个Python面试常问的问题(小结)
Nov 20 #Python
python使用pip安装SciPy、SymPy、matplotlib教程
Nov 20 #Python
Python笔记之facade模式
Nov 20 #Python
将python安装信息加入注册表的示例
Nov 20 #Python
如何使用Python脚本实现文件拷贝
Nov 20 #Python
You might like
PHP测试成功的邮件发送案例
2015/10/26 PHP
Yii中srbac权限扩展模块工作原理与用法分析
2016/07/14 PHP
利用ajax和PHP实现简单的流程管理
2017/03/23 PHP
php生成条形码的图片的实例详解
2017/09/13 PHP
解决laravel groupBy 对查询结果进行分组出现的问题
2019/10/09 PHP
PDO实现学生管理系统
2020/03/21 PHP
JS或jQuery获取ASP.NET服务器控件ID的方法
2015/06/08 Javascript
在jQuery中处理XML数据的大致方法
2015/08/14 Javascript
AngularJS控制器controller正确的通信的方法
2016/01/25 Javascript
Bootstrap 3 按钮标签实例代码
2017/02/21 Javascript
JavaScript实现类似淘宝的购物车效果
2017/03/16 Javascript
js正则相关知识点专题
2018/05/10 Javascript
vue解决使用webpack打包后keep-alive不生效的方法
2018/09/01 Javascript
使用layui监听器监听select下拉框,事件绑定不成功的解决方法
2019/09/28 Javascript
[40:27]完美世界DOTA2联赛PWL S3 PXG vs GXR 第一场 12.19
2020/12/24 DOTA
Python统计单词出现的次数
2018/04/04 Python
python3.X 抓取火车票信息【修正版】
2018/06/19 Python
Win10下python3.5和python2.7环境变量配置教程
2018/09/18 Python
Django urls.py重构及参数传递详解
2019/07/23 Python
Python自动化完成tb喵币任务的操作方法
2019/10/30 Python
pycharm通过anaconda安装pyqt5的教程
2020/03/24 Python
新手常见Python错误及异常解决处理方案
2020/06/18 Python
python使用建议与技巧分享(二)
2020/08/17 Python
HTML5事件方法全部汇总
2016/05/12 HTML / CSS
H5调用相机拍照并压缩图片的实例代码
2017/07/20 HTML / CSS
详解canvas.toDataURL()报错的解决方案全都在这了
2020/03/31 HTML / CSS
美国购买和销售礼品卡平台:Raise
2017/01/13 全球购物
美国优质马术服装购买网站:Breeches.com
2019/12/16 全球购物
PHP经典面试题
2016/09/03 面试题
高校毕业生自我鉴定
2013/10/27 职场文书
生产车间班组长岗位职责
2014/01/06 职场文书
预备党员思想汇报1000字
2014/10/07 职场文书
2015年教师师德师风承诺书
2015/04/28 职场文书
农业项目投资意向书
2015/05/09 职场文书
2016年度基层党建工作公开承诺书
2016/03/25 职场文书
2019最新劳动仲裁申请书!
2019/07/08 职场文书