第四十篇 Python之设计模式总结-简单工厂、工厂方法、抽象工厂、单例模式
一. 简单工厂
简单工厂模式(Simple Factory Pattern):是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类.
简单工厂的用处不大,主要就是一个if...else语句
结合一个具体的例子,把上面的图再对应一下
# 1. 定义一个工厂,对应图中的接受参数
class BigCat(object):
# 接受参数(接受原材料)
def __init__(self, money):
self.money = money
# 工厂基本的生产模板
def pay(self):
print("收到大猫金融支付金额{0}".format(self.money)) # 2. 定义不同的产品生产线
class WeChat(object): def __init__(self, money):
self.money = money def pay(self):
print("收到微信支付金额{0}".format(self.money)) class ZhiFuBao(object): def __init__(self, money):
self.money = money def pay(self):
print("收到支付宝支付金额{0}".format(self.money)) # 3. 输入参数(原材料入场)
channel = input("请选择支付方式:")
money = input("请输入消费金额:") # 简单工厂,if...else判断就行了
# 4. 根据接收的不同原材料,判断是生产什么产品的,然后进行对应产品线的具体生产
# 如果是要微信支付
if channel == 'WeChat':
WeChat(money).pay() # Wechat()实例化,生产微信对应的产品
elif channel == 'ZhiFuBao':
ZhiFuBao(money).pay()
else:
BigCat(money).pay()
class Fruit:
def __init__(self,name,weight):
self.name = name
self.weight = weight def product(self):
print("这是{},重量是{}吨,用来生产混合果汁的".format(self.name, self.weight)) class Apple(Fruit):
def __init__(self,name,weight):
super(Apple, self).__init__(name,weight) def product(self):
print("这是{},重量是{}吨,用来生产{}罐头的".format(self.name, self.weight, self.name)) class Peer(Fruit):
def __init__(self,name,weight):
super(Peer, self).__init__(name, weight) def product(self):
print("这是{},重量是{}吨,用来生产{}罐头的".format(self.name, self.weight, self.name)) if __name__ == "__main__":
name = input("请输入原材料:")
weight = input("请输入原材料的重量: ")
if name == 'Apple':
Apple(name, weight).product()
elif name == "Peer":
Peer(name, weight).product()
else:
Fruit(name, weight).product()
实现简单水果工厂,可以根据水果名生产对应的水果罐头
二.工厂方法
工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延时到其子类.
工厂方法模式克服了简单工厂模式违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点
场景:雷锋工厂,不关心执行者,只关心执行结果
工厂方法的实现要点:
1. 先要定义每一个产品的具体生产细节(定义每一个产品的类)
2. 再给需要的每一个产品都创建一个生产工厂,提供一个统一的创建方法,然后该创建方法返回具体的产品
3. 这个过程就是把每个产品的生产细节在工厂方法里给包装了一个,外部使用者调用的时候是看不到具体的实现细节的。 工厂方法的使用:
1. 要使用哪个工厂方法,就from...import...,导入具体的工厂方法
2. 然后调用该工厂,获取具体的产品(方法)
3. 有了具体的产品(方法)就可以执行具体的逻辑了 工厂方法传参数会有个小的注意点需要小心,有两种处理方式可以灵活使用:
1. 在定义每个产品类的时候不要在构造方法里接受参数,直接在具体的类方法里接受参数,对应的也使用的时候,也只在调用具体的方法的时候传参
2. 在每个产品类的构造方法里传参, 工厂方法与简单工厂的比较:
1. 不需要給使用者暴露具体的产品的生产过程细节,能封装很多细节,只给使用者提供了一个接口,更解耦;而简单工厂则都暴露给了使用者
2. 如果有新增,简单工厂就需要添加一个if;而工厂方法虽然也需要添加,但是使用者需要使用的时候只需要import对应的工厂方法就可以了,不用的话就无所谓了
3. 工厂方法最大的优点就是把对象的获取和对象的创建给隔离开了,根本不关心对象是怎么创建的 举例:
有个大猫金融、支付宝、微信三种支付渠道,实现一个工厂方法并使用工厂方法
1. 实现工厂方法,文件名:factorymethodpractice.py
# 1. 先定义不同的支付方式(对应工厂里具体的产品),及每个产品具体的生产细节 class BigCat():
# 关于传参的处理方式一: 有构造函数
def __init__(self,money):
self.money = money def pay(self):
print("收到大猫金融的支付金额{0}".format(self.money)) class WeChat():
# 关于传参的处理方式二:直接就没有构造函数,只在具体的方法里接受参数
def pay(self, money):
print("收到微信支付的金额{0}".format(money)) class ZhiFuBao():
def __init__(self, money):
self.money = money def pay(self):
print("收到支付宝支付的金额{0}".format(self.money)) # 2. 为每个支付方式(每个产品)定义特定的工厂,每个工厂都有具体的工厂方法函数,负责返回
# 具体的工厂方法函数,其实就是对每个产品具体的生产细节进行了包装,让外部使用者只能用,却不知道具体的生产过程细节 # 3. 对外只提供这些特定的工厂(接口)
class BigCatFactory():
# 关于传参的处理方式一:
# 因为BigCat()类是需要传参的,return其实就是先调用BigCat()类,将BigCat()执行结果返回,所以也需要传参
# 因此,可以在create的时候就传递参数
def create(self,money):
return BigCat(money) class WeChatFactory():
# 关于传参的处理方式二:
# WeChat()没有构造函数,初始化的时候不接收参数,所以对外提供的接口不需要传参
# 只有在调用WeChat下面具体的pay()方法时才需要传递参数
def create(self):
return WeChat() class ZhiFuBaoFactory():
def create(self, money):
return ZhiFuBao(money)
2. 使用工厂方法: usefactorymethod.py
# 1. 先获取工厂
from factorymethodpractice import BigCatFactory # 获取工厂
factory = BigCatFactory() # 2. 调工厂去创建具体的产品
# 关于传参的处理方式一:在调用create的时候就给create传递参数
payment = factory.create(100) # # 3. 有了具体的产品,就可以去执行具体产品里具体的逻辑了
payment.pay() ''' ------------------------- ''' from factorymethodpractice import WeChatFactory
factory = WeChatFactory()
payment = factory.create()
# 关于传参的处理方式二:只在调用具体方法的时候给需要传参的方法才传递参数
payment.pay(200)
再举个例子说明工厂方法及两种参数不同的处理方式
# 接口文件 fruitfactorypractice.py # 定义Apple产品类,实现具体的生产细节
class Apple():
# 参数处理方式一:有构造方法
def __init__(self,name):
self.name = name def appleguantou(self):
print("{}罐头生产出来了".format(self.name)) # 定义生产Apple的工厂方法
class AppleFactory():
# create的时候就需要传递参数,因为Apple在实例化的时候就需要用到参数
def create(self, name):
return Apple(name) ### ++++++++++++++++++++++++++### # 定义Pear产品类,实现具体的生产细节
class Pear(object):
# 参数的处理方式二:没有构造方法
def pearguantou(self,name):
print("{}罐头生产出来了".format(name))
# 定义生产Pear的工厂方法
class PearFactory(object):
# 参数的处理方式二:create的时候不需要传递参数,只有在调用到需要用参数的方法pearguantou的时候才传递参数
def create(self):
return Pear()
# 调用文件,使用工厂方法 文件名:usefactorymethod.py from fruitfactorypractice import AppleFactory
factory = AppleFactory()
proment = factory.create('第四十篇 Python之设计模式总结-简单工厂、工厂方法、抽象工厂、单例模式的更多相关文章
- 孤荷凌寒自学python第四十天python 的线程锁RLock
孤荷凌寒自学python第四十天python的线程锁RLock (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 因为研究同时在多线程中读写同一个文本文件引发冲突,所以使用Lock锁尝试同步, ...
- 设计模式之工厂模式VS抽象工厂
一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...
- 详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂) v阅读目录
1楼留头头大神:http://www.cnblogs.com/toutou/p/4899388.html v阅读目录 v写在前面 v简单工厂模式 v工厂方法模式 v抽象工厂模式 v博客总结 v博客 ...
- C# 设计模式(1)——简单工厂模式、工厂模式、抽象工厂模式
1.前言 上一篇写了设计模式原则有助于我们开发程序的时候能写出高质量的代码(牵一发而不动全身),这个系列还是做个笔记温习一下各种设计模式,下面就看看简单工厂模式.工厂模式.抽象工厂模式. 2.简单工厂 ...
- Delphi 设计模式:《HeadFirst设计模式》Delphi代码---工厂模式之抽象工厂[转]
1 2 {<HeadFirst设计模式>工厂模式之抽象工厂 } 3 { 抽象工厂的产品 } 4 { 编译工具:Delphi7.0 ...
- [python实现设计模式]-3.简单工厂模式-触宝开放平台
预备知识: 开放封闭原则(Open-Closed Principle OCP) Software entities(classes,modules,functions etc) should open ...
- 大话设计模式C++实现-第15章-抽象工厂模式
一.UML图 二.概念 抽象方法模式(Abstract Factory):提供一个创建一系列相关或互相依赖对象的接口,而无需指定他们详细的类. 三.包括的角色 (1)抽象工厂 (2)详细工厂:包含详细 ...
- Java设计模式从精通到入门五 抽象工厂方法模式
定义 抽象工厂类为创建一组相关和相互依赖的对象提供一组接口,而无需指定一个具体的类. 这里我得把工厂方法模式得定义拿出来做一下比较:定义一个创建对象的接口,由子类决定实例化哪一个类.工厂方法是一个 ...
- C#设计模式——简单工厂模式、工厂模式和抽象工厂模式
一:简单工厂模式 1:描述:简单工厂模式是由一个工厂对象根据接收到的消息决定要创建哪一个类的对象事例. 2:优点:工厂类中有相关逻辑判断,可以根据需要动态创建相关的对象事例,而客户端只需要告诉工厂类创 ...
随机推荐
- ASP.NET Web API编程——版本控制
版本控制 版本控制的方法有很多,这里提供一种将Odata与普通web api版本控制机制统一的方法,但也可以单独控制,整合控制与单独控制主要的不同是:整合控制通过VersionController ...
- Impossible WHERE noticed after reading const tables
阿里云反馈的慢SQL,执行计划返回如下:Impossible WHERE noticed after reading const tables sql很简单: SELECT * FROM deposi ...
- CSS技巧之向下箭头
思路:使用◇符号(可在输入法的软键盘找到该符号),使用定位选择位置,并隐藏溢出的上半部分细点:1.使用i标签的楷体属性把◇变大2.给i只有◇符号一半的高度,并隐藏溢出,正常显示一个向上箭头3.对s使用 ...
- 基于vue脚手架的项目打包上线(发布)方法和误区
最近要把vue脚手架开发的一个项目上线,只知道vue脚手架是基于node的服务端项目,那么只需要 npm run dev 就可以轻松启动整个项目,当我想当然的给服务器配置合适的node环境(这里也遇到 ...
- Android 中Dialog的使用
本文是参考ProAndroid的第10章Working with Dialogs的内容,在合适的地方添加了作者自己的一些见解最终成文. Android 中的对话框是一个展示在当前窗口上的小一号的窗口, ...
- ORACLE GOLDEN GATE oracle同步数据至kafka
一.服务器信息 ip 软件版本 ogg版本 软件包 操作系统版本 OGG安装路径 10.1.50.52 源 oracle11.2.0.4 12.2.0.1.1 V100692-01.zip cen ...
- php与java
作者:eechen链接:https://www.zhihu.com/question/20377398/answer/141328982来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...
- 如何给ioloop.run_sync()中调用的函数传入参数
问题 如何给tornado.ioloop.IOLoop中的run_sync方法中调用的函数添加参数 解决方案 使用functools.partial 解决示例 from tornado import ...
- UIDynamic-吸附-重力-碰撞-物理仿真动画
现实生活中: 运动场==物理仿真器 跑步==物理仿真行为 人==仿真元素 创建步骤: 1.创建物理仿真器,并且指定仿真范围 2.创建物理仿真行为,并且指定仿真元素 3.将物理仿真行为添加到仿真器中 D ...
- linux普通用户su root切换提示没有文件或目录
1. 首先进入单用户模式: 1). ubuntu : 上述情况可以在grub界面选择第二项修复,但没有grub可以参考: 1.重启ubuntu,随即长按shirft进入grub菜单: 2.选择reco ...