python 工厂方法模式原理与实现

2023-05-16

一、简介

工厂模式是属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象的过程中不会向客户端暴露实现逻辑,而是通过一个共同的接口类来指向新创建的对象。

二、工厂方法模式的主要角色

  1. 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法newProduct()来创建产品。
  2. 具体工厂(ConcreteFactory):主要实现抽象工厂中的抽象方法,完成具体产品的创建。
  3. 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
  4. 具体产品(ConcreteProduct):实现了抽象产品定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

三、简单工厂模式

内容:不直接向客户端暴露对象创建实现的细节,而是通过工厂类来负责创建产品类的实例。

具体代码(jiandan.py):

from abc import ABCMeta, abstractmethod

class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self):
        pass

class WechatPay(Payment):
    def pay(self, money):
        print("微信支付%s" % money)
        return

class Alipay(Payment):
    def __init__(self, huabei=False):
        self.huabei = huabei
    def pay(self, money):
        if self.huabei:
            print("花呗支付%s" % money)
        else:
            print("支付宝余额支付%s" % money)

class PaymentFactory:
    def create_pay(self, method):
        if method == "wechat":
            return WechatPay()
        elif method == "alipay":
            return Alipay()
        elif method == "huabei":
            return Alipay(huabei=True)
        else:
            raise TypeError("No such payment name %s" % method)

# client
pf = PaymentFactory()
p = pf.create_pay("huabei")
p.pay(100)

结果:

ABCMeta是python的一个元类,用于在Python程序中创建抽象基类,抽象基类中声明的抽象方法,使用abstractmethod装饰器装饰。

简单明了的说:创建一个公共的抽象类,然后创建多个支付的类继承这个抽象类,各种支付类里实现具体的支付方式,通过工厂类选择支付方式,这样客服端只实现支付方式,不需要知道具体的实现方法。

优点:

  • 隐藏了对象创建的实现细节
  • 客户端不需要修改代码

缺点:

  • 违反了单一职责原则,将创建逻辑集中到一个工厂类里
  • 当添加新产品时,需要修改工厂类代码,违反了开闭原则

 四、工厂模式

内容:定义了一个用于创建对象的接口(工厂类),让工厂子类决定实例化哪一个产品类。

具体代码(factory_method.py):

from abc import ABCMeta, abstractmethod

class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self):
        pass

class WechatPay(Payment):
    def pay(self, money):
        print("微信支付%s" % money)
        return

class Alipay(Payment):
    def __init__(self, huabei=False):
        self.huabei = huabei
    def pay(self, money):
        if self.huabei:
            print("花呗支付%s" % money)
        else:
            print("支付宝余额支付%s" % money)

class PaymentFactory(metaclass=ABCMeta):
    @abstractmethod
    def create_method(self):
        pass

class AlipayFactory(PaymentFactory):
    def create_method(self):
        return Alipay()

class WechatFactory(PaymentFactory):
    def create_method(self):
        return WechatPay()

class HuabeiFactory(PaymentFactory):
    def create_method(self):
        return Alipay(huabei=True)

pf = HuabeiFactory()
p = pf.create_method()
p.pay(100)

结果:

五、抽象工厂模式

 内容:定义一个工厂类接口,让工厂子类来创建一系列相关或者相互依赖的对象。

与工厂模式相比,抽象工厂模式中的每一个产品都生产一套产品。

具体代码(abstract_factory.py):

from abc import ABCMeta, abstractmethod
"""
抽象产品
"""

class PhoneShell(metaclass=ABCMeta):
    @abstractmethod
    def show_shell(self):
        pass

class OS(metaclass=ABCMeta):
    @abstractmethod
    def show_os(self):
        pass

class CPU(metaclass=ABCMeta):
    @abstractmethod
    def show_cpu(self):
        pass

# 抽象工厂
class PhoneFactory(metaclass=ABCMeta):
    @abstractmethod
    def make_shell(self):
        pass
    @abstractmethod
    def make_cpu(self):
        pass
    @abstractmethod
    def make_os(self):
        pass

# 具体产品
class SmallShell(PhoneShell):
    def show_shell(self):
        print("普通手机壳小手机壳")

class BigShell(PhoneShell):
    def show_shell(self):
        print("普通手机壳大手机壳")

class AppleShell(PhoneShell):
    def show_shell(self):
        print("苹果手机壳")

class SnapDragonCPU(CPU):
    def show_cpu(self):
        print("骁龙CPU")

class MediaTekCPU(CPU):
    def show_cpu(self):
        print("联发科CPU")

class AppleCPU(CPU):
    def show_cpu(self):
        print("苹果CPU")

class AppleOS(OS):
    def show_os(self):
        print("苹果OS系统")

class AndroidOS(OS):
    def show_os(self):
        print("Android系统")

class IOS(OS):
    def show_os(self):
        print("IOS系统")

# 具体工厂
class MiFactory(PhoneFactory):
    def make_cpu(self):
        return SnapDragonCPU()
    def make_os(self):
        return AndroidOS()
    def make_shell(self):
        return BigShell()

class HuaweiFactory(PhoneFactory):
    def make_cpu(self):
        return MediaTekCPU()
    def make_os(self):
        return AndroidOS()
    def make_shell(self):
        return SmallShell()

class IPhoneFactory(PhoneFactory):
    def make_cpu(self):
        return AppleCPU()
    def make_os(self):
        return AppleOS()
    def make_shell(self):
        return AppleShell()

class Phone:
    def __init__(self, cpu, os, shell):
        self.cpu = cpu
        self.os = os
        self.shell = shell
    def show_info(self):
        print("手机信息:")
        self.cpu.show_cpu()
        self.os.show_os()
        self.shell.show_shell()

def make_phone(factory):
    cpu = factory.make_cpu()
    os = factory.make_os()
    shell = factory.make_shell()
    return Phone(cpu, os, shell)

p1 = make_phone(MiFactory())
p1.show_info()

结果:

优点:

  • 将客户端与类的具体实现相分离
  • 每个工厂创建了一个完整的产品系列,使得易于交换产品系列
  • 有利于产品的一致性(及产品之间的约束关系)

缺点:

  • 难以支持新种类的抽象产品

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python 工厂方法模式原理与实现 的相关文章

  • week13作业B TT的神秘任务2

    题目 xff1a 在你们的帮助下 xff0c TT 轻松地完成了上一个神秘任务 但是令人没有想到的是 xff0c 几天后 xff0c TT 再次遇到了那个神秘人 而这一次 xff0c 神秘人决定加大难度 xff0c 并许诺 TT xff0c
  • week14作业B Q老师与十字叉

    Input 9 5 5 3 4 4 3 5 5 1 4 5 5 5 3 3 3 4 4 Output 0 0 0 0 0 4 1 1 2 记录每一行 每一列空白的格子数目 xff0c 然后遍历每一个格子 xff0c
  • week14 作业D Q老师染砖

    衣食无忧的 Q老师 有一天突发奇想 xff0c 想要去感受一下劳动人民的艰苦生活 具体工作是这样的 xff0c 有 N 块砖排成一排染色 xff0c 每一块砖需要涂上红 蓝 绿 黄这 4 种颜色中的其中 1 种 且当这 N 块砖中红色和绿色
  • 用队列实现图的拓扑排序

    span class hljs preprocessor include lt stdio h gt span span class hljs preprocessor include lt stdlib h gt span span cl
  • week14作业E Q老师度假

    忙碌了一个学期的 Q老师 决定奖励自己 N 天假期 假期中不同的穿衣方式会有不同的快乐值 已知 Q老师 一共有 M 件衬衫 xff0c 且如果昨天穿的是衬衫 A xff0c 今天穿的是衬衫 B xff0c 则 Q老师 今天可以获得 f A
  • week15作业A ZJM 与霍格沃兹

    ZJM 为了准备霍格沃兹的期末考试 xff0c 决心背魔咒词典 xff0c 一举拿下咒语翻译题 题库格式 xff1a 魔咒 对应功能 背完题库后 xff0c ZJM 开始刷题 xff0c 现共有 N 道题 xff0c 每道题给出一个字符串
  • week16 实验A TT数鸭子

    题目 xff1a 这一天 xff0c TT因为疫情在家憋得难受 xff0c 在云吸猫一小时后 xff0c TT决定去附近自家的山头游玩 TT来到一个小湖边 xff0c 看到了许多在湖边嬉戏的鸭子 xff0c TT顿生羡慕 此时他发现每一只鸭
  • group by分组查询后排序

    group by分组查询后排序 如 xff1a 分组查询 SELECT s name name COUNT s id value FROM t setmeal s t order o WHERE s id 61 o setmeal id G
  • 数据库的视图

    数据库视图的作用 数据库视图是一种虚拟的表 xff0c 它不是一个实际的表 xff0c 而是根据一个或多个实际表的查询结果生成的一个虚拟表 xff0c 它可以看作是对一个或多个表的一个或多个列的子集的逻辑表示 在数据库中 xff0c 视图有
  • Ubuntu开启FTP服务+FileZilla传输文件

    1 Ubuntu安装 FTP 服务 sudo apt install vsftpd 2 本地 写入权限使能 xff0c 首先打开 etc vsftpd conf 进行配置 sudo vim etc vsftpd conf 配置文件中 loc
  • spring集成Junit单元测试出现的问题及解决办法

    spring集成Junit单元测试出现的问题及解决办法 1 在spring集成Junit单元测试的时候 xff0c 所有的集成步骤都没有问题 xff0c 但是在启动测试的时候出现如下问题 xff1a java lang IllegalSta
  • MySQL实验

    表如下 xff1a 学院 xff08 学院代码 xff0c 学院名称 xff09 学生 xff08 学号 xff0c 姓名 xff0c 性别 xff0c 学院代码 xff09 教师 xff08 教师号 xff0c 教师名 xff0c 学院代
  • SpringBoot整合Mybatis-plus代码生成器

    本文还是采用经典实用知识三段论 是什么 xff1f 能干什么 xff1f 怎么干 xff1f 让Mybatis plus代码生成器轻而易举的为你所用 希望文章能够帮到你提高写代码的效率 前言 整合基于在idea已经创建好的Springboo
  • 定义struct结构体数组

    题目要求 xff1a 有3个候选人 xff0c 每个选民只能投票选一人 xff0c 要求编一个统计选票的程序 xff0c 先后输入被选人的名字 xff0c 最后输出各人得票结果 解题思路 xff1a 设一个结构体数组 xff0c 数组中包含
  • AAC高级音频编码

    AAC 的支持现状 目前支持 AAC 的产品还比较少 xff0c 这主要是因为专利使用费大大限制了 AAC 的发展 xff01 不过好在有索尼 诺基亚 苹果 松下四大巨头的鼎力支持 xff0c 场面还不算冷清 重量级的 iPod 和 iPo
  • 三种做法——判断给定的字符序列是否是回文,回文是指一个字符序列以中间字符为基础,两边字符忽略大小写完全相同

    判断给定的字符序列是否是回文 xff0c 回文是指一个字符序列以中间字符为基础 xff0c 两边字符忽略大小写完全相同 xff08 10分 xff09 判断回文多种方法 xff1a 不值得推荐方法 xff1a 纯死脑筋做法 span cla
  • word文件转md文件

    文章目录 一 下载pandoc二 pandoc转换1 cmd进入文件夹2 代码实现 一 下载pandoc 建议使用msi直接安装 xff0c 而不是下载安装包直接使用 xff0c msi的下载方法 xff1a 安装方法 二 pandoc转换
  • JavaScript中定义结构体一维二维多维数组

    相信学过C语言的开发者刚接触JavaScript时都会很不习惯 xff0c C语言中的虽然是结构化面向过程的编程语言 xff0c 但是C语言中也有封装的思想 xff0c 例如C语言结构体和公用体等 xff0c 在他们中都可以直接定义变量 C
  • does not name a type报错的改正方式

    does not name a type报错的改正方式 原代码如下 xff1a 报错 xff1a does not name a type 原因 xff1a 不知道 改正方法 xff1a 把初始化放主函数外面 xff0c 赋值放主函数里面
  • ERROR: Cause: unable to find valid certification path to requested target终极解决方法

    ERROR Cause unable to find valid certification path to requested target终极解决方法 2022 09 20 更新一下 xff1a 报这个错主要是因为网络问题 xff0c

随机推荐

  • yum安装ansible报错如何解决

    yum安装ansible报错解决方案 一 报错信息 xff1a 二 如何解决1 重装虚拟机2 修改yum源3 使用EPEL源4 安装ansible5 测试 文章参考 xff1a https mirrors tuna tsinghua edu
  • FORTRAN基础编程(1)——基本格式及读入输出

    FORTRAN基础编程 xff08 1 xff09 基本格式及输出 读入 文章目录 FORTRAN基础编程 xff08 1 xff09 基本格式及输出 读入书面格式一 Fixed Format 固定格式 二 Free Format 自由格式
  • Anaconda3-2022.05安装与环境配置

    文章目录 1 Anaconda下载方式一 xff1a Anacoda官网下载方式二 xff1a 国内镜像下载 2 Anaconda安装3 Anaconda环境变量配置4 测试是否配置成功 1 Anaconda下载 方式一 xff1a Ana
  • 解题笔记——救援

    解题笔记 救援 救生船从大本营出发 xff0c 营救若干屋顶上的人回到大本营 xff0c 屋顶数目以及每个屋顶的坐标和人数都将由输入决定 xff0c 求出所有人都到达大本营并登陆所用的时间 在直角坐标系的原点是大本营 xff0c 救生船每次
  • 【千奇百怪】java自定义spotbugs检测器

    前两天 xff0c 在对一个代码质量检测平台维护的时候 xff0c 遇到了一个新添加指定规则集的需求 xff0c 在经过一番折腾后否定掉了基于 ANTLR 实现自定义规则 xff1b 基于 CheckStyle 实现自定义规则 xff1b
  • win10深度学习环境配置

    nvidia驱动以及cuda的安装与卸载 下载cuda和对应的cudnn nvidia官网 直接在搜索栏搜索想要下载的版本 xff0c cuda11 x和cudnn11 x 首先安装cuda 安装cuda会自动安装相对应的显卡驱动 xff0
  • 【CCF-CSP】201312-1 出现次数最多的数 C++

    文章目录 一 题目二 解题1 题目解释1 出现次数最多的数2 如果这样的数有多个 xff0c 请输出其中最小的一个 2 代码3 提交结果 三 总结1 代码思路 xff1a 2 其他 一 题目 题目原始链接 xff1a http 118 19
  • 【CCF-CSP】201403-1 相反数 C++

    文章目录 一 题目二 使用步骤1 解题2 代码3 提交结果 总结1 代码思路2 其他 一 题目 原题目链接 二 使用步骤 1 解题 求相反数的队数 xff0c 可以利用相反数的绝对值相等的思路来解题 2 代码 dev c 43 43 5 1
  • 【CCF-CSP】201409-4 最优配餐 C++

    文章目录 一 题目二 解题1 题目2 代码3 提交结果 总结1 代码思路 一 题目 原题目链接 二 解题 1 题目 一个BFS xff08 宽度优先搜索 xff09 的实现 xff0c 用于处理迷宫中的节点 下面是代码的详细解释 xff1a
  • 【CCF-CSP】201412-2 Z字形扫描 C++

    文章目录 一 题目二 解题1 核心2 代码3 提交结果 总结 一 题目 原题目链接 二 解题 1 核心 一个关于矩阵的遍历输出算法 具体来说 xff0c 输出的是一个n n的矩阵z中的所有元素 内层循环的意思是 xff1a 在外层循环中确定
  • 【CCF-CSP】 201604-4 游戏

    文章目录 一 题目二 解题1 题目2 代码3 提交结果 总结1 注意边界 一 题目 原题目链接 二 解题 1 题目 类似于迷宫问题 xff0c 假设有一个n行m列的矩阵 xff0c 其中的一些格子是障碍物 xff0c 机器人从 xff08
  • 碰撞的小球 201803-2 C++

    文章目录 一 题目二 解题1 题目2 代码3 提交结果 总结1 解释 一 题目 原题目链接 二 解题 1 题目 这段代码通过模拟小球在一维轴上的运动来解决碰撞小球问题 它读入小球的数量 n xff0c 轴的长度 L 和运动的时间 t xff
  • 风险人群筛查 202009-2 C++

    文章目录 一 题目二 解题1 题目2 代码3 提交结果 总结1 解释 一 题目 原题目链接 二 解题 1 题目 这个程序解决了一个计数问题 它读取一些输入值 xff0c 包括n k t xl yd xr和yu 其中 xff0c n表示人数
  • 如此编码 202209-1 C++

    文章目录 一 题目二 解题1 题目2 代码3 提交结果 总结1 解释2 其他 一 题目 原题目链接 二 解题 1 题目 根据题目的提示 xff0c 我们已经知道m xff0c 需要求解的是b 那我们先求解c xff0c 然后再求解b 2 代
  • 期末预测之最佳阈值(类似前缀和的思想)

    题目 见https blog csdn net qq 45985728 article details 114903481 思路 我对此题没什么太好的思路 大概就只有暴力枚举混个70分吧 具体思路还是见上面的题目网址 代码 span cla
  • 阿里云服务器建站教程(从0到1)

    购买了阿里云服务器后 xff0c 需要一系列的配置 设置密码 首先 xff0c 点击右上角的 控制台 在左边找到 云服务器ESC xff0c 点击 可以看到有你刚刚购买的服务器 xff0c 点击进去 进入之后 xff0c 点击 更多 xff
  • 阿里云服务器建站教程

    第一步 xff1a 阿里云域名购买 需要到阿里云购买域名 xff1a 域名特惠专场 第二步 xff1a IPC备案 自行下载阿里云app进行IPC备案 xff0c 因为需要进行人脸验证 第三步 xff1a 购买服务器 购买服务器 xff1a
  • 树莓派3B+远程连接被拒或超时亦或屏幕无反应的登录方式

    报了一个大学生创新创业比赛 xff0c 计划做一个基于视觉识别的切菜机械臂 xff0c 毫无头绪 xff0c 于是先学树莓派吧 xff0c 入手3B 43 有一段时间了 xff0c 为了节约成本没有买屏幕 xff0c 几天后发现最大的问题就
  • 最大矩形(题解)

    题意 xff1a 给一个直方图 xff0c 求直方图中的最大矩形的面积 例如 xff0c 下面这个图片中直方图的高度从左到右分别是2 1 4 5 1 3 3 他们的宽都是1 xff0c 其中最大的矩形是阴影部分 思路 xff1a 对于每个高
  • python 工厂方法模式原理与实现

    一 简介 工厂模式是属于创建型模式 xff0c 它提供了一种创建对象的最佳方式 在工厂模式中 xff0c 我们在创建对象的过程中不会向客户端暴露实现逻辑 xff0c 而是通过一个共同的接口类来指向新创建的对象 二 工厂方法模式的主要角色 抽