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

《设计模式的艺术》笔记 - 抽象工厂模式

介绍

        提供了一个创建一系列相关或相互依赖的对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。

        在抽象工厂模式中,每个具体工厂都提供了多个工厂方法用于产生多种不同类型的产品,这些产品构成了一个产品族。

实现

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class AbstractProductA {};class AbstractProductB {};class ConcreteProductA : public AbstractProductA {
public:ConcreteProductA();
};class ConcreteProductB : public AbstractProductB {
public:ConcreteProductB();
};class AbstractFactory {
public:virtual AbstractProductA *createProductA() = 0;virtual AbstractProductB *createProductB() = 0;
};class ConcreteFactory1 : public AbstractFactory {
public:AbstractProductA *createProductA() override;AbstractProductB *createProductB() override;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"#include "myclass.h"ConcreteProductA::ConcreteProductA() {std::cout << "产品A" << std::endl;
}ConcreteProductB::ConcreteProductB() {std::cout << "产品B" << std::endl;
}AbstractProductA* ConcreteFactory1::createProductA() {std::cout << "工厂1生产了: ";return new ConcreteProductA();
}AbstractProductB* ConcreteFactory1::createProductB() {std::cout << "工厂1生产了: ";return new ConcreteProductB();
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {AbstractFactory *factory = new ConcreteFactory1();auto a = factory->createProductA();auto b = factory->createProductB();delete factory;delete a;delete b;return 0;
}

总结

        优点:

        1. 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了在抽象工厂中声明的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。

        2. 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。

        3. 增加新的产品族很方便,无须修改已有系统,符合开闭原则。

        缺点:

        1. 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了开闭原则。

        使用场景:

        1. 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是很重要的,用户无须关心对象的创建过程,将对象的创建和使用解耦。

        2. 系统中有多于一个的产品族,而每次只使用其中某一个产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。

        3. 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。同一个产品族中的产品可以是没有任何关系的对象,但是它们都具有一些共同的约束。例如同一操作系统下的按钮和文本框,按钮与文本框之间没有直接关系,但它们都是属于某一操作系统的,此时具有一个共同的约束条件:操作系统的类型。

        4. 产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。

练习

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class Controller {  // 抽象产品};class AndroidOperationController : public Controller { // 具体产品
public:AndroidOperationController();
};class AndroidInterfaceController : public Controller { // 具体产品
public:AndroidInterfaceController();
};class IOSOperationController : public Controller { // 具体产品
public:IOSOperationController();
};class IOSInterfaceController : public Controller { // 具体产品
public:IOSInterfaceController();
};class ControllerFactory { // 抽象工厂
public:virtual Controller *createOperation() = 0;virtual Controller *createInterface() = 0;
};class AndroidControllerFactory : public ControllerFactory {
public:Controller *createOperation() override;Controller *createInterface() override;
};class IOSControllerFactory : public ControllerFactory {
public:Controller *createOperation() override;Controller *createInterface() override;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"#include "myclass.h"AndroidOperationController::AndroidOperationController() {std::cout << "Android系统游戏操作控制" << std::endl;
}AndroidInterfaceController::AndroidInterfaceController() {std::cout << "Android系统游戏界面控制" << std::endl;
}IOSOperationController::IOSOperationController() {std::cout << "ios系统游戏操作控制" << std::endl;
}IOSInterfaceController::IOSInterfaceController() {std::cout << "ios系统游戏界面控制" << std::endl;
}Controller* AndroidControllerFactory::createOperation() {return new AndroidOperationController();
}Controller* AndroidControllerFactory::createInterface() {return new AndroidInterfaceController();
}Controller* IOSControllerFactory::createOperation() {return new IOSOperationController();
}Controller* IOSControllerFactory::createInterface() {return new IOSInterfaceController();
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {ControllerFactory *factory;Controller *op, *in;factory = new AndroidControllerFactory();op = factory->createOperation();in = factory->createInterface();delete factory;delete op;delete in;factory = new IOSControllerFactory();op = factory->createOperation();in = factory->createInterface();delete factory;delete op;delete in;return 0;
}

相关文章:

《设计模式的艺术》笔记 - 抽象工厂模式

介绍 提供了一个创建一系列相关或相互依赖的对象的接口&#xff0c;而无须指定它们具体的类。抽象工厂模式又称为Kit模式&#xff0c;它是一种对象创建型模式。 在抽象工厂模式中&#xff0c;每个具体工厂都提供了多个工厂方法用于产生多种不同类型的产品&#xff0c;这些产品构…...

7.11、Kali Linux中文版虚拟机安装运行教程

目录 一、资源下载准备工作 二、安装教程 三、kali linux换源 四、apt-get update 报错 一、资源下载准备工作 linux 中文版镜像历史版本下载:http://old.kali.org/kali-images/ 大家可以自行选择版本下载&#xff0c;本人下载的是2021版本 二、安装教程 打开vmvare wokst…...

Go+快速开始详细指南

Go快速开始 Go编程语言是为工程、STEM教育和数据科学设计的。 对于工程:用儿童能掌握的最简单的语言工作。对于STEM教育:学习一门可以在未来工作中使用的工程语言。对于数据科学:用同一种语言与工程师交流。 安装方法 现在&#xff0c;我们建议您从源代码安装Go。 注意:需…...

SQL:一行中存在任一指标就显示出来

当想要统计的两个指标不在一张表中时&#xff0c;需要做关联。但很多情况下&#xff0c;也没有办法保证其中一张表的维度是全的&#xff0c;用left join或right join可能会导致数据丢失。所以借助full join处理。 1&#xff09;如&#xff0c;将下面的数据处理成表格中的效果&…...

【代码随想录06】454. 四数相加 II 383. 赎金信 15. 三数之和 18. 四数之和

目录 454. 四数相加 II题目描述做题思路参考代码 383. 赎金信题目描述做题思路参考代码 15. 三数之和题目描述参考代码 18. 四数之和题目描述参考代码 454. 四数相加 II 题目描述 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你…...

NodeJs 第十五章 session

Session代表服务器和客户端一次会话的过程。 在计算机科学领域来说&#xff0c;尤其是在网络领域&#xff0c;会话(session)是一种持久网络协议&#xff0c;在用户(或用户代理)端和服务器端之间创建关联&#xff0c;从而起到交换数据包的作用机制&#xff0c;session在网络协议…...

JRTP实时音视频传输(1)-必做的环境搭建与demo测试

1.需求 1&#xff09;支持协议自动切换。在网络优的情况下使用TCP、网络差的情况下使用UDP&#xff0c;满足实时音视频传输需求&#xff0c; 2&#xff09;支持RTCP &#xff0c;流量控制&#xff0c;阻塞控制等。需要能支持RTCP&#xff0c;这样便能在这个基础上&#xff0c;…...

腿部臀部训练

坐式蹬腿器 100kg&#xff0c;是器械的极限了&#xff0c;也差不多是我的极限&#xff0c;深蹲是40kg&#xff0c;应该还可以加点&#xff0c;大腿外扩器55kg&#xff0c;没有尝试能不能做更重的&#xff0c;羡慕健身房里面的好身材的同学&#xff0c;自己得好好练 1.21健身房关…...

windows系统下docker软件中使用ubuntu发行版本的linux系统

1.软件下载 官网下载地址 下载安装之后&#xff0c;再去微软商店下载wsl软件&#xff0c;可以直接用&#xff0c;或者也可以使用命令行拉取&#xff08;下面会讲&#xff09; 2.在docker里面创建容器的两种方法 2.1.命令行创建 前言&#xff1a;输入 winr 打开命令行进行下面…...

vue实现小球掉落

首先&#xff0c;将小球儿动画代码封装成组件&#xff0c;创建个文件&#xff0c;例如qiu.js let createBall (left, top,box) > {// 点击事件 const {clientX,clienty} ev createBall(clientX,clienty)const ball document.createElement(div);ball.style.position a…...

k8s的存储卷、数据卷---动态PV创建

当发布PVC之后可以生成PV&#xff0c;还可以在动态服务器上直接生成挂载目录。PVC直接绑定和使用PV。 动态PV需要两个组件 存储卷插件&#xff1a;Provisioner(存储分配器)根据定义的属性创建PV StorageClass&#xff1a;定义属性 存储卷插件 存储卷插件&#xff1a;k8s本…...

go最佳实践:如何舒适地编码

什么是 "最佳 "做法&#xff1f; 有很多做法&#xff1a;你可以自己想出来&#xff0c;在互联网上找到&#xff0c;或者从其他语言中拿来&#xff0c;但由于其主观性&#xff0c;并不总是容易说哪一个比另一个好。”最佳”的含义因人而异&#xff0c;也取决于其背景…...

C# 消息队列、多线程、回滚、并行编程、异步编程、反射

消息队列 消息队列是一种在应用程序之间传递消息的异步通信机制。它可以使应用程序解耦并提高系统的可伸缩性和可靠性。在 C# 中&#xff0c;你可以使用多个消息队列技术&#xff0c;其中一种广泛使用的技术是 RabbitMQ。 RabbitMQ 是一个开源的消息代理&#xff0c;实现了高…...

汇编代码生成和编译器的后端

1.前置程序&#xff1a;语义分析和中间代码生成 基于SLR(1)分析的语义分析及中间代码生成程序-CSDN博客https://blog.csdn.net/lijj0304/article/details/135097554?spm1001.2014.3001.5501 2.程序目标 在前面编译器前端实现的基础上&#xff0c;将所生成的中间代码翻译成某…...

MySQL 8.0中新增的功能(九)

FROM_UNIXTIME()、UNIX_TIMESTAMP()和CONVERT_TZ()的64位支持 根据MySQL 8.0.28版本的更新&#xff0c;FROM_UNIXTIME()、UNIX_TIMESTAMP() 和 CONVERT_TZ() 函数现在在支持64位的平台上处理64位值。这包括64位版本的Linux、MacOS和Windows。在兼容的平台上&#xff0c;UNIX_T…...

QT基础篇(8)QT5模型视图结构

1.概述 QT5的模型视图结构主要包括模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和委托&#xff08;Delegate&#xff09;三个部分。 模型&#xff08;Model&#xff09;&#xff1a;模型是数据的抽象表示&#xff0c;负责存储和管理数据。它可以是自…...

vue3-响应式基础之reactive

reactive() 还有另一种声明响应式状态的方式&#xff0c;即使用 reactive() API。与将内部值包装在特殊对象中的 ref 不同&#xff0c;reactive() 将使对象本身具有响应性&#xff1a; 「点击按钮1」 <script lang"ts" setup> import { reactive } from vuec…...

【ceph】如何将osd的内容挂载出来---ceph-objectstore-tool 实现

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…...

怎样实现安全便捷的网间数据安全交换?

数据安全交换是指在数据传输过程中采取一系列措施来保护数据的完整性、机密性和可用性。网间数据安全交换&#xff0c;则是需要进行跨网络、跨网段甚至跨组织地进行数据交互&#xff0c;对于数据的传输要求会更高。 大部分企业都是通过网闸、DMZ区、VLAN、双网云桌面等方式实现…...

微信小程序定义并获取日志/实时log信息

步骤一&#xff1a;开通实时日志 可以在开发者工具->详情->性能质量->实时日志&#xff0c;点击前往&#xff0c;在浏览器打开we分析界面&#xff1a; 也可登录小程序管理后台&#xff0c;点击统计进入we分析&#xff1a; 在we分析界面找到性能质量&#xff0c;打开实…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...