设计模式:工厂方法模式(讲故事图文易懂)

news2025/4/21 11:19:27

目录

  • 简单工厂
  • 工厂方法模式


简单工厂

定义:简单工厂由一个工厂根据参数类型决定创建哪种产品的实例。
简单工厂不包含在23种设计模式之内(简单工厂不满足开闭原则,后面会详细讲)
举例:张三去4S店买了车,显而易见,车不是张三造出来的,车是工厂造出来的,张三获得了该车并能够使用该车,但是造车的细节张三不用知道。

铁蛋在一家汽车工厂上班,这家工厂承接了”小米汽车“和”华为汽车“的生产,一天铁蛋接到了要求,要新开一个”长安汽车“生产线生产长安汽车,铁蛋要怎么做呢?
在这里插入图片描述

先写一个简单工厂的例子,再看看铁蛋要怎么做?
简单工厂模式有三个角色:抽象基类(Car)
                                            实现类(XiaoMiCar、HuaWeiCar)
                                            简单工厂类(SimpleFactory)

#include <iostream>
#include <string>
using namespace std;

//抽象基类
class Car
{
public:
	Car(string name) : name_(name) {}
	virtual void Show() = 0;

protected:
	string name_;
};

//实现类
class XiaomiCar : public Car {
public:
	XiaomiCar(string name) : Car(name) {}
	void Show() {
		cout << "获得一辆小米轿车: " << name_ << endl;
	}
};
//实现类
class HuaweiCar : public Car {
public:
	HuaweiCar(string name) : Car(name) {}
	void Show() {
		cout << "获得一辆华为轿车: " << name_ << endl;
	}
};

enum CarType
{
	XIAOMI, HUAWEI
};

//简单工厂类
class SimpleFactory {
public:
	Car* CreateCar(CarType type) {
		switch (type) {
		case XIAOMI:
			return new XiaomiCar("SU7");
		case HUAWEI:
			return new HuaweiCar("问界");
		default:
			return nullptr;
		}
	}
};

int main()
{
	SimpleFactory* factory = new SimpleFactory();
	Car* c1 = factory->CreateCar(XIAOMI);
	Car* c2 = factory->CreateCar(HUAWEI);
	c1->Show();
	c2->Show();

	delete c1;
	delete c2;
	delete factory;
}

运行结果:
在这里插入图片描述
上面小米汽车XiaomiCar 和华为汽车HuaweiCar 继承了汽车基类Car。
简单工厂SimpleFactory根据传入不同类型CarType来生产不同类型的车。

你是否想到了铁蛋要怎么做,铁蛋是这样做的:
1.增加长安汽车类(继承了汽车基类Car)
2.修改简单工厂类SimpleFactory(增加”CHANGAN“类型车的创建)

#include <iostream>
#include <string>
using namespace std;

class Car
{
public:
	Car(string name) : name_(name) {}
	virtual void Show() = 0;

protected:
	string name_;
};

class XiaomiCar : public Car {
public:
	XiaomiCar(string name) : Car(name) {}
	void Show() {
		cout << "获得一辆小米轿车: " << name_ << endl;
	}
};

class HuaweiCar : public Car {
public:
	HuaweiCar(string name) : Car(name) {}
	void Show() {
		cout << "获得一辆华为轿车: " << name_ << endl;
	}
};

class ChanganCar : public Car {
public:
	ChanganCar(string name) : Car(name) {}
	void Show() {
		cout << "获得一辆长安轿车: " << name_ << endl;
	}
};

enum CarType
{
	XIAOMI, HUAWEI, CHANGAN
};

class SimpleFactory {
public:
	Car* CreateCar(CarType type) {
		switch (type) {
		case XIAOMI:
			return new XiaomiCar("SU7");
		case HUAWEI:
			return new HuaweiCar("问界");
		case CHANGAN:
			return new ChanganCar("深蓝《偷偷藏不住》");
		default:
			return nullptr;
		}
	}
};

int main()
{
	cout << "------简单工厂------" << endl;
	SimpleFactory* factory = new SimpleFactory();
	Car* c1 = factory->CreateCar(XIAOMI);
	Car* c2 = factory->CreateCar(HUAWEI);
	Car* c3 = factory->CreateCar(CHANGAN);
	c1->Show();
	c2->Show();
	c3->Show();

	delete c1;
	delete c2;
	delete c3;
	delete factory;
}

运行结果:
在这里插入图片描述
成功生产了长安轿车!


但是从逻辑上来讲,同一个工厂不会生产小米汽车又生产华为汽车,又或者这个工厂还将生产长安汽车

因为:当简单工厂想增加生产长安汽车时,会修改简单工厂类SimpleFactory(增加”CHANGAN“类型车的创建),违反了开闭原则(对修改关闭,对扩展开放)。每当我们增加一种产品的时候就要去修改工厂方法,这样会破坏其内聚性,给维护带来额外开支。

所以,有了工厂方法模式来解决该问题。

工厂方法模式

定义:工厂基类负责定义创建对象的公共接口,子类工厂负责创建出具体的对象,来实现不同产品的工厂化创建。
设计模式有三大分类:创建型模式、结构型模式、行为型模式
工厂方法模式属于创建型模式
在这里插入图片描述
工厂方法模式不只有一个工厂每个工厂只生产一种特定的产品。这样做的好处是当以后需要增加新的产品时,直接新增加一个对应的工厂就可以,而不是去修改原有的工厂,符合编程原则的开闭原则

#include <iostream>
#include <string>
using namespace std;

class Car
{
public:
	Car(string name) : name_(name) {}
	virtual void Show() = 0;

protected:
	string name_;
};

class XiaomiCar : public Car {
public:
	XiaomiCar(string name) : Car(name) {}
	void Show() {
		cout << "获得一辆小米轿车: " << name_ << endl;
	}
};

class HuaweiCar : public Car {
public:
	HuaweiCar(string name) : Car(name) {}
	void Show() {
		cout << "获得一辆华为轿车: " << name_ << endl;
	}
};

class Factory {
public:
	virtual Car* CreateCar(string name) = 0;
};

class XiaomiFactory : public Factory
{
public:
	Car* CreateCar(string name)
	{
		return new XiaomiCar(name);
	}
};

class HuaweiFactory : public Factory
{
public:
	Car* CreateCar(string name)
	{
		return new HuaweiCar(name);
	}
};

int main()
{
	cout << "------工厂方法模式------" << endl;
	Factory* xiaomiFactory = new XiaomiFactory();
	Factory* huaweiFactory = new HuaweiFactory();
	Car* xiaomiCar = xiaomiFactory->CreateCar("SU7");
	Car* huaweiCar = huaweiFactory->CreateCar("问界");

	xiaomiCar->Show();
	huaweiCar->Show();

	delete xiaomiCar;
	delete huaweiCar;
	delete xiaomiFactory;
	delete huaweiFactory;
}

运行结果:
在这里插入图片描述

同样上面小米汽车XiaomiCar 和华为汽车HuaweiCar 继承了汽车基类Car。
小米工厂XiaomiFactory和华为工厂HuaweiFactory继承了工厂基类Factory。
小米工厂生产小米汽车,华为工厂生产华为汽车。

这样,铁蛋想生产”长安汽车“,就直接新建长安汽车工厂,由长安工厂来生产长安汽车,这样就不用修改小米工厂和华为工厂,满足程序设计的开闭原则

铁蛋是这样做的
1.增加了长安汽车类ChanganCar (继承了汽车基类Car)
2.增加了长安汽车工厂ChanganFactory (继承了工厂基类Factory)

#include <iostream>
#include <string>
using namespace std;

class Car
{
public:
	Car(string name) : name_(name) {}
	virtual void Show() = 0;

protected:
	string name_;
};

class XiaomiCar : public Car {
public:
	XiaomiCar(string name) : Car(name) {}
	void Show() {
		cout << "获得一辆小米轿车: " << name_ << endl;
	}
};

class HuaweiCar : public Car {
public:
	HuaweiCar(string name) : Car(name) {}
	void Show() {
		cout << "获得一辆华为轿车: " << name_ << endl;
	}
};

class Factory {
public:
	virtual Car* CreateCar(string name) = 0;
};

class XiaomiFactory : public Factory
{
public:
	Car* CreateCar(string name)
	{
		return new XiaomiCar(name);
	}
};

class HuaweiFactory : public Factory
{
public:
	Car* CreateCar(string name)
	{
		return new HuaweiCar(name);
	}
};

class ChanganCar : public Car {
public:
	ChanganCar(string name) : Car(name) {}
	void Show() {
		cout << "获得一辆长安轿车: " << name_ << endl;
	}
};

class ChanganFactory : public Factory
{
public:
	Car* CreateCar(string name)
	{
		return new ChanganCar(name);
	}
};

int main()
{
	cout << "------工厂方法模式------" << endl;
	Factory* xiaomiFactory = new XiaomiFactory();
	Factory* huaweiFactory = new HuaweiFactory();
	Factory* changanFactory = new ChanganFactory();
	Car* xiaomiCar = xiaomiFactory->CreateCar("SU7");
	Car* huaweiCar = huaweiFactory->CreateCar("问界");
	Car* changanCar = changanFactory->CreateCar("深蓝《偷偷藏不住》");

	xiaomiCar->Show();
	huaweiCar->Show();
	changanCar->Show();

	delete xiaomiCar;
	delete huaweiCar;
	delete changanCar;
	delete xiaomiFactory;
	delete huaweiFactory;
	delete changanFactory;
}

运行结果:
在这里插入图片描述


无广告,以汽车为例故事形式介绍了简单工厂和工厂方法模式。

谢谢观看,祝顺利!

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

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

相关文章

大二第17周总结——2023年的最后一天

本周&#xff0c;学校安排的是数据结构的程序设计&#xff0c;设计是挺好设计的&#xff0c;小半天搞完了&#xff0c;然后帮室友也搞了。内容在上一个博客。 学习上嘛~ 学了一下websocket,看了下微信小程序........ 今天早上做了一套小米的面试题&#xff0c;不做不知道&…

Java开发框架和中间件面试题(10)

目录 104.怎么保证缓存和数据库数据的一致性&#xff1f; 105.什么是缓存穿透&#xff0c;什么是缓存雪崩&#xff1f;怎么解决&#xff1f; 106.如何对数据库进行优化&#xff1f; 107.使用索引时有哪些原则&#xff1f; 108.存储过程如何进行优化&#xff1f; 109.说说…

按摩上门预约小程序源码系统 开发组合:PHP+MySQL 附带完整的搭建教程

现代生活节奏的加快&#xff0c;人们越来越注重健康与放松。按摩作为传统的舒缓方式&#xff0c;市场需求逐年上升。然而&#xff0c;传统的按摩服务预约方式较为繁琐&#xff0c;用户需拨打热线电话或前往实体店进行预约&#xff0c;这无疑增加了用户的操作成本。因此&#xf…

前端框架前置学习(4) AJAX

同步代码和异步代码 同步代码 浏览器按照我们书写代码的顺序一行一行地执行程序.浏览器会等待代码的解析和工作,在上一行代码完成之后才会执行下一行代码.这被称之为同步程序 逐行执行,需要原地等待结果 异步代码 异步编码技术使得程序可以在执行一个可能长期运行的任务的…

七:Day01_Java9—16新特性

第一章 JDK9 新特性 jdk9是新特性最多的&#xff0c;因为jdk8是一个稳定版本。 1、JDK9新特性概述 模块系统 &#xff08;Module System&#xff09; Java9最大特性。它提供了类似于OSGI框架的功能&#xff0c;模块之间存在相互的依赖关系&#xff0c;可以导出一个公共的API…

数据库——LAMP的搭建及MySQL基操

1.实验内容及原理 1. 在 Windows 系统中安装 VMWare 虚拟机&#xff0c;在 VMWare 中安装 Ubuntu 系统,并在 Ubuntu 中搭建 LAMP 实验环境。 2. 使用 MySQL 进行一些基本操作&#xff1a; &#xff08;1&#xff09;登录 MySQL&#xff0c;在 MySQL 中创建用户&#xff0c;并对…

听GPT 讲Rust源代码--src/tools(37)

File: rust/src/tools/clippy/clippy_lints/src/explicit_write.rs 在Rust源代码中&#xff0c;explicit_write.rs这个文件是Clippy的一个lint插件&#xff0c;其作用是检查代码中的write!、writeln!宏使用时的不当或繁琐的情况&#xff0c;并给出相关的警告或建议。 具体来说&…

门控循环单元(GRU)-多输入回归预测

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、部分程序&#xff1a; 四、全部代码数据分享&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译…

Redis为何如此快速?

1. 引言 Redis&#xff08;Remote Dictionary Server&#xff09;是一个高性能的键值对存储数据库。它以其出色的性能和灵活的数据结构而闻名&#xff0c;今天就来谈谈redis为什么会这么快。 1.1 Redis是单线程吗&#xff1f; Redis 的单线程主要是指 Redis 的网络 IO 和键值对…

【REST2SQL】01RDB关系型数据库REST初设计

0 概念 REST2SQL实现连接数据库&#xff0c;数据库的表或视图即可提供REST的GET\POST\PUT\DELETE请求&#xff0c;SQL可执行SQLECT\INSERT\UPDATE\DELETE语句。 0.1 RDB Relational Database 即关系型数据库&#xff08;简称 RDB&#xff09;是一种以关系&#xff08;即表格…

SpringCloud(H版alibaba)框架开发教程,使用eureka,zookeeper,consul,nacos做注册中心——附源码(1)

源码地址&#xff1a;https://gitee.com/jackXUYY/springboot-example 创建订单服务&#xff0c;支付服务&#xff0c;公共api服务&#xff08;共用的实体&#xff09;&#xff0c;eureka服务 1.cloud-consumer-order80 2.cloud-provider-payment8001 3.cloud-api-commons 4.…

医院安全(不良)事件报告系统源码 支持二次开发、支持源码交付

医疗不良事件报告系统源码旨在建立全面的、统一的医疗不良事件标准分类系统和患者安全术语&#xff0c;使不良事件上报管理更加标准化和科学化。通过借鉴国内外医疗不良事件报告系统的先进经验&#xff0c;根据医疗不良事件的事件类型、处理事件的不同部门&#xff0c;灵活设置…

探索小红书笔记API:挖掘数据背后的故事

随着数字化时代的到来&#xff0c;数据已经成为企业和个人决策的重要依据。小红书作为一个流行的社交电商平台&#xff0c;积累了大量的用户数据和内容。通过探索小红书笔记API&#xff0c;我们可以深入挖掘这些数据背后的故事&#xff0c;从而更好地理解用户需求和市场趋势。 …

用C语言函数求x^y-------(C每日一编程)

编写函数,计算x^y&#xff08;x,y都是整数&#xff09;。 参考代码&#xff1a; int fun(int x, int y) {int k 1, i;for (i 1; i < y; i)k k * x;return k; } int main() {int x, y;scanf("%d%d", &x, &y);printf("%d", fun(x, y));retur…

文献阅读:LoRA: Low-Rank Adaptation of Large Language Models

文献阅读&#xff1a;LoRA: Low-Rank Adaptation of Large Language Models 1. 文章简介2. 方法介绍3. 实验 & 结论 1. 基础实验 1. Bert系列模型2. GPT系列模型 2. 消解实验 1. 作用矩阵考察2. 中间维度考察3. 扰动程度分析 4. 总结 & 思考 文献链接&#xff1a;htt…

Python中使用Matplotlib绘制圆环图

更多Python学习内容&#xff1a;ipengtao.com Matplotlib是Python中一个非常强大的库&#xff0c;它可以创建各种类型的图表&#xff0c;包括圆环图。圆环图是一种用于显示不同部分的相对比例的图表&#xff0c;通常用于呈现百分比或比例数据。在本文中&#xff0c;将深入探讨如…

FreeRTOS列表与列表项相关知识总结以及列表项的插入与删除实战

1.列表与列表项概念及结构体介绍 1.1列表项简介 列表相当于链表&#xff0c;列表项相当于节点&#xff0c;FreeRTOS 中的列表是一个双向环形链表 1.2 列表、列表项、迷你列表项结构体 1&#xff09;列表结构体 typedef struct xLIST { listFIRST_LIST_INTEGRITY_CHECK_VAL…

我的 2023 年终总结

时间太瘦&#xff0c;指缝太宽&#xff0c;岁月就这样匆匆流逝&#xff0c;似乎年初许愿时的憧憬还在眼前&#xff0c;转瞬就到了年尾&#xff0c;对2023年做个简单的回顾吧 我的 2022 年终总结 我的 2019 年终总结 总结2022年展望2023年 2023年的目标 参与晋升&#xff0c;希望…

机器学习、人工智能、深度学习的关系

人工智能(Artificial Intelligence&#xff0c;AI) 人工智能范围很广&#xff0c;它是一门新的科学与工程&#xff0c;是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的技术科学&#xff0c;研究内容涵盖语音识别、图像识别、自然语言处理、智能搜索和…

ssm基于冲突动态监测算法的健身房预约系统的设计与实现论文

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装健身房预约系统软件来发挥其高效地信息处理的作用&#xff…