当前位置: 首页 > news >正文

工厂模式~

现实世界中的例子

        考虑一个招聘经理的情况。一个人不可能为每一个职位都进行面试。根据职位空缺,她必须决定并将面试步骤委托给不同的人。

用简单的话来说

        它提供了一种将实例化逻辑委托给子类的方法。

维基百科的解释

        在基于类的编程中,工厂方法模式是一种创建型模式,它使用工厂方法来处理创建对象时无需指定将要创建对象的确切类的问题。这是通过调用工厂方法(在接口中指定并由子类实现,或者在基类中实现并由派生类可选地重写)来创建对象,而不是直接调用构造函数来实现的。

编程示例:

        以我们之前的招聘经理为例,首先定义了一个Interviewer接口以及它的几个实现类。

#include <iostream>
#include <memory>// 面试官接口
class Interviewer {
public:virtual void askQuestions() const = 0;virtual ~Interviewer() = default;
};// 开发人员类
class Developer : public Interviewer {
public:void askQuestions() const override {std::cout << "询问关于设计模式的问题!" << std::endl;}
};// 社区执行官类
class CommunityExecutive : public Interviewer {
public:void askQuestions() const override {std::cout << "询问关于社区建设的问题" << std::endl;}
};// 招聘经理抽象类
class HiringManager {
public:virtual ~HiringManager() = default;virtual std::unique_ptr<Interviewer> makeInterviewer() const = 0;void takeInterview() const {auto interviewer = makeInterviewer();interviewer->askQuestions();}
};// 开发经理类
class DevelopmentManager : public HiringManager {
public:std::unique_ptr<Interviewer> makeInterviewer() const override {return std::make_unique<Developer>();}
};// 市场经理类
class MarketingManager : public HiringManager {
public:std::unique_ptr<Interviewer> makeInterviewer() const override {return std::make_unique<CommunityExecutive>();}
};// 主函数演示功能
int main() {DevelopmentManager devManager;devManager.takeInterview(); // 输出: 询问关于设计模式的问题!MarketingManager marketingManager;marketingManager.takeInterview(); // 输出: 询问关于社区建设的问题。return 0;
}

Interviewer 接口

        首先,我们有一个 Interviewer 接口,所有的面试官类都必须实现这个接口。

class Interviewer {
public:virtual void askQuestions() const = 0; // 纯虚函数,子类必须实现virtual ~Interviewer() = default; // 虚析构函数,确保子类析构函数被正确调用
};

Developer 类和 CommunityExecutive 类

        这两个类实现了 Interviewer 接口。

class Developer : public Interviewer {
public:void askQuestions() const override {std::cout << "询问关于设计模式的问题!" << std::endl;}
};class CommunityExecutive : public Interviewer {
public:void askQuestions() const override {std::cout << "询问关于社区建设的问题" << std::endl;}
};

HiringManager 抽象类

        HiringManager 是一个抽象类,它包含了一个工厂方法 makeInterviewer,用于创建具体的面试官。它还包含一个 takeInterview 方法,该方法使用工厂方法创建的面试官来进行面试。

class HiringManager {
public:virtual ~HiringManager() = default; // 虚析构函数// 工厂方法,子类必须实现,用于创建面试官virtual std::unique_ptr<Interviewer> makeInterviewer() const = 0;// 进行面试,使用工厂方法创建的面试官void takeInterview() const {auto interviewer = makeInterviewer();interviewer->askQuestions();}
};

具体的 HiringManager 子类

        每个具体的招聘经理类(如 DevelopmentManager 和 MarketingManager)实现了 HiringManager 类的工厂方法,以创建特定类型的面试官。

class DevelopmentManager : public HiringManager {
public:std::unique_ptr<Interviewer> makeInterviewer() const override {return std::make_unique<Developer>(); // 返回开发人员面试官}
};class MarketingManager : public HiringManager {
public:std::unique_ptr<Interviewer> makeInterviewer() const override {return std::make_unique<CommunityExecutive>(); // 返回社区执行官面试官}
};

主函数

        在主函数中,我们创建了 DevelopmentManager 和 MarketingManager 的实例,并调用 takeInterview 方法,展示了不同的面试过程。

int main() {DevelopmentManager devManager;devManager.takeInterview(); // 输出: 询问关于设计模式的问题!MarketingManager marketingManager;marketingManager.takeInterview(); // 输出: 询问关于社区建设的问题。return 0;
}

类图:

关系说明

Interviewer 接口:

  • Interviewer 是一个接口,定义了 askQuestions 方法。
  • Developer 和 CommunityExecutive 类实现了 Interviewer 接口。

HiringManager 抽象类:

  • HiringManager 是一个抽象类,定义了工厂方法 makeInterviewer 和一个模板方法 takeInterview。
  • DevelopmentManager 和 MarketingManager 继承了 HiringManager 并实现了 makeInterviewer 方法。

工厂方法模式:

  • HiringManager 类的 makeInterviewer 方法是一个工厂方法,它的具体实现由子类 DevelopmentManager 和 MarketingManager 提供。
  • DevelopmentManager 的 makeInterviewer 方法返回 Developer 对象。
  • MarketingManager 的 makeInterviewer 方法返回 CommunityExecutive 对象。

何时使用:

        当类中包含一些通用处理逻辑,但所需的子类是在运行时动态决定的,或者换句话说,当客户端不知道它可能需要哪个具体的子类时,这种模式非常有用。通过定义一个抽象类或接口以及一个或多个工厂方法,可以允许子类在运行时决定实例化哪个类。这增加了代码的灵活性和可扩展性,因为新的子类可以在不修改现有代码的情况下被引入和使用。

        在上面的例子中,HiringManager类提供了一个通用的takeInterview方法,但具体的面试官(Interviewer)是在子类中通过makeInterviewer工厂方法动态决定的。这样,当需要添加新的面试官类型时,只需创建一个新的实现Interviewer接口的类,并在相应的招聘经理子类中重写makeInterviewer方法即可。

相关文章:

工厂模式~

现实世界中的例子 考虑一个招聘经理的情况。一个人不可能为每一个职位都进行面试。根据职位空缺&#xff0c;她必须决定并将面试步骤委托给不同的人。 用简单的话来说 它提供了一种将实例化逻辑委托给子类的方法。 维基百科的解释 在基于类的编程中&#xff0c;工厂方法模式是…...

Elasticsearch基本使用及介绍

Elasticsearch 1. 关于各种数据库的使用 关于MySQL&#xff1a;是关系型数据库&#xff0c;能清楚的表示数据之间的关系&#xff0c;并且&#xff0c;是基于磁盘存储的&#xff0c;可以使用相对较低的成本存储大量的数据 关于Redis&#xff1a;是基于K-V结构的在内存中读写数…...

10. PH47代码框架文件组织

通过之前章节对PH47体系的介绍&#xff0c;读者对PH47能建立起了初步的概念及掌握各主要构成部分的使用开发方法。从本章节开始&#xff0c;就将对PH47代码的二次开发内容进行具体讲述。 本部分就将对PH47框架当中代码文件的组织方式及功能作用进行介绍&#xff0c;对于将来熟…...

LabVIEW提高开发效率技巧----VI继承与重载

在LabVIEW开发中&#xff0c;继承和重载是面向对象编程&#xff08;OOP&#xff09;中的重要概念。通过合理运用继承与重载&#xff0c;不仅能提高代码的复用性和灵活性&#xff0c;还能减少开发时间和维护成本。下面从多个角度介绍如何在LabVIEW中使用继承和重载&#xff0c;并…...

4.8 大数据发展趋势

文章目录 今天&#xff0c;我想与大家探讨一个充满潜力和变革的主题——大数据的发展趋势。大数据不仅正在改变我们的工作和生活方式&#xff0c;更是推动社会进步和经济发展的关键因素。 首先&#xff0c;让我们看看国内的大数据发展趋势。中国政府高度重视大数据产业&#x…...

【无标题】react组件封装

子组件制作 import { useState,useRef, useEffect} from "react"const Table (data)> {const {value ,option} dataconsole.log(value)const [stata,setValue] useState()const useRefs useRef(value)useEffect(()> {useRefs.current.value value })c…...

git+cmake将Open3D配置到visual studio

这里假设你已经安装好了上述内容&#xff0c;我们直接开始安装&#xff1a; 第一步&#xff1a;以管理员身份打开powershell&#xff0c;执行 git clone https://github.com/isl-org/Open3D.git然后依次执行 cd Open3D mkdir build cd build开启你的梯子&#xff0c;并设置你…...

ArcGIS-CityEngine 2024-新手小白也能试用+入门可视化vga编程--第一篇

目录 下载CityEngine并创建空项目 场景双击 _Tour &#xff08;Navigator面板)的就行了&#xff0c;&#xff08;不用额外下载&#xff09; 生成街道 基本操作 多个图层Group 区分 Editor 多个区域&#xff08;插件模式&#xff0c;浮空窗口&#xff0c; 官方的例子&…...

IntelliJ IDEA 快捷键大全(也适用全家桶其他编辑器)

以下是 IntelliJ IDEA 的常用功能快捷键大全&#xff0c;适用于 Windows/Linux 系统&#xff08;Mac 用户可将 Ctrl 替换为 Cmd&#xff0c;Alt 替换为 Option&#xff09;&#xff1a; 功能分类功能描述快捷键 (Windows/Linux)基本操作显示所有快捷键Ctrl J显示主菜单Alt H…...

基于SSM高校普法系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;律师管理&#xff0c;法律知识管理&#xff0c;新闻类型管理&#xff0c;法律新闻&#xff0c;律师推荐管理 律师账号功能包括&#xff1a;系统首页&#xff0c;个人中心&#xf…...

CDN加速流程分享

我们有IP,我们需要用CDN的阿里云进行加速&#xff0c;让网站的视频显示的更加流畅 首先&#xff0c;我们面对的第一个问题就是把ip解析成域名的形式&#xff0c;我们这里的域名是 edu.senhacore.xyz 解释一下为什么要变成域名才行&#xff0c;因为国内要使用cdn就必须把ip转…...

全网爆火的排队免单模式究竟是如何运作?

在私域平台的探索过程中&#xff0c;许多企业主尝试了链动21、推三返一等裂变模式。虽然这些模式在某些情况下取得了显著成效&#xff0c;但也有不少企业反映难以推广。问题的核心在于客户的购买意愿不足&#xff0c;市场动力缺乏。仅仅依靠推广团队的积极裂变是不够的&#xf…...

Excel:vba实现批量修改文件名

原文件名&#xff1a;修改后的文件名&#xff1a; Sub test() 我这里只定义了一个cell,其余的我没有定义 Dim cell As Range清空 A 列中所有的内容,确保之前的数据不会影响到后续的操作 [a:a].Clear获取文件加的名字&#xff0c;这里的dir函数只返回一个文件名,即该文件下的第…...

【数据分享】中国历史学年鉴(1979-2001)

数据介绍 目录如下&#xff1a; 特稿 2000年国际历史科学大会 史学研究 史学理论 西周春秋战国史 秦汉史 魏晋南北朝史 隋唐五代史 宋史 辽西夏金史 蒙元史 明史 清史 晚清政治史 近代文化史 中外关系史 近代经济史 近代社会史 近代思想史 民国政治史 世…...

ubuntu系统启动wmplayer提示vmware unable to install all modules的处理方法

1. 终端中输入下面的命令查看vmplayer版本 vmplayer -v 2. git clone https://github.com/mkubecek/vmware-host-modules.git 3. cd vmware-host-modules 4. make 5. sudo make install...

数据库原理与应用(基于MySQL):实验六数据查询

实验6.1 对学生实验数据库(stuexpm)的学生信息表(StudentInfo)和成绩信息表(Scorelnfo)进行信息查询,编写和调试查询语句的代码,完成以下操作 (1)使用两种方式查询Studentlnfo表的所有记录 ①使用列名表。 ② 使用*. use stuexpm;select StudentID,Name,Sex,Birthday,Specia…...

【java面经thinking】二

目录 redis了解 使用原因 应用场景 数据类型 redis事务 数据持久化 RDB(快照)&#xff1a; AOF(即时更新)&#xff1a; 选择方式&#xff1a; redis快速的原因 redis单线程 单机瓶颈 经典3问 参考博客 redis了解 缓存中间件 使用原因 缓解高并发、提升高可用。…...

正规方程推导,详细版

推导正规方程&#xff08;Normal Equation&#xff09;通常是在线性回归的上下文中进行的。线性回归的目标是找到一个线性模型 h θ ( x ) θ T x h_\theta(x) \theta^T x hθ​(x)θTx&#xff0c;使得模型的预测值与实际值之间的差异&#xff08;通常是均方误差&#xff0…...

【原创】java+ssm+mysql在线文件管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…...

cocos Creator + fairyGUI 快速入门

版本 Creator 3.8.x&#xff0c;FairyGUI 2022 大部分内容来自 https://en.fairygui.com/docs/sdk/creator 1.新建cocos项目&#xff0c;根目录运行 npm install --save fairygui-cc 引入 fairyGUI库 2.assets目录之外新建fairyGUI项目 3.fairyGUI中编辑UI 完成后发布到Creato…...

UICollectionView 的UICollectionReusableView复用 IOS18报错问题记录

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath 方法复用报错 报错详情&#xff1a; Terminating app due to uncaught exception NSInternal…...

Ansible Roles与优化

Ansible Roles与优化 Ansible作为一款自动化运维工具&#xff0c;凭借其简洁的语法、强大的功能以及良好的扩展性&#xff0c;在IT运维领域得到了广泛应用。Ansible Roles作为Ansible的核心特性之一&#xff0c;为自动化部署和管理提供了极大的便利。本文将深入探讨Ansible Ro…...

Ubuntu 22.04上安装Miniconda

在Ubuntu 22.04上安装Miniconda&#xff0c;可以按照以下步骤进行&#xff1a; 步骤1&#xff1a;更新系统 首先&#xff0c;更新您的系统软件包&#xff1a; sudo apt update sudo apt upgrade -y步骤2&#xff1a;下载Miniconda安装脚本 访问Miniconda的官方网站或使用以下…...

【MySQL】入门篇—SQL基础:数据定义语言(DDL)

数据定义语言&#xff08;DDL&#xff0c;Data Definition Language&#xff09;是SQL&#xff08;结构化查询语言&#xff09;的一部分&#xff0c;主要用于定义和管理数据库的结构。 DDL允许用户创建、修改和删除数据库及其对象&#xff08;如表、索引、视图等&#xff09;。…...

电影评论网站开发:Spring Boot技术详解

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了电影评论网站的开发全过程。通过分析电影评论网站管理的不足&#xff0c;创建了一个计算机管理电影评论网站的方案。文章介绍了电影评论网站的系统分析部分&…...

20240817 全志 笔试

文章目录 1、选择题1.11.21.31.41.51.61.71.81.91.101.111.121.131.141.151.161.171.181.191.202、填空题2.12.23、问答题3.14、编程题4.14.2岗位:NO2510 嵌入式软件设计工程师(珠海/广州/西安/深圳) 题型:20 道选择题,2 道填空题,1 道问答题,2 道编程题 1、选择题 1.…...

laravel 查询数据库

数据库准备 插入 三行 不同的数据 自行搭建 laravel 工程 参考 工程创建点击此处 laravel 配置 数据库信息 DB_CONNECTIONmysql #连接什么数据库 DB_HOST127.0.0.1 # 连接 哪个电脑的 ip &#xff08;决定 电脑 本机&#xff09; DB_PORT3306 # 端口 DB_DATABASEyanyu…...

【Codeforces】CF 2009 F

Firefly’s Queries #前缀和 #数据结构 #数学 题目描述 Firefly is given an array a a a of length n n n. Let c i c_i ci​ denote the i i i’th cyclic shift ∗ ^{\text{∗}} ∗ of a a a. She creates a new array b b b such that b c 1 c 2 ⋯ c n b c…...

GTP4聊天记录中letax保存为word

​ 别的不说&#xff0c;GPT4用来看代码很是很爽的&#xff0c;可以让他直接恢复出函数中的数学公式&#xff0c;有的时候为了做笔记&#xff0c;GPT4回复的答案&#xff0c;复制出来使markdown、letax等格式&#xff0c;为了更好的记笔记&#xff0c;可以使用下面的工具将复制…...

vscode调试编译找不到gcc,只有cl,但是检查cmd是对的,控制面板的路径也更改了

&#x1f3c6;本文收录于《全栈Bug调优(实战版)》专栏&#xff0c;主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&am…...