3.抽象工厂模式

news2024/9/27 7:27:03

与工厂模式对比

工厂模式

工厂模式是类创建模式。在工厂模式中,只需要生产同一种产品,只不过是生产厂家不同。

所以产品类的设计:

  • 抽象的产品类Product
  • 具体的产品类Product_AProduct_B, Product_C, Product_D……

工厂的设计:

  • 抽象的工厂Factory
  • 与产品对应的Factory_A, Factory_B, Factory_C, Factory_D……

特点是每增加一个厂家,就会成对地增加类。
不考虑增加产品种类,否则就会升级为抽象工厂模式。

抽象工厂模式

抽象工厂模式是对象创建模式。抽象工厂模式中,每个厂家都生产多种产品

反映到我们的工厂类,就是需要提供更多的产品制造接口。

优点

每增加一个厂家,就要有一个具体的工厂类产生、多个具体的产品类产生。
只需让具体的工厂继承Factory抽象的工厂、具体的产品继承抽象的产品、具体的工厂负责制造具体的产品。对其他类没有影响。

缺点/限制

当增加一种新的产品时(不推荐),每个已有的工厂都需要增加新的方法,来制造对应的产品,违背了开闭原则。

产品已有的种类是固定的,而品阶/等级/厂商可以变。

有时这也算是个优点,因为将每个工厂的产品视为一套产品,这很符合一些应用场合。
例如对不同的操作系统提供一套UI组件,对不同操作系统使用不同的具体工厂来产生一套组件。

又比如在数据相关类的设计中,有不同的数据库,不同的数据库会给出不同的连接类、语句类。数据库就像具体的工厂,连接类、语句类则是产品。不同的数据库自成一套。

类图

下面的例子模拟不同的文具工厂生产各种文具,
假设厂家有:爱好,晨光……
假设文具有:书、铅笔、尺子……

在这里插入图片描述

代码

#include <iostream>
#include <memory>
#include <vector>

using namespace std;


class Book;
class AiHaoBook;
class ChenGuangBook;

class Pencil;
class AiHaoPencil;
class ChenGuangPencil;

class Ruler;
class AiHaoRuler;
class ChenGuangRuler;

class Factory;
class ChenGuangFactory;
class AiHaoFactory;

class Factory {
public:
	virtual ~Factory() = default;
	virtual unique_ptr<Book> make_book() = 0;
	virtual unique_ptr<Pencil> make_pencil() = 0;
	virtual unique_ptr<Ruler> make_ruler() = 0;
};

class AiHaoFactory : public Factory {
public:
	unique_ptr<Book> make_book() override;
	unique_ptr<Pencil> make_pencil() override;
	unique_ptr<Ruler> make_ruler() override;
};

class ChenGuangFactory : public Factory {
public:
	unique_ptr<Book> make_book() override;
	unique_ptr<Pencil> make_pencil() override;
	unique_ptr<Ruler> make_ruler() override;
};

class Book {
public:
	virtual ~Book() = default;
	virtual string get_brand() const = 0;
	string get_type() const;
private:
	static const string type;
};

class Pencil {
public:
	virtual ~Pencil() = default;
	virtual string get_brand() const = 0;
	string get_type() const;
private:
	static const string type;
};

class Ruler {
public:
	virtual ~Ruler() = default;
	virtual string get_brand() const = 0;
	string get_type() const;
private:
	static const string type;
};

const string Book::type ("Book");
const string Pencil::type ("Pencil");
const string Ruler::type ("Ruler");

string
Book::get_type() const
{
	return Book::type;
}

string
Pencil::get_type() const
{
	return Pencil::type;
}

string
Ruler::get_type() const
{
	return Ruler::type;
}

class AiHaoBook: public Book {
public:
	string get_brand() const override;
private:
	static const string brand;
};

class AiHaoPencil : public Pencil {
public:
	string get_brand() const override;
private:
	static const string brand;
};

class AiHaoRuler : public Ruler {
public:
	string get_brand() const override;
private:
	static const string brand;
};

class ChenGuangBook: public Book {
public:
	string get_brand() const override;
private:
	static const string brand;
};

class ChenGuangPencil : public Pencil {
public:
	string get_brand() const override;
private:
	static const string brand;
};

class ChenGuangRuler : public Ruler {
public:
	string get_brand() const override;
private:
	static const string brand;
};

const string AiHaoBook::brand ("AiHao");
const string AiHaoPencil::brand ("AiHao");
const string AiHaoRuler::brand ("AiHao");

const string ChenGuangBook::brand ("ChenGuang");
const string ChenGuangPencil::brand ("ChenGuang");
const string ChenGuangRuler::brand ("ChenGuang");
string
AiHaoBook::get_brand() const
{
	return AiHaoBook::brand;
}

string
AiHaoPencil::get_brand() const
{
	return AiHaoPencil::brand;
}

string
AiHaoRuler::get_brand() const
{
	return AiHaoRuler::brand;
}

string
ChenGuangBook::get_brand() const
{
	return ChenGuangBook::brand;
}

string
ChenGuangPencil::get_brand() const
{
	return ChenGuangPencil::brand;
}

string
ChenGuangRuler::get_brand() const
{
	return ChenGuangRuler::brand;
}

unique_ptr<Book>
AiHaoFactory::make_book()
{
	return make_unique<AiHaoBook>();
}

unique_ptr<Pencil>
AiHaoFactory::make_pencil()
{
	return make_unique<AiHaoPencil>();
}

unique_ptr<Ruler>
AiHaoFactory::make_ruler()
{
	return make_unique<AiHaoRuler>();
}

unique_ptr<Book>
ChenGuangFactory::make_book()
{
	return make_unique<ChenGuangBook>();
}

unique_ptr<Pencil>
ChenGuangFactory::make_pencil()
{
	return make_unique<ChenGuangPencil>();
}

unique_ptr<Ruler>
ChenGuangFactory::make_ruler()
{
	return make_unique<ChenGuangRuler>();
}


int
main (void)
{
	vector<unique_ptr<Factory>> makers;
	makers.emplace_back (make_unique<AiHaoFactory>());
	makers.emplace_back (make_unique<ChenGuangFactory>());
	for (auto &maker : makers) {
		unique_ptr<Book> book = maker->make_book();
		unique_ptr<Pencil> pencil = maker->make_pencil();
		unique_ptr<Ruler> ruler = maker->make_ruler();
		
		cout << book->get_brand() << " " << book->get_type() << endl;
		cout << pencil->get_brand() << " " << pencil->get_type() << endl;
		cout << ruler->get_brand() << " " << ruler->get_type() << endl;
	}
}

plantuml

@startuml





/' Objects '/

class AiHaoBook {
	+get_brand() : string
	--
	-brand : static const string
}


class AiHaoFactory {
	+make_book() : unique_ptr<Book>
	+make_pencil() : unique_ptr<Pencil>
	+make_ruler() : unique_ptr<Ruler>
}


class AiHaoPencil {
	+get_brand() : string
	--
	-brand : static const string
}


class AiHaoRuler {
	-brand : static const string
	+get_brand() : string
}


abstract class Book {
	+{abstract}~Book()
	+virtual get_brand() : string
	+get_type() : string
	--
	-type : static const string
}


class ChenGuangBook {
	+get_brand() : string
	--
	-brand : static const string
}


class ChenGuangFactory {
	+make_book() : unique_ptr<Book>
	+make_pencil() : unique_ptr<Pencil>
	+make_ruler() : unique_ptr<Ruler>
}


class ChenGuangPencil {
	+get_brand() : string
	--
	-brand : static const string
}


class ChenGuangRuler {
	+get_brand() : string
	--
	-brand : static const string
}


abstract class Factory {
	+{abstract}~Factory()
	+virtual make_book() : unique_ptr<Book>
	+virtual make_pencil() : unique_ptr<Pencil>
	+virtual make_ruler() : unique_ptr<Ruler>
}


abstract class Pencil {
	+{abstract}~Pencil()
	+virtual get_brand() : string
	+get_type() : string
	--
	-type : static const string
}


abstract class Ruler {
	+{abstract}~Ruler()
	+virtual get_brand() : string
	+get_type() : string
	--
	-type : static const string
}





/' Inheritance relationships '/

Book <|----- AiHaoBook


Book <|----- ChenGuangBook


Factory <|-- AiHaoFactory


Factory <|-- ChenGuangFactory


Pencil <|----- AiHaoPencil


Pencil <|----- ChenGuangPencil


Ruler <|----- AiHaoRuler


Ruler <|----- ChenGuangRuler



.ChenGuangFactory .....> .ChenGuangBook

.ChenGuangFactory .....> .ChenGuangPencil

.ChenGuangFactory .....> .ChenGuangRuler

.AiHaoFactory .....> .AiHaoBook
.AiHaoFactory .....> .AiHaoPencil
.AiHaoFactory .....> .AiHaoRuler


/' Aggregation relationships '/





/' Nested objects '/



@enduml

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

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

相关文章

详解Android 13种 Drawable的使用方法

前言关于自定义View&#xff0c;相信大家都已经很熟悉了。今天&#xff0c;我想分享一下关于自定义View中的一部分&#xff0c;就是自定义Drawable。Drawable 是可绘制对象的一个抽象类&#xff0c;相对比View来说&#xff0c;它更加的纯粹&#xff0c;只用来处理绘制的相关工作…

用Python+ChatGPT批量生成论文概述

用PythonChatGPT批量生成论文概述 做算法研究离不开阅读大量论文。从海量论文中找到需要的论文往往耗费算法团队不少的精力。 ChatGPT官方例子中有一个“TL;DR”摘要生成&#xff0c;非常适合生成论文摘要。 于是我用pythonGPT-3 API开发了一个工具&#xff0c;可以直接从arx…

基于Android校园失物招领的设计与实现

需求信息&#xff1a; 客户端&#xff1a; 1&#xff1a;登录注册&#xff1a;用户可以通过自己的信息进行账号的注册 2&#xff1a;查看信息&#xff1a;用户可以查看失物和拾物信息&#xff0c;以及对信息进行点赞和评论 3&#xff1a;发布拾物信息&#xff1a;用户可以发布自…

连阿迪达斯都卖不动了!是国潮太卷,还是消费者对品牌祛魅了?

据权威报告&#xff0c;2022年&#xff0c;阿迪达斯业绩不佳&#xff0c;尤其是大中华区表现疲软。就在昨晚&#xff0c;阿迪在业绩指引中称“2023年营运亏损可能高达7亿欧元”&#xff0c;其美国存凭证&#xff08;ADR&#xff09;价格暴跌近9%。值得注意的是&#xff0c;这已…

2分钟告诉你怎么成为一名黑客?零基础入门

在很久很久以前&#xff08;别问我有多久&#xff0c;不要在意这些细节&#xff09;&#xff0c;“ 黑客”指的是 喜爱钻研技术、精通计算机技术的程序员。后来有些黑客写了些能破坏程序或者系统正常运行的代码&#xff0c;又用搞了些破坏&#xff0c;于是这些黑客有了新的称呼…

APP优化 —— MMAP内存映射

mmap 一种内存映射文件的方法 mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上&#xff0c;如果文件的大小不是所有页的大小之和&#xff0c;最后一个页不被使用的空间将会清零。mmap在用户空间映射调用系统中作用很大。 头文件 <sys/mman.h> 函数原型 v…

微信小程序(起步)

微信小程序1、微信小程序--起步1.1 小程序简介1.2 小程序构成1.3 小程序的宿主环境1.4 协同工作和发布1、微信小程序–起步 1.1 小程序简介 小程序与普通网页开发的区别 运行环境不同 网页运行在浏览器中&#xff0c;小程序运行在微信环境中 API不同 小程序无法调用DOM和BOM…

【unity3d】1 界面 贴图 渲染 相机

一 学习背景 暴雪国服停运后&#xff0c;没有星际玩要死力 玩了一段时间[原神]感觉这个世界观和机制设定有点牛笔&#xff0c;米哈游怎么不像[魔兽世界-魔兽争霸]的关系那样&#xff0c;做个[原神争霸]捏&#xff0c;不如自己做一个耍耍 二 unity3d安装 1 官网&#xff0c;直…

Kotlin DSL 实战

1. 前言Kotlin 是一门对 DSL 友好的语言&#xff0c;它的许多语法特性有助于 DSL 的打造&#xff0c;提升特定场景下代码的可读性和安全性。本文将带你了解 Kotlin DSL 的一般实现步骤&#xff0c;以及如何通过 DslMarker &#xff0c; Context Receivers 等特性提升 DSL 的易用…

GORM-GEN快速上手

目录 1.什么是 GEN 2.GEN特性 3.快速使用GEN 3.1. 下载 3.2. 生成 4. 基础查询 5. 自定义 SQL 查询 6.demo源码 1.什么是 GEN 官方文档&#xff1a;Gen Guides | GORM - The fantastic ORM library for Golang, aims to be developer friendly. GEN 项目地址&#xf…

「mysql是怎样运行的」第19章 从猫爷被杀说起---事务简介

「mysql是怎样运行的」第19章 从猫爷被杀说起—事务简介 文章目录「mysql是怎样运行的」第19章 从猫爷被杀说起---事务简介[toc]一、事务的起源概述原子性(Atomicity)隔离性(Isolation)一致性(Consistency)持久性(Durability)二、事务的概念一、事务的起源 概述 对于大部分程…

android UI优化的基本原理和实战方法

任何Android应用都需要UI跟用户交互.UI是否好坏更是直接影响到用户的体验.如今UI的优化视乎是应用开发中一个绕不过去的话题。所以本篇文章小编带大家全面了解Android ui优化的主要知识和优化方法。 一、UI优化 UI优化知识点主要分为三部分&#xff1a; 第一部分&#xff0c…

Linux简单介绍(基本涵盖日常使用到的各种shell知识点)

文章目录shell基础认知1. shell语言2. 脚本执行方式3. 快捷键4. 通配符5. 命令后跟的选项6. 逻辑运算 && ||7. 算术运算&#xff08;equal&#xff0c;great&#xff0c;less&#xff09;8. 目录或文件意义9. 规则10. vimshell脚本常规内容解释1. set -ex2. set -o pip…

Google Brain新提出的优化器“Lion”,效果要比Adam(W)更好

Google Brain新提出的优化器“Lion”&#xff0c;效果要比Adam(W)更好 论文地址&#xff1a;https://arxiv.org/abs/2302.06675代码地址&#xff1a;https://github.com/google/automl/blob/master/lion/lion_pytorch.py 1 简单、内存高效、运行速度更快 与 AdamW 和各种自适…

量子计算对网络安全的影响

量子计算的快速发展&#xff0c;例如 IBM 的 Quantum Condor 处理器具有 1000 个量子比特的容量&#xff0c;促使专家们宣称第四次工业革命即将实现“量子飞跃”。 量子计算机的指数处理能力已经受到政府和企业的欢迎。 由于从学术和物理原理到商业可用解决方案的不断转变&am…

Spark Explain:查看执行计划

Spark SQL explain 方法有 simple、extended、codegen、cost、formatted 参数&#xff0c;具体如下 目录一、基本语法二、执行计划处理流程三、具体案例一、基本语法 从 3.0 开始&#xff0c;explain 方法有一个新的 mode 参数&#xff0c;指定执行计划展示格式 只展示物理执…

都2023年了,竟然还有人问网络安全怎么入门?

工作一直忙碌&#xff0c;偶然翻了一下知乎&#xff0c;都2022年了&#xff0c;相关网课这么多了&#xff0c;还有人不知道怎么学习网络安全&#xff0c;不了解也就算了&#xff0c;竟然还有一批神仙也真敢回答&#xff0c;对这个行业了解各一知半解就当做这些萌新的启蒙老师了…

UDP与TCP协议

目录 UDP协议 协议报头 UDP协议特点&#xff1a; 应用场景&#xff1a; TCP TCP协议报头 确认应答机制 理解可靠性 超时重传机制 连接管理机制 三次握手&#xff1a; 四次挥手&#xff1a; 滑动窗口 如何理解缓冲区和滑动窗口&#xff1f; 倘若出现丢包&#xf…

05 DC-AC逆变器(DCAC Converter / Inverter)简介

文章目录0、概述逆变原理方波变换阶梯波变换斩控调制方式逆变器分类逆变器波形指标1、方波变换器A 单相单相全桥对称单脉冲调制移相单脉冲调制单相半桥2、方波变换器B 三相180度导通120度导通&#xff08;线、相的关系与180度相反&#xff09;3、阶梯波逆变器独立直流源二极管钳…

Esxi NAT网络搭建

前言 本文主要讲述如何在Esxi上只有一个公网IP情况下,实现内部虚拟机上网,以及外部对内部服务的访问,以及外网通过vpn访问内网; 环境 Esxi 6.7iKuai8 3.6.13OpenVPN 2.6一、创建虚拟路由 1.1 目的 虚拟路由,也就是常说的软路由;只有一个外网IP情况下,其他虚拟机需要上…