第四十篇 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 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 因为研究同时在多线程中读写同一个文本文件引发冲突,所以使用Lock锁尝试同步, ...
一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...
1楼留头头大神:http://www.cnblogs.com/toutou/p/4899388.html v阅读目录 v写在前面 v简单工厂模式 v工厂方法模式 v抽象工厂模式 v博客总结 v博客 ...
1.前言 上一篇写了设计模式原则有助于我们开发程序的时候能写出高质量的代码(牵一发而不动全身),这个系列还是做个笔记温习一下各种设计模式,下面就看看简单工厂模式.工厂模式.抽象工厂模式. 2.简单工厂 ...
1 2 {<HeadFirst设计模式>工厂模式之抽象工厂 } 3 { 抽象工厂的产品 } 4 { 编译工具:Delphi7.0 ...
预备知识: 开放封闭原则(Open-Closed Principle OCP) Software entities(classes,modules,functions etc) should open ...
一.UML图 二.概念 抽象方法模式(Abstract Factory):提供一个创建一系列相关或互相依赖对象的接口,而无需指定他们详细的类. 三.包括的角色 (1)抽象工厂 (2)详细工厂:包含详细 ...
定义 抽象工厂类为创建一组相关和相互依赖的对象提供一组接口,而无需指定一个具体的类. 这里我得把工厂方法模式得定义拿出来做一下比较:定义一个创建对象的接口,由子类决定实例化哪一个类.工厂方法是一个 ...
一:简单工厂模式 1:描述:简单工厂模式是由一个工厂对象根据接收到的消息决定要创建哪一个类的对象事例. 2:优点:工厂类中有相关逻辑判断,可以根据需要动态创建相关的对象事例,而客户端只需要告诉工厂类创 ...
随机推荐
1.首先通过上图 locolhost:8080/login.html 访问到这个登录的html页 2 通过html页的 action="LoginServlet" 进行映射,所以填 ...
1. 安装subversion#yum -y install subversion2. 安装好了之后 新建一个svn目录#mkdir /home/svn3. 新建两个版本仓库#svnadmin cre ...
https://www.cnblogs.com/java-maowei/p/5950930.html
(1)新建threadGroup: (2)设置并发用户数量: (3) ...
Sales Document 原文:http://www.cnblogs.com/qiangsheng/archive/2008/03/13/1103294.html Data base docume ...
-Xms256M -Xmx512M -XX:PermSize=256m -XX:MaxPermSize=512m
Android中,主线程中的组件,不能被子线程调用,否则就会出现异常. 这里所使用的方法就是利用Handler类中的Callback(),接受线程中的Message类发来的消息,然后把所要在线程中执行 ...
# 安装 需要相关包# ==================================================================node1 node2 node3 yum ...
你是否正打算优化hashCode()方法?是否想要绕开正则表达式?Lukas Eder介绍了很多简单方便的性能优化小贴士以及扩展程序性能的技巧. 最近“全网域(Web Scale)”一词被炒得火热,人 ...
这篇笔记的只要知识点: (1)ls查看文件信息,列表中每个字符所代表的含义 (2) 使用通配符匹配文件 (3) chmod命令:修改文件或目录权限 (4) 与用户相关命令(who.su.exit.pa ...