第四十篇 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:优点:工厂类中有相关逻辑判断,可以根据需要动态创建相关的对象事例,而客户端只需要告诉工厂类创 ...
随机推荐
- 显示mac电脑中隐藏的文件和文件夹
显示mac电脑中隐藏的文件和文件夹的办法:打开电脑,cd到相应的文件夹,输入以下命令,为显示隐藏的文件和文件夹 defaults write com.apple.finder AppleShowAll ...
- Softmax回归(Softmax Regression, K分类问题)
Softmax回归:K分类问题, 2分类的logistic回归的推广.其概率表示为: 对于一般训练集: 系统参数为: Softmax回归与Logist ...
- java中StringBuffer与String、StringBuilder的区别
在java中我们经常可以看到StringBuffer和String的用法,但是我自己在使用过程中,经常会将两者弄混淆,今天我们就来了解一下两者的区别: 我们首先来看一下我们的官方API中的简单介绍: ...
- Xcode命令行作用
问题:Command Line Tools for Xcode有什么用 答案: Command Line Tools里面有git, xcrun, xcodebuild, gcc, gdb, make等 ...
- jsp内置对象pageContext如何在Servlet中获取值
pageContext javax.servlet.jsp.PageContext 的实例,该对象代表该JSP 页面上下文,使用该对象可以访问页面中的共享数据.常用的方法有getServletCont ...
- ie 兼容
ese,promise解决text/babel <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7 ...
- LeetCode 中级 - 优势洗牌(870)
给定两个大小相等的数组 A 和 B,A 相对于 B 的优势可以用满足 A[i] > B[i] 的索引 i 的数目来描述. 返回 A 的任意排列,使其相对于 B 的优势最大化. 示例 2: 输入: ...
- Zabbix——自动发现
前提条件: Zabbix版本为4.0 固定网段寻找网络设备,并添加组.添加模板.添加proxy. 设置完毕,等待~~ 如果没有问题,将会直接出现在host中.
- 阿里云centOS7.4上MySql5.6安装
最近一个项目要部署在阿里云上,为了开发团队方便,我自费买了个ECS,先装个数据库给开发用. 因为之前都是在真机安装,与这次阿里云上的部署比起来,还是有点区别的. Mysql 1 安装mysql版本包 ...
- 10.31课程.this指向
作用域: 浏览器给js的生存环境(栈). 作用域链: js中的关键字例如var.function...都可以提前声明,然后js由上到下逐级执行,有就使用,没有就在它的父级元素中查找.这就叫做作用域链. ...