设计模式之工厂方法模式

2023-11-01

工厂方法模式

根据简单工厂模式的案例可知,如果我们想要添加一种立方运算,只需要创建一个立方运算类继承运算类,然后在工厂类中添加一个case分支用于逻辑判断,问题在于,我们在进行功能扩展的同时,也修改了工厂类中的代码,这很明显违背了开放-封闭原则,于是工厂方法模式应运而生。

UML类图:
在这里插入图片描述

工厂模式:定义一个创建对象的工厂类,为每一种需要创建对象的类创建一个相应的具体工厂类来继承该工厂类,如有A类,B类,C类,那我们就创建3个具体工厂类继承工厂类分别用于创建A类对象、B类对象和C类对象。在客户端,根据逻辑判断出我们需要创建什么对象,先创建相应的工厂对象,然后通过相应的工厂对象调用其中的成员函数创建我们需要的对象,比如我们想要创建A类对象,就需要先创建相应的A类工厂对象,然后通过A类工厂对象调用其成员函数创建出A类对象。

#include<iostream>
using namespace std;

class Base
{

};

class A:public Base
{

};

class B:public Base
{

};

//工厂类
class Factory
{
public:
	virtual Base* createConcrete() { return nullptr; };
};

//具体工厂类
class Afactory:public Factory
{
public:
	Base* createConcrete() override
	{
		cout << "A类对象被创建" << endl;
		return new A();
	}
};

class Bfactory:public Factory
{
public:
	Base* createConcrete()
	{
		cout << "B类对象被创建" << endl;
		return new B();
	}
};

int main()
{
	//依据逻辑判断需要创建A类对象
	//先创建相应的工厂对象
	//如果需要更换对象,即创建B类对象,只需要把Afactory更换为Bfactory即可
	Factory* factory = new Afactory();
	//然后通过工厂对象调用其成员函数创建我们需要的对象
	Base* base = factory->createConcrete();
}

这样,当我需要添加立方运算时,只需要添加一个立方运算类继承运算类,再添加一个相应的工厂类继承抽象工厂类,而无需对原有工厂类进行修改,这样就完全符合开放-封闭原则的精神。

在这里插入图片描述
但其实仔细观察就会发现,工厂模式把简单工厂内部的选择判断逻辑移到了客户端代码来进行,你想要增加功能,本来是改工厂类的,现在是要修改客户端。

优点:
工厂模式既克服了简单工厂模式违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点,使得要更换对象时,不需要大的改动就能实现,降低了客户端程序与产品对象的耦合。

缺点:

  • 每增加一个产品类,就需要增加一个相应的工厂类,增加了额外的开发量。
  • 将简单工厂模式中工厂类中要创建什么对象的逻辑判断移到了客户端程序,增加功能的时候需要修改客户端。

使用场景:

  • 首先,工厂方法模式是new一个对象的替代品,所以在所有需要生成对象的地方都可以使用,但是需要慎重地考虑是否要增加一个工厂类进行管理,增加代码的复杂度。
  • 其次,需要灵活的、可扩展的框架时,可以考虑采用工厂模式。万物皆对象,那万物也就皆产品类,例如需要设计一个连接邮件服务器的框架,有三种网络协议可供选择:POP3、IMAP、HTTP,我们就可以把这三种连接方法作为产品类,定义一个工厂类如IConnectMail,然后创建3个具体的工厂类继承工厂类用于创建3种产品类的对象,再按照不同的传入条件,创建不同的产品对象,选择不同的连接方式。如此设计,可以做到完美的扩展,如某些邮件服务器提供了WebService接口,很好,我们只要增加一个产品类和相应的工厂类就可以了。
  • 再次,工厂方法模式可以用在异构项目中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计模式之工厂方法模式 的相关文章

随机推荐

  • id 重启event_系统已在未先正常关机的情况下重新启动 事件ID:41

    创建日期 2018 07 18 系统已在未先正常关机的情况下重新启动 事件ID 41 日志名称 System 来源 Microsoft Windows Kernel Power 日期 2018 7 17 23 55 06 事件 ID 41
  • do...while(0)的妙用

    在C 中 有三种类型的循环语句 for while 和do while 但是在一般应用中作循环时 我们可能用for和while要多一些 do while相对不受重视 但是 最近在读我们项目的代码时 却发现了do while的一些十分聪明的用
  • Km Kcat Kcat/Km

    max 是指 最大反应速度 当 底物浓度 足够大时 体系中 酶的活性中心达到饱和状态 其反应速度达到最大 由此可见 最大反应速度 max 随 酶浓度的变化而变化 kcat 指反应常数 catalytic constant kcat 可以由
  • python爬取小说(二)书籍基本信息爬取

    爬完数据目录和内容后 我们来爬取书籍的基本信息 在上篇博客的基础上 爬取书籍信息并存入字典 coding utf 8 import urllib request import bs4 import re import sqlite3 def
  • SpringBoot项目使用docker-maven-plugin插件构建docker镜像以及推送到docker hub或docker registry私服

    我们知道docker可将应用程序和基础设施层隔离 可更快地打包 测试以及部署应用程序 本文主要介绍SpringBoot项目如何构建docker镜像以及推送到私服或者docker hub服务器上 本文介绍的方式是使用docker maven
  • JAVA 反射机制--reflection

    1 关于JAVAf 反射机制的一些基本的介绍参见好搜百科http baike haosou com doc 5458411 5696799 html或者搜索关键字 JAVAf 反射机制 2 这里总结下JAVAf 反射机制是如何运用的 或者说
  • Python零基础小白快速上手,不多废话

    Python零基础小白快速上手 Markdown编辑器和python安装 Markdown编辑器就是程序员常用的记事本 https img blog csdnimg cn 20201031151738673 png pic center 这
  • ElementUI中的 el-table 怎样格式化显示1和0为男和女

    场景 数据库中存储的是int型的1和0 从数据中取出来的也是1和0 怎样将其格式化为男和女 实现 table 表格
  • java list转换类型_java List数据转换为json类型数据

    list new ArrayList for int i 0 i lt carouselImageList size i CarouselImage a carouselImageList get i if a null a new Car
  • grafana使用

    1 面板 1 1 添加面板 add a new panel 增加一个新的统计图 add a new row 多个panel集合在一起 例如overview 1 2 Panel 2 PromQL查询语句 2 1 计算每一个样本的占比 饼图展示
  • 使用RBF(径向基函数)网络进行Python编程

    使用RBF 径向基函数 网络进行Python编程 径向基函数 RBF 网络是一种常用的神经网络模型 它在许多领域中都有广泛的应用 如模式识别 函数逼近和时间序列预测等 本文将介绍如何使用Python编程实现RBF网络 并提供相应的源代码 首
  • 详细使用sqlite3教程及打包资源

    包含编译好的unicode 多字节两种静态库 和sqlite3 h 还有我自己写的详细使用sqlite3的类 完整可用 实际项目我用过 有不对的地方还请大家批评指正 https download csdn net download qq 3
  • 推荐一款 IDEA 生成代码神器,写代码再也不用加班了

    Easycode是idea的一个插件 可以直接对数据的表生成entity controller service dao mapper 无需任何编码 简单而强大 1 安装 EasyCode 我这里的话是已经那装好了 建议大家在安装一个插件 叫
  • 2021年华为OD面试总结

    文章目录 写在前面 面试总体流程 简历筛选 线上机考 综合评测 业务面试 背景调查和HR面试 主管面试 写在前面 笔者211重点大学本科 毕业近5年 因为之前不是学python的 是近两年入了编程教培行业 所以慢慢接触到的python 然后
  • 《数据结构与算法》实验:查找结构的实验比较——二叉查找树BST & 二分(折半)查找

    数据结构与算法 实验和课程Github资源 数据结构与算法 实验 线性结构及其应用 算术表达式求值 数据结构与算法 实验 树型结构的建立与遍历 数据结构与算法 实验 图结构的建立与搜索 数据结构与算法 实验 查找结构的实验比较 二叉查找树B
  • 优化学习01-尽量不在循环里进行查询

    背景 BI项目 查询导购的等级 前端访问调接口太慢了 排查了其他sql 发现是自己把查询放在循环里的原因 错误示范 修改方案 最终的结果 List
  • 汽车市场勇进派 乐车邦林金文的逆周期生意

    汽车后市场一度是资本方疯狂下注的互联网创业领域 但越疯狂就可能越惨淡 林金文是那种特别务实的创业者 这与他创业前在汽车行业里的成长经验密不可分 也是乐车邦能够经历资本寒冬与车市衰退而挺立潮头的缘故 作者 严 睿 编辑 刘 煜 潮水退去才知道
  • 实现Parcelable的bean中有数组对象

    package com whu travel whu bean import android os Parcel import android os Parcelable Created by Fly on 2016 8 2 public
  • 带你快速实现扇形图?

    首先我们需要了解一个新的概念 conic gradient 圆锥形渐变 特性 圆锥渐变的起始点是图形中心 渐变方向以顺时针方向绕中心旋转实现渐变效果 兼容性 根据 can i use 目前只在chrome 69及以上支持 可以使用polyf
  • 设计模式之工厂方法模式

    工厂方法模式 根据简单工厂模式的案例可知 如果我们想要添加一种立方运算 只需要创建一个立方运算类继承运算类 然后在工厂类中添加一个case分支用于逻辑判断 问题在于 我们在进行功能扩展的同时 也修改了工厂类中的代码 这很明显违背了开放 封闭