创建型模式 | 工厂模式

news2024/11/20 16:35:13

文章目录

  • 一、简单工厂
    • 1.1、原理
    • 1.2、核心角色
    • 1.3、UML类图
    • 1.4、代码实现
    • 1.5、总结
  • 二、工厂模式
    • 2.1、原理
    • 2.2、关键角色
    • 2.3、代码实现
    • 2.4、总结
  • 三、抽象工厂模式
    • 3.1、原理
    • 3.2、关键角色
    • 3.3、UML类图
    • 3.4、工厂模式与抽象工厂模式的区别

前言

工厂模式是最常用的设计模式之一,它提供了一种创建对象的最佳方式,在创建对象的时候,不会对客户端暴露创建逻辑,并且通过使用一个共同的接口来创建新的对象。工厂模式有三种,分别是简单工厂、工厂模式,抽象工厂

一、简单工厂

1.1、原理

通过传⼊相关的类型来返回相应的类对象,简单工厂模式看为工厂方法模式的一种特例。

1.2、核心角色

  • 简单工厂(SimpleFactory):根据类型创建类对象
  • 抽象产品(IProduct):产品接口,描述所有实例对象的公共接口
  • 具体产品(ConcreteProduct):实现产品接口

1.3、UML类图

下面以生成手机的代码为例,介绍简单工厂模式,UML类图如下:

在这里插入图片描述

1.4、代码实现

代码实现,如下:

#include <iostream>
using namespace std;

// 手机(抽象接口)
class IPhone {
public:
    virtual void Describe() = 0;
};

// 华为手机(具体产品)
class HuaweiPhone : public IPhone {
public:
    void Describe() {
        cout << "华为手机" << endl;
    }
};

// 苹果手机(具体产品)
class ApplePhone : public IPhone {
public:
    void Describe() {
        cout << "苹果手机" << endl;
    }
};

// 简单工厂
class PhoneFactory {
public:
    IPhone* Produce(string type) {
        IPhone *pPhone = nullptr;
        if (type == "Huawei") {
            pPhone = new HuaweiPhone;
        } else if (type == "Apple") {
            pPhone = new ApplePhone;
        }
        return pPhone;
    }
};

int main()
{
    // 简单工厂
    PhoneFactory factory;

    IPhone *pHuaweiPhone = factory.Produce("Huawei");
    IPhone *pApplePhone = factory.Produce("Apple");

    pHuaweiPhone->Describe();
    pApplePhone->Describe();

    return 0;
}

1.5、总结

简单工厂模式优点与缺点,如下:

优点:

  • 实现简单
  • 实现了对象创建与业务逻辑的分离

缺点:

  • 可扩展性差,如果新增手机产品,就需要修改PhoneFactory::Produce方法,违反了开放封闭原则

二、工厂模式

2.1、原理

定义创建对象抽象工厂,具体工厂负责实现抽象工厂接口,创建对应类型的对象

2.2、关键角色

  • 抽象工厂:定义了创建抽象产品的抽象工厂
  • 具体工厂:实现抽象工厂接口的具体工厂类,负责生产具体的产品
  • 抽象产品:产品接口,描述所有实例对象的公共接口
  • 具体产品:实现产品接口

2.3、代码实现

#include <iostream>
using namespace std;

// 手机(抽象接口)
class IPhone {
public:
    virtual void Describe() = 0;
};

// 华为手机(具体产品)
class HuaweiPhone : public IPhone {
public:
    void Describe() {
        cout << "华为手机" << endl;
    }
};

// 苹果手机(具体产品)
class ApplePhone : public IPhone {
public:
    void Describe() {
        cout << "苹果手机" << endl;
    }
};

// 抽象工厂
class IFactory {
public:
    virtual IPhone* Produce() = 0;
};

// 具体工厂(生产华为手机)
class HuaweiPhoneFactory : public IFactory {
public:
    IPhone* Produce() {
        return new HuaweiPhone;
    }
};

// 具体工厂(生产苹果手机)
class ApplePhoneFactory : public IFactory {
public:
    IPhone* Produce() {
        return new ApplePhone;
    }
};

int main()
{
    // 工厂对象
    HuaweiPhoneFactory huaweiFactory;
    ApplePhoneFactory appleFactory;

    IPhone *pHuaweiPhone = huaweiFactory.Produce();
    IPhone *pApplePhone = appleFactory.Produce();

    pHuaweiPhone->Describe();
    pApplePhone->Describe();

    return 0;
}

2.4、总结

工厂模式优点与缺点,如下:

优点:

  • 解决了简单工厂模式可扩展性差的问题,如果新增手机产品,新增一个产品类及对应的工厂类就可以,不会修改原有的代码,符合开放封闭原则

缺点:

  • 随着产品的增多,类的个数容易过多,增加复杂度
  • 具体工厂只能生产出一种产品(可以用抽象工厂模式解决)

三、抽象工厂模式

3.1、原理

抽象工厂模式在工厂方法模式的基础上进行进一步抽象。设想下面这种场景:在手机的基础上新增了Pad,要创建华为Phone华为Pad苹果Phone苹果Pad等产品,如果使用工厂模式,就要新增四个工厂类,使用工厂方法模式,创建了很多具体工厂类,而没有利用产品的商品族的概念。

抽象工厂模式是用于解决一类产品的创建问题(在上述场景中,可以把华为Phone华为Pad苹果Phone苹果Pad归纳为PhonePad这两类商品)

3.2、关键角色

抽象工厂模式与工厂模式的关键角色类似,有差异的地方在于抽象工厂类,如下:

  • 抽象工厂类:定义一组接口,用于创建多类产品;工厂方法的抽象工厂类,只定义了创建一类产品的接口

3.3、UML类图

使用抽象工厂类解决工厂方法遇到的两个问题,一是:只能生产一类产品的问题;二是:增加产品导致产品工厂类的个数容易过多的问题(解决新增Pad产品的问题,如果使用抽象工厂方法需要新增两个工厂类,而使用工厂方法需要四个工厂类),UML类图如下:

在这里插入图片描述

3.4、工厂模式与抽象工厂模式的区别

工厂模式主要解决一类产品的创建问题,抽象工厂模式主要是来解决多类(产品簇)产品创建问题。具体差异体现在抽象工厂角色上,工厂模式提供一个接口,创建一类产品;抽象工厂提供多个接口,可以创建多类产品。

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

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

相关文章

ROS---激光雷达的使用

ROS—激光雷达的使用 激光雷达是现今机器人尤其是无人车领域及最重要、最关键也是最常见的传感器之一&#xff0c;是机器人感知外界的一种重要手段。本文将介绍在ROS下使用激光雷达传感器&#xff0c;我们选用的激光雷达型号为思岚A1。 使用流程如下: 硬件准备&#xff1b;软…

C++——简介、Hello World、变量常量、数据类型

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

idea编译报错(Maven项目)

idea编译报错 找不到符号 第一步&#xff1a;开启注解处理器 第二步&#xff1a;清理MVN&#xff0c;package并重新编译 第三步&#xff1a;重新导入项目&#xff1a;

本地开发环境请求服务器接口跨域的问题(vue的问题)

上面的这个报错大家都不会陌生&#xff0c;报错是说没有访问权限&#xff08;跨域问题&#xff09;。本地开发项目请求服务器接口的时候&#xff0c;因为客户端的同源策略&#xff0c;导致了跨域的问题。下面先演示一个没有配置允许本地跨域的的情况&#xff1a; 可以看到&…

【亲测有效】Win11 卸载MySQL5.7以及安装MySQL8.0.35

目录 一、卸载原来本地的mysql5.7 1.mysql服务部分 1.1停止mysql服务 1.2删除mysql服务 2.卸载 MySQL程序 3.残余文件的清理 3.1删除mysql安装的目录 3.2删除mysql数据存放的目录 3.3删除mysql自定义目录 4.清理注册表 5.删除环境变量配置 二、安装mysql8.0.35 1.…

Explain详解与索引最佳实践

Mysql安装文档参考&#xff1a;https://blog.csdn.net/yougoule/article/details/56680952 Explain工具介绍 使用EXPLAIN关键字可以模拟优化器执行SQL语句&#xff0c;分析你的查询语句或是结构的性能瓶颈 在 select 语句之前增加 explain 关键字&#xff0c;MySQL 会在查询…

全网第一篇教你怎么总结多线程知识

于「全景图」&#xff0c;我之前也有一直在构建&#xff0c;可是因为知识储备不够&#xff0c;确实很难构建出来。稍微了解过并发领域知识的人都知道&#xff0c;里面的知识点、概念多而散&#xff1a;线程安全、锁、同步、异步、阻塞、非阻塞、死锁、队列(为什么并发要跟队列扯…

2024年云服务器配置推荐,看看哪家便宜?

作为多年站长使市面上大多数的云厂商的云服务器都使用过&#xff0c;很多特价云服务器都是新用户专享的&#xff0c;本文有老用户特价云服务器&#xff0c;阿腾云atengyun.com有多个网站、小程序等&#xff0c;国内头部云厂商阿里云、腾讯云、华为云、UCloud、京东云都有用过&a…

Backtrader 文档学习-Strategy with Signals

Backtrader 文档学习-Strategy with Signals backtrader可以不通过重写策略的方式触发交易&#xff0c;尽管重写策略是首选通用的方式。 下面介绍通过使用信号也是可以实现交易触发的。 1.定义signal import backtrader as btdata bt.feeds.OneOfTheFeeds(datanamemydatana…

微信公众号使用后端代码接入开发指南

1. 部署到服务器一套后端服务 要求&#xff1a;外界通过get请求可以访问到该服务&#xff0c;并且该地址只返回文本&#xff1a;hello, this is handle view&#xff0c;这就是下面这段代码的意思 这段代码的意思就是服务匹配到/wx的get请求&#xff0c;返回文本hello, this …

【UE Niagara学习笔记】07 - 火焰的热变形效果

目录 效果 步骤 一、创建热变形材质 二、添加新的发射器 2.1 设置粒子材质 2.2 设置粒子初始大小 2.3 设置粒子持续生成 三、修改材质 四、设置粒子效果 在上一篇博客&#xff08;【UE Niagara学习笔记】06 - 制作火焰喷射过程中飞舞的火星&#xff09;的基础上继续…

机器学习之特征工程

一、背景 什么是特征&#xff1f;在机器学习中,特征是一个现象的个别可测量的属性或特征。让我们观察一束阳光&#xff0c;直接看的话&#xff0c;它是白光&#xff0c;但是我们使用三菱镜&#xff0c;它就是七种颜色的光。所以&#xff0c;选取的事物的特征不同&#xff0c;我…

能赚钱的GPT Store正式上线!如何将自己的 GPT 放到商店中?

等了两个月&#xff0c;OpenAI 的 GPT Store 今日凌晨终于上线&#xff01;上线 GPT Store 的同时&#xff0c;OpenAI 同步了最新的 GPTs 数据&#xff1a;截止到1月11日&#xff0c;用户已创建300万的GPTs&#xff01; GPTs 开发者可以通过 GPTs 来获利。OpenAI 将在今年第一季…

PLECS如何下载第三方库并导入MOSFET 的xml文件,xml库路径添加方法及相关问题

1. 首先xml库的下载&#xff0c;PLECS提供了一个跳转的链接。 https://www.plexim.com/download/thermal_models 2. 下载一个库&#xff08;以最后一个Wolfspeed为例&#xff0c;属于CREE的SiC MOSFET&#xff09; 下载这个就行&#xff0c;都包含了。不信自己可以试试再下载…

java物品检验管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web 物品检验管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysq…

C++里main函数int main(int argc, char **argv)

C里main函数int main(int argc, char **argv), 这两个参数argc和argv分别是什么

免费申请eu.org域名,开启个人网站之旅

介绍 eu.org的免费域名注册服务是由OpenTLD B.V.提供的。相比于其他免费域名注册服务&#xff0c;eu.org的域名后缀更加独特。同时&#xff0c;eu.org的域名注册也比较简单&#xff0c;只需要填写一些基本信息&#xff0c;就可以获得自己的免费域名。 注册账号 点击进入登…

C#中的Abp项目发布后,将exe设置为开机自动启动

一.跳过登陆界面 1.win R,输入“regedit”进入注册表&#xff0c;点开“HKEY_LOCAL_MACHINE” 2.SOFTWARE–>Policies–>Microsoft–>Windows–>新建–>项–>Personalization,新建–>DWORD(32位&#xff09;&#xff0c;名字定位“NoLockScreen”,值设为…

【JaveWeb教程】(20) MySQL数据库开发之 基本查询、条件查询、聚合函数、分组查询、排序查询、分页查询 详细代码示例讲解

目录 1. 数据库操作-DQL1.1 介绍1.2 语法1.3 基本查询1.4 条件查询1.5 聚合函数1.6 分组查询1.7 排序查询1.8 分页查询1.9 案例1.9.1 案例一1.9.2 案例二 在上次学习的内容中&#xff0c;我们讲解了&#xff1a; 使用DDL语句来操作数据库以及表结构&#xff08;数据库设计&…

java通过HttpClient方式实现https请求的工具类(绕过证书验证)

目录 一、引入依赖包二、HttpClient方式实现的https请求工具类三、测试类 一、引入依赖包 引入相关依赖包 <!--lombok用于简化实体类开发--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><option…