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

目录

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


简单工厂

定义:简单工厂由一个工厂根据参数类型决定创建哪种产品的实例。
简单工厂不包含在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.hqwc.cn/news/311161.html

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

相关文章

Radar System Pro - Plug Play Solution

Radar System Pro是一款功能多样且可定制的资源,旨在通过功能齐全且易于使用的雷达系统增强您的Unity项目。无论您是在开发第一人称射击游戏、策略游戏还是太空探索模拟器,我们的雷达系统都将为您提供所需的工具,以创建引人入胜且身临其境的体验。 雷达系统是一个模块化资产…

排序整形数组--------每日一题

大家好这是今年最后的一篇了&#xff0c;感谢大家的支持&#xff0c;新的一年我会更加努力地。 文章目录 目录 文章目录 题⽬描述&#xff1a; 输⼊10个整数&#xff0c;然后使⽤冒泡排序对数组内容进⾏升序排序&#xff0c;然后打印数组的内容 一、题目解读 冒泡排序是⼀种基础…

【低代码平台】10个开源免费Airtable 的替代方案

Airtable是一个易于使用的简单低代码平台&#xff0c;有助于团队协作管理复杂的数据表&#xff0c;并创建定制的工作流程。把它想象成一个类固醇上的云电子表格。 Airtable还简化了数据输入过程&#xff0c;连接和集成第三方服务和应用程序&#xff0c;并提供了许多数据导入/导…

每日一题——LeetCode977

方法一 个人方法&#xff1a; 以示例1为例&#xff1a;把[-4,-1,0,3,10] 中n<0的元素拆分出来&#xff0c;把他们的平方从小到大放入arr数组&#xff0c;则arr[0,1,16] ,那数组就还剩[3,10] 对于剩下的元素&#xff0c;看arr里面有没有比他们平方更小的元素先放入res数组&…

Linux操作系统( YUM软件仓库技术 )

镜像文件的回环挂载&#xff08;把iso镜像文件释放成系统安装光盘&#xff09;foundation0上操作 回环挂载的用法&#xff1a; du -sh 对象名 //估算文件&#xff08;一切对象皆文件&#xff09;大小 !$ //上一条命令的最后一个参数 新创建的挂载点目录是空白目录 挂载&#xf…

kivy开发一个登陆界面

Kivy Kivy是一个用于开发跨平台移动应用&#xff08;如Android和iOS&#xff09;以及桌面应用&#xff08;如Windows、Linux和macOS&#xff09;的Python框架。它采用开源许可证&#xff08;MIT许可证&#xff09;&#xff0c;提供了丰富的图形界面组件和工具&#xff0c;以便…

使用yolov5的2.0分支训练自己的模型并在x3派运行

目录 准备代码、权重、数据集配置环境准备数据标注数据 训练模型转换模型验证模型准备校准数据转换为板上模型模型精度分析 上板 之前训练自己模型的时候使用的是博主 bubbling的1.0分支的代码&#xff0c;博主的 博客比较详细&#xff0c;使用的是VOC2007数据集&#xff0c;…

RK3568笔记七:yolov5-seg实例分割测试验证

若该文为原创文章&#xff0c;转载请注明原文出处。 记录的目的是想在RK3568上实现实例分割&#xff0c;在github的rknn_mode_zoo仓库里看到了例子&#xff0c;带着疑问测试了一下&#xff0c;结果跑通了&#xff0c;这里记录下全过程。 一、环境 1、硬件&#xff1a;正点原…

Java安装详细教程

文章目录 一、JDK 下载 和 安装1.1 选择 Java版本1.2 下载 JDK 二、 配置环境变量2.1 配置环境变量的原因2.2 配置环境变量2.3 验证配置是否成功 参考资料 一、JDK 下载 和 安装 1.1 选择 Java版本 访问 Oracle 官方网站的 Java 下载页面Java Archive | Oracle。 在 “Java …

vue实现滑动切换:切换选项时滑块有滑动过渡的效果

效果图 思路&#xff1a; 1. 高亮的色块是独立的一个盒子&#xff0c;需要插入当前激活的内容用来撑开色块盒子的宽度&#xff0c;这样色块的宽度就会和当前激活的内容宽度一致&#xff0c;色块的字体颜色设置透明即可 2. 色块滑动的距离是读当前激活元素的offsetLeft&#x…

Redis经典五大类型源码及底层实现(二)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

【数据结构——图】图的最短路径(头歌习题)【合集】

目录 第1关&#xff1a;单源最短路径完整代码 第2关&#xff1a;多源最短路径输入格式:输出格式:完整代码 第1关&#xff1a;单源最短路径 给一个n(1 ≤ n ≤ 2500) 个点 m(1 ≤ m ≤ 6200) 条边的无向图&#xff0c;求 s 到 t 的最短路。 输入格式: 第一行四个由空格隔开的整…