《设计模式的艺术》笔记 - 工厂方法模式

介绍

        在简单工厂模式中,当系统中需要引入新的产品时,由于静态工厂方法通过所传入的参数的不同来创建不同的产品,这必定要修改工厂类的源代码,将违背开闭原则。因此,工厂方法模式应运而生。工厂方法模式是定义一个用于创建对象的接口,让子类决定将哪一个类实例化

实现

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class Product {
public:void methodSame();virtual void methodDiff() = 0;  // 抽象方法的声明,由具体产品实现
};class ConcreteProductA : public Product {
public:void methodDiff() override;
};class ConcreteProductB : public Product {
public:void methodDiff() override;
};class Factory {
public:virtual Product *createProduct() = 0;
};class ProductAFactory : public Factory {
public:Product *createProduct() override;
};class ProductBFactory : public Factory {
public:Product *createProduct() override;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"#include "myclass.h"void Product::methodSame() { // 公共方法的实现std::cout << "methodSame" << std::endl;
}void ConcreteProductA::methodDiff() {std::cout << "ConcreteProductA" << std::endl;
}void ConcreteProductB::methodDiff() {std::cout << "ConcreteProductB" << std::endl;
}Product *ProductAFactory::createProduct() {return new ConcreteProductA();
}Product *ProductBFactory::createProduct() {return new ConcreteProductB();
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {Factory *factory;Product *product;factory = new ProductAFactory();product = factory->createProduct();product->methodSame();product->methodDiff();delete factory;delete product;factory = new ProductBFactory();product = factory->createProduct();product->methodSame();product->methodDiff();delete factory;delete product;return 0;
}

重载工厂类方法

class Factory {
public:virtual Product *createProduct() = 0;virtual Product *createProduct(std::string opt);    // 新增
};

隐藏工厂类创建产品实例方法

class Factory {
public:virtual Product *createProduct() = 0;void methodDiff() {Product *product = this->createProduct();product->methodDiff();delete product;}
};

总结

        优点:

        1. 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节。用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。

        2. 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够让工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,正是因为所有的具体工厂类都具有同一抽象父类。

        3. 使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合开闭原则。

        缺点:

        1. 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。

        2. 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。

练习

        使用工厂方法模式设计一个程序来读取各种不同类型的图片格式,针对每种图片格式都设计一个图片读取器。例如,GIF图片读取器用于读取GIF格式的图片,JPG图片读取器用于读取JPG格式的图片。需充分考虑系统的灵活性和可扩展性。

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class Reader {
public:virtual void read(const std::string &file) = 0;
};class GIFReader : public Reader {
public:void read(const std::string &file) override;
};class JPGReader : public Reader {
public:void read(const std::string &file) override;
};class Factory {
private:virtual Reader *createReader() = 0;
public:void read(const std::string &file) {Reader *reader = this->createReader();reader->read(file);delete reader;}
};class GIFFactory : public Factory {
private:Reader *createReader() override;
};class JPGFactory : public Factory {
private:Reader *createReader() override;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"#include "myclass.h"void GIFReader::read(const std::string &file) {std::cout << "read GIF file: " << file << std::endl;
}void JPGReader::read(const std::string &file) {std::cout << "read JPG file: " << file << std::endl;
}Reader* GIFFactory::createReader() {return new GIFReader();
}Reader* JPGFactory::createReader() {return new JPGReader();
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {Factory *factory;factory = new GIFFactory();factory->read("file.gif");delete factory;factory = new JPGFactory();factory->read("file.jpg");delete factory;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/618047.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

超声波眼镜清洗机清洗眼镜会有伤害吗?适合洗眼镜超声波清洗机

眼镜作为日常生活中不可或缺的辅助视力工具&#xff0c;经常需要清洁保养以确保视力清晰和舒适佩戴。随着科技的发展&#xff0c;超声波眼镜清洗机成为越来越受欢迎的清洁方式。然而&#xff0c;很多人可能会担心使用超声波清洗机是否会对眼镜造成损害。但是可以很可以的告诉大…

【CMake报错解决】解决ITK和VTK版本不对应问题

ITKVTKGlue编译报错&#xff1a; CMake Error at C:/…/ITK/debug/lib/cmake/ITK-4.13/Modules/ITKVtkGlue.cmake:37 (vtk_module_config): Unknown CMake command “vtk_module_config”. 原因&#xff1a;ITK和VTK版本不对应导致找不到vtk_module_config文件&#xff0c;编译…

设计模式——原型模式(Prototype Pattern)

概述 原型模式(Prototype Pattern)&#xff1a;使用原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型创建新的对象。原型模式是一种对象创建型模式。原型模式的工作原理很简单&#xff1a;将一个原型对象传给那个要发动创建的对象&#xff0c;这个要发动创建的对象…

C1-3.4 多个样本的向量化

C1-3.4 多个样本的向量化 1、为什么要用样本的向量化呢&#xff1f; 总结一句话&#xff1a;计算方便 下图是神经网络计算的步骤&#xff0c;右侧 是有一个输入变量a[0]&#xff08;什么是X呢&#xff0c;因为输入层有三个神经元&#xff0c;说明有三个输入变量&#xff0c;…

15 个适用于 Windows 的 PDF 解锁工具大全

PDF&#xff08;便携式文件格式&#xff09;是一种文件格式&#xff0c;用于呈现和交换任何独立于任何软件、硬件或操作系统的可靠访问的文档。Adobe 发明了它&#xff0c;但现在它是由国际标准化组织 (ISO) 维护的开放标准。因此&#xff0c;您现在必须了解这些 PDF 解锁工具。…

Spring Boot项目中校验器的使用与注意事项

Spring Boot项目中校验器的使用与注意事项 Spring Boot为开发者提供了强大而灵活的校验机制&#xff0c;通过使用校验器&#xff08;Validator&#xff09;&#xff0c;我们能够在应用程序中方便地进行数据验证和错误处理。本文将深入介绍Spring Boot中校验器的使用方法&#…

go如何终止多个for select循环嵌套

空山新雨后&#xff0c;天气晚来秋。 目录 分类说明 总结 分类说明 for select循环嵌套&#xff0c;如何终止&#xff1f;上代码&#xff1a; stop : make(chan struct{})go func() {for i : 1; i < 3; i {fmt.Println("writed ", i)time.Sleep(time.Second * …

「HDLBits题解」Alwaysblock2

本专栏的目的是分享可以通过HDLBits仿真的Verilog代码 以提供参考 各位可同时参考我的代码和官方题解代码 或许会有所收益 题目链接&#xff1a;Alwaysblock2 - HDLBits // synthesis verilog_input_version verilog_2001 module top_module(input clk,input a,input b,output…

phpcms v9外链文章获取点击量

默认phpcms v9的外链文章因为直接跳转&#xff08;不进入详情页模板&#xff09;&#xff0c;导致外链文章的点击量一直是0&#xff0c;而我们有时需要按点击量排行或者排序的时候&#xff0c;就有问题了。 这里我们借助系统自带的点击量接口api来获取&#xff1a; 一、前台JS…

【随笔】遗传算法优化的BP神经网络(随笔,不是很详细)

文章目录 一、算法思想1.1 BP神经网络1.2 遗传算法1.3 遗传算法优化的BP神经网络 二、代码解读2.1 数据预处理2.2 GABP2.3 部分函数说明 一、算法思想 1.1 BP神经网络 BP神经网络&#xff08;Backpropagation Neural Network&#xff0c;反向传播神经网络&#xff09;是一种监…

Linux第21步_取消鼠标中键的复制粘贴功能

在ubuntu18.04操作系统中&#xff0c;选中文本后&#xff0c;若按下鼠标中键&#xff0c;就可以执行复制粘贴&#xff0c;相当于 CtrlshiftC 后又按了 CtrlshiftV。在Linux系统中&#xff0c;基本上都是这么配置的。在windows系统中&#xff0c;我们习惯用Ctrl-C复制&#xff0…

普通人想通过抖音赚钱要先知道这4点

1.变现方式 想做抖音首先要想好变现路径以及通过什么方式变现。做抖音就是在经营某一类人群&#xff0c;因为人群绑定了精准标签&#xff0c;系统推送的精准又绑定了变现。所以要明确你经营的目标人群是谁&#xff0c;你在做谁的生意&#xff0c;你要赚谁的钱。他们的年龄、收…

OpenCV-Python的版本介绍及区别

OpenCV-Python版本介绍 OpenCV-Python有多个版本&#xff0c;每个版本都有其特定的功能和改进。以下是一些常见OpenCV-Python版本及其介绍和区别&#xff1a; OpenCV-Python 2.x版本 这是OpenCV-Python的旧版本&#xff0c;支持Python 2.x。它包含了许多传统的计算机视觉功能&…

可盐可甜的红色马甲背心

膨体棉腈面料不易皱&#xff0c;搭配阿兰花菱形镂空设计 真的绝绝子&#xff0c;红色吸睛又美观 随便搭配一件衬衫去穿&#xff0c;自带文艺气息 氛围感直接拉满 出街拍照很出片&#xff0c;时髦又气质 女孩子的甜美&#xff0c;温柔等都可以突显 有喜欢的可以尝试一下哟…

超维空间M1无人机使用说明书——61、ROS无人机物体识别与精准投放

引言&#xff1a;基于空中物流的项目背景。我们提供了使用基于诗句的物体识别和精准投放、降落。实现原理如下&#xff1a; 1、在ROS下使用机载电脑实现物体识别 2、记载电脑根据反馈的位置发布运动控制指令 3、PX4解析机载电脑发布的命令&#xff0c;作出运动控制 4、设置…

将抖音视频转成MP3并下载

这篇是在上一篇的基础上写的&#xff0c;这篇负责抖音作者详情页的视频转声音提取&#xff0c;这篇需要用到后端。 本地启动后端后&#xff0c;在控制台输入对应代码&#xff0c;即可实现hover在封面上&#xff0c;按d一键下载音频 控制台代码 // 获取作者的视频列表var liEle…

【蓝桥备赛】特殊时间——时间日期类问题

题目链接 特殊时间 个人思路 枚举年份范围比较广&#xff0c;考虑略微复杂&#xff1b;枚举月日重点只要看月份需要枚举12个月&#xff1b;枚举时间有24小时。 综合起来看&#xff0c;枚举月日的讨论应该比较少。 详细分析看注释 参考代码 Java public class Main {publi…

LeetCode 2085. 统计出现过一次的公共字符串

目录 一、题目 1、题目描述 2、接口描述 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 C代码 ​Python3代码 一、题目 1、题目描述 给你两个字符串数组 words1 和 words2 &#xff0c;请你返回在两个字符串数组中 都恰好出现一次 的字符串的数目。 2…

我的创作纪念日(随便唠唠)

机缘 我在CSDN上面发表文章只是一时兴起&#xff0c;想着可以当作记录学习知识的一个笔记使用&#xff0c;并且我写的内容通常是我学习一段时间之后&#xff0c;经过了一段时间的沉淀&#xff08;这个时间通常是三个月到半年&#xff09;&#xff0c;觉得理解的够深刻之后才会…

思科无线AP 2802无法注册,手工指定控制器的IP

背景 Cisco AP 2802I Default username and password: Cisco Cisco 无法注册成功到wlc 5520上&#xff0c;AP上红灯一直闪烁。 Console连接AP&#xff0c;发现有获得Ip&#xff0c;但因为跨3层又没有dhcp option 43下发WLC IP&#xff0c;所以无法注册成功 。 获得IP地址&…