一. 简单工厂

简单工厂模式(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之设计模式总结-简单工厂、工厂方法、抽象工厂、单例模式的更多相关文章

  1. 孤荷凌寒自学python第四十天python 的线程锁RLock

     孤荷凌寒自学python第四十天python的线程锁RLock (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 因为研究同时在多线程中读写同一个文本文件引发冲突,所以使用Lock锁尝试同步, ...

  2. 设计模式之工厂模式VS抽象工厂

    一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...

  3. 详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂) v阅读目录

    1楼留头头大神:http://www.cnblogs.com/toutou/p/4899388.html   v阅读目录 v写在前面 v简单工厂模式 v工厂方法模式 v抽象工厂模式 v博客总结 v博客 ...

  4. C# 设计模式(1)——简单工厂模式、工厂模式、抽象工厂模式

    1.前言 上一篇写了设计模式原则有助于我们开发程序的时候能写出高质量的代码(牵一发而不动全身),这个系列还是做个笔记温习一下各种设计模式,下面就看看简单工厂模式.工厂模式.抽象工厂模式. 2.简单工厂 ...

  5. Delphi 设计模式:《HeadFirst设计模式》Delphi代码---工厂模式之抽象工厂[转]

     1  2 {<HeadFirst设计模式>工厂模式之抽象工厂 }  3 { 抽象工厂的产品                       }  4 { 编译工具:Delphi7.0     ...

  6. [python实现设计模式]-3.简单工厂模式-触宝开放平台

    预备知识: 开放封闭原则(Open-Closed Principle OCP) Software entities(classes,modules,functions etc) should open ...

  7. 大话设计模式C++实现-第15章-抽象工厂模式

    一.UML图 二.概念 抽象方法模式(Abstract Factory):提供一个创建一系列相关或互相依赖对象的接口,而无需指定他们详细的类. 三.包括的角色 (1)抽象工厂 (2)详细工厂:包含详细 ...

  8. Java设计模式从精通到入门五 抽象工厂方法模式

    定义 抽象工厂类为创建一组相关和相互依赖的对象提供一组接口,而无需指定一个具体的类. ​ 这里我得把工厂方法模式得定义拿出来做一下比较:定义一个创建对象的接口,由子类决定实例化哪一个类.工厂方法是一个 ...

  9. C#设计模式——简单工厂模式、工厂模式和抽象工厂模式

    一:简单工厂模式 1:描述:简单工厂模式是由一个工厂对象根据接收到的消息决定要创建哪一个类的对象事例. 2:优点:工厂类中有相关逻辑判断,可以根据需要动态创建相关的对象事例,而客户端只需要告诉工厂类创 ...

随机推荐

  1. Git如何从github上pull别人的项目

    1:使用git方式导入项目 菜单-File->import->Git->Projects from Git 2:选择某个服务器上的资源 3:选择需要pull的地址 后面需要自己加上 ...

  2. HDU 1019 (多个数的最小公倍数)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1019 Least Common Multiple Time Limit: 2000/1000 MS (J ...

  3. oracle cascade用法

    原文地址:https://www.cnblogs.com/moyijian/p/9940323.html#4111551 级联删除,比如你删除某个表的时候后面加这个关键字,会在删除这个表的同时删除和该 ...

  4. 关于从Oracle数据库中删除表数据

    1,删除表 drop 1.1 执行drop table table_name  语句 被 drop后的表被放在用户回收站(user_recyclebin)里,而没有被直接删除掉,回收站里的表可以被恢复 ...

  5. iOS之safari调试iOS app web页面

    Overview 当下移动端开发过程中大量使用前段H5.js等等技术,而这些web页面的调试在Xcode控制台中不太明了,经常我们移动app运行了就是方法,但是不能显示响应的效果,这时候或许就是已经报 ...

  6. CF考古活动

    Codeforces Beta Round #1 http://codeforces.com/contest/1 A.测试用水题,呵呵.给三个数nma,求ceil(n/a)*ceil(m/a). 长整 ...

  7. 682. Baseball Game (5月28日)

    解答(打败98.60%) class Solution { public: int calPoints(vector<string>& ops) { vector<int&g ...

  8. ABAP术语-BAPI ExplorerSupertype

    Supertype 原文:http://www.cnblogs.com/qiangsheng/archive/2008/03/17/1109837.html Object type from whic ...

  9. easyui datagrid 异步加载数据时滚动条有时会自动滚到最底部的问题

    在使用easyui 的datagrid异步加载数据时发现滚动条有时会自动滚到最底部.经测试发现,如果加载数据前没有选中行则不会出现这个问题.这样我们可以在重新异步加载数据前取消选中行就可以避免这个问题 ...

  10. php 批量去除项目文件bom头

    <?php if (isset($_GET['dir'])) { //设置文件目录 $basedir = $_GET['dir']; } else { $basedir = '.'; } $au ...