设计模式--工厂模式

news2025/4/11 21:56:23

  这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
  工厂模式主要使用了C++的多态特性。将存在继承关系的类,通过一个工厂类创建对应的子类(派生类)对象。在项目复杂的情况下,可以便于子类对象的创建。
  工厂模式的实现方式可分别简单工厂模式、工厂方法模式、抽象工厂模式,每个实现方式都存在优和劣。
  以制鞋厂为例对这三种工厂模式进行举例说明

1. 简单工厂模式

1.1 UML图

类比情形:鞋厂可以指定生产耐克、阿迪达斯和李宁牌子的鞋子。哪个鞋炒的火爆,老板就生产哪个,看形势生产。
UML图如下:
在这里插入图片描述
一个工厂类包含如下三要素:

  • 工厂类:工厂模式的核心类,会定义一个用于创建指定的具体实例对象的接口。
  • 抽象产品类:是具体产品类的继承的父类或实现的接口。
  • 具体产品类:工厂类所创建的对象就是此具体产品实例。

1.2 具体代码实现

/**
  * Shoes为鞋子的抽象类(基类),接口函数为Show(),用于显示鞋子广告。
  * NiKeShoes、AdidasShoes、LiNingShoes为具体鞋子的类,分别是耐克、阿迪达斯和李 宁鞋牌的鞋,它们都继承于Shoes抽象类。
  */
#include<iostream>
using namespace std;

// 鞋子抽象类
class Shoes
{
public:
    virtual ~Shoes() {}
    virtual void Show() = 0; // 纯虚函数在子类实现
};

// 耐克鞋子
class NiKeShoes : public Shoes
{
public:
    void Show()
    {
        std::cout << "我是耐克球鞋,我的广告语:Just do it" << std::endl;
    }
};

// 阿迪达斯鞋子
class AdidasShoes : public Shoes
{
public:
    void Show()
    {
        std::cout << "我是阿迪达斯球鞋,我的广告语:Impossible is nothing" << std::endl;
    }
};

// 李宁鞋子
class LiNingShoes : public Shoes
{
public:
    void Show()
    {
        std::cout << "我是李宁球鞋,我的广告语:Everything is possible" << std::endl;
    }
};


enum SHOES_TYPE
{
    NIKE,
    LINING,
    ADIDAS
};

// 总鞋厂
class ShoesFactory
{
public:
    // 根据鞋子类型创建对应的鞋子对象
    Shoes *CreateShoes(SHOES_TYPE type)
    {
        switch (type)
        {
        case NIKE:
            return new NiKeShoes();
            break;
        case LINING:
            return new LiNingShoes();
            break;
        case ADIDAS:
            return new AdidasShoes();
            break;
        default:
            return NULL;
            break;
        }
    }
};

int main()
{
    ShoesFactory shoesfactory;
    Shoes* ptr_nike_shoes = shoesfactory.CreateShoes(NIKE);
    if(ptr_nike_shoes != NULL)
    {
        ptr_nike_shoes->Show();
        delete ptr_nike_shoes;
        ptr_nike_shoes = NULL;
    } 
    
    Shoes* ptr_adidas_shoes = shoesfactory.CreateShoes(ADIDAS);
    if(ptr_adidas_shoes != NULL)
    {
        ptr_adidas_shoes->Show();
        delete ptr_adidas_shoes;
        ptr_adidas_shoes = NULL;
    }
    
    Shoes* ptr_lining_shoes = shoesfactory.CreateShoes(LINING);
    if(ptr_lining_shoes != NULL)
    {
        ptr_lining_shoes->Show();
        delete ptr_lining_shoes;
        ptr_lining_shoes = NULL;
    }

    return 0;    
}

2. 工厂方法模式

2.1 UML图

**类比情形:**现各类鞋子抄的非常火热,于是为了大量生产每种类型的鞋子,则要针对不同品牌的鞋子开设独立的生产线,那么每个生产线就只能生产同类型品牌的鞋。
UML图:
在这里插入图片描述
工厂方法模式的结构组成:

  • 抽象工厂类:工厂方法模式的核心类,提供创建具体产品的接口,由具体工厂类实现。
  • 具体工厂类:继承于抽象工厂,实现创建对应具体产品对象的方式。
  • 抽象产品类:它是具体产品继承的父类(基类)。
  • 具体产品类:具体工厂所创建的对象,就是此类。

2.2 具体代码实现

#include<iostream>
using namespace std;

// 鞋子抽象类
class Shoes
{
public:
    virtual ~Shoes() {}
    virtual void Show() = 0; // 纯虚函数在子类实现
};

// 耐克鞋子
class NiKeShoes : public Shoes
{
public:
    void Show()
    {
        std::cout << "我是耐克球鞋,我的广告语:Just do it" << std::endl;
    }
};

// 阿迪达斯鞋子
class AdidasShoes : public Shoes
{
public:
    void Show()
    {
        std::cout << "我是阿迪达斯球鞋,我的广告语:Impossible is nothing" << std::endl;
    }
};

// 李宁鞋子
class LiNingShoes : public Shoes
{
public:
    void Show()
    {
        std::cout << "我是李宁球鞋,我的广告语:Everything is possible" << std::endl;
    }
};


// 总鞋厂实现
class ShoesFactory
{
public:
    virtual Shoes *CreateShoes() = 0;
    virtual ~ShoesFactory() {}
};

// 耐克生产鞋厂
class NikeProducer : public ShoesFactory
{
public:
    Shoes *CreateShoes()
    {
        return new NiKeShoes();
    }
};

// 阿迪达斯生产鞋厂
class AdidasProductor : public ShoesFactory
{
public:
    Shoes *CreateShoes()
    {
        return new AdidasShoes();
    }
};

// 李宁生产鞋厂
class LiningProductor : public ShoesFactory
{
public:
    Shoes *CreateShoes()
    {
        return new LiNingShoes;
    }
};

int main()
{
    // ================ 生产耐克流程 ==================== //
    // 鞋厂开设耐克生产线
    ShoesFactory *niKeProducer = new NikeProducer();
    // 耐克生产线产出球鞋
    Shoes *nikeShoes = niKeProducer->CreateShoes();
    // 耐克球鞋广告喊起
    nikeShoes->Show();
    // 释放资源
    delete nikeShoes;
    delete niKeProducer;

    // ================ 生产阿迪达斯流程 ==================== //
    // 鞋厂开设阿迪达斯生产者
    ShoesFactory *adidasProducer = new AdidasProductor();
    // 阿迪达斯生产线产出球鞋
    Shoes *adidasShoes = adidasProducer->CreateShoes();
    // 阿迪达斯球鞋广喊起
    adidasShoes->Show();
    // 释放资源
    delete adidasShoes;
    delete adidasProducer;

    return 0;
}

3. 抽象工程模式

场景类比:鞋厂为了扩大了业务,不仅只生产鞋子,把运动品牌的衣服也一起生产了。

3.1 UML图

在这里插入图片描述

3.2 具体代码实现

抽象工厂模式的结构组成(和工厂方法模式一样):

  • 抽象工厂类:工厂方法模式的核心类,提供创建具体产品的接口,由具体工厂类实现。
  • 具体工厂类:继承于抽象工厂,实现创建对应具体产品对象的方式。
  • 抽象产品类:它是具体产品继承的父类(基类)。
  • 具体产品类:具体工厂所创建的对象,就是此类。
/*
Clothe和Shoes,分别为衣服和鞋子的抽象产品类。
NiKeClothe和NiKeShoes,分别是耐克衣服和耐克衣服的具体产品类。
*/
#include <iostream>
using namespace std;

// 衣服基类
class Clothe{
public:
    virtual void Show() = 0;
    virtual ~Clothe(){}
};

class NikeClothe : public Clothe{
public:
    void Show(){
        std::cout << "我是耐克衣服,时尚我最在行!" << std::endl;
    }
};

// 鞋子基类
class Shoes{
public:
    virtual void Show() = 0;
    virtual ~Shoes(){};
};

class NikeShoes : public Shoes{
public:
    void Show(){
        std::cout << "我是耐克球鞋,让你酷起来!" << std::endl;
    }
};

// 总厂
class Factory{
public:
    virtual Shoes *CreateShoes() = 0;
	virtual Clothe *CreateClothe() = 0;
    virtual ~Factory() {}
};

class NikeProducer: public Factory{
public:
    Shoes *CreateShoes(){
        return new NikeShoes();
    }
    Clothe *CreateClothe(){
        return new NikeClothe();
    }
};

int main(int argc, char *argv[]){
    Factory *nike_producer = new NikeProducer();
    Clothe *nike_clothe = nike_producer->CreateClothe();
    Shoes *nike_shoes = nike_producer->CreateShoes();
    nike_clothe->Show();
    nike_shoes->Show();
    delete nike_producer;
    delete nike_clothe;
    delete nike_shoes;
}

【参考连接】

https://zhuanlan.zhihu.com/p/83535678
https://zhuanlan.zhihu.com/p/83537599(进阶版工厂类)

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

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

相关文章

通过一张照片来定位拍摄地点和网站的域名 LA CTF 2023

简介 这次打ctf遇到了一个比较经典的osint类题目&#xff0c;在这里分享一下如何做此类题目 题目链接&#xff1a; https://platform.lac.tf/challs题目简介&#xff1a; 你能猜出这个猫天堂的名字吗&#xff1f;答案是此位置的网站域。例如&#xff0c;如果答案是 ucla&…

浅谈分布式锁的原理

1.业务场景引入 在进行代码实现之前&#xff0c;我们先来看一个业务场景&#xff1a; 系统A是一个电商系统&#xff0c;目前是一台机器部署&#xff0c;系统中有一个用户下订单的接口&#xff0c;但是用户下订单之前一定要去检查一下库存&#xff0c;确保库存足够了才会给用户…

SPINAND UBI 离线烧录 开发指南

SPINAND UBI 离线烧录 开发指南 1 概述 编写目的: 介绍Sunxi SPINand 烧写时的数据布局 2 名词解释 词义UBIunsorted block imagePEBphysical erase blockLEBlogical erase block PEB 和logical block 关系 1 PEB 1 logical block 1 logical block 2 physical blocks3 总…

React从入门到精通二

React从入门到精通之购物车案例1. 购物车需求说明使用到的data list2. 项目code1. 购物车需求说明 list data展示到列表中每个item的通过按钮来控制购买的数据量删除按钮可以删除当前的itemTotal Price计算当前购物车的总的价格 使用到的data list const books [{id: 1,name…

OAK相机深度流探测草莓距离

编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查看首发地址链接。 ▌前言 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是助手…

uniapp 悬浮窗(悬浮球、动态菜单、在其他应用上层显示) Ba-FloatBall

简介&#xff08;下载地址&#xff09; Ba-FloatBall 是一款在其他应用上层显示的悬浮球插件。支持展示菜单、拖动、自动贴边等&#xff1b;支持自定义样式。 支持添加展示菜单&#xff0c;可自定义&#xff08;不添加菜单&#xff0c;可只显示悬浮球&#xff09;支持自定义悬…

一口吃不成ChatGPT,复旦版MOSS服务器被挤崩后续

ChatGPT 是目前最先进的 AI&#xff0c;由于 ChatGPT 的训练过程所需算力资源大、标注成本高&#xff0c;此前国内暂未出现对大众开放的同类产品。 适逢ChatGPT概念正火&#xff0c;2 月 21 日&#xff0c;复旦团队发布首个中国版类 ChatGPT 模型「MOSS」&#xff0c;没想到瞬时…

Python-生成列表

1.生成列表使用列表前必须先生成列表。1.1使用运算符[ ]生成列表在运算符[ ]中以逗号隔开各个元素会生成包含这些元素的新列表。另外&#xff0c;如果[ ]中没有元素就会生成空列表示例>>> list01 [] >>> list01 [] >>> list02 [1, 2, 3] >>…

云、安全、网络三位一体,Akamai 推出大规模分布式边缘和云平台 Akamai Connected Cloud

出品 | CSDN 云计算 云服务市场规模在持续增长。 基于网络技术积累与优势&#xff0c;与布局边缘计算之后&#xff0c;巨头 Akamai 在继续推进它的技术与产品进程。近日&#xff0c;Akamai 正式推出大规模分布式边缘和云平台 Akamai Connected Cloud&#xff0c;包含云计算、安…

软考学习笔记(题目知识记录)

答案为 概要设计阶段 本题涉及软件工程的概念 软件工程的任务是基于需求分析的结果建立各种设计模型&#xff0c;给出问题的解决方案 软件设计可以分为两个阶段&#xff1a; 概要设计阶段和详细设计阶段 结构化设计方法中&#xff0c;概要设计阶段进行软件体系结构的设计&…

学生管理系统-课后程序(JAVA基础案例教程-黑马程序员编著-第六章-课后作业)

【案例6-2】 学生管理系统 【案例介绍】 1.任务描述 在一所学校中&#xff0c;对学生人员流动的管理是很麻烦的&#xff0c;本案例要求编写一个学生管理系统&#xff0c;实现对学生信息的添加、删除、修改和查询功能。每个功能的具体要求如下&#xff1a; 系统的首页&#…

视频技术基础知识

一、视频图像基础 像素&#xff1a;图像的基本单元&#xff0c;即一个带有颜色的小块分辨率&#xff1a;图像的大小或尺寸&#xff0c;用像素个数来表示。原始图像分辨率越高&#xff0c;图像就越清晰位深&#xff1a;存储每位像素需要的二进制位数&#xff1b;位深越大&#…

JAVA线程入门简介

线程入门简介什么是程序?什么是进程?什么是线程&#xff1f;单线程与多线程并发与并行线程的使用用java查看有多少个cpu创建线程的两种方式继承Thread类&#xff0c;重写run方法实现Runnable接口&#xff0c;重写run方法多线程机制为社么是start?源码解析什么是程序? 是为完…

防错料使用二维码解决方案 生产过程物料防错管理

生产过程中&#xff0c;物料的防错管理是非常重要的一环。它能够有效地防止物料错用或混用&#xff0c;从而降低产品质量问题的发生率&#xff0c;减少生产成本和生产周期&#xff0c;提高生产效率和产品质量。以下是生产过程物料防错管理的具体措施&#xff1a;1.明确物料标识…

SpringBoot Data Redis来操作Redis

SpringBoot Data Redis来操作Redis1、Redis启动Redis主要的作用安装的位置启动2、Java中来操作Redis3、Spring Data Redis(重点)测试连接配置Redis序列化器redisTemplate操作常见数据类型通用操作&#xff0c;针对不同的数据类型都可以操作申明&#xff1a; 未经许可&#xff0…

浅谈Springboot自动化配置原理

文章目录1.前言2.SpringBoot的入口3.SpringBootApplication背后的秘密4.Configuration5.ComponentScan扫描bean6.EnableAutoConfiguration7.自动配置生效1.前言 不论在工作中&#xff0c;亦或是求职面试&#xff0c;Spring Boot已经成为我们必知必会的技能项。除了某些老旧的政…

java面试题-JUC线程池

1.FutureTask的作用?FutureTask 是 Java 并发编程中的一个类&#xff0c;用于异步执行任务并获取其结果。它实现了 Future 和 Runnable 接口&#xff0c;因此可以作为一个可运行的任务提交给 Executor 执行&#xff0c;也可以通过 Future 接口获取任务执行的结果。FutureTask …

2023年DAMA-CDGA/CDGP数据治理认证选择哪家机构好?

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

将整数数组变为浮点型数组的np.asfarray()方法

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 将整数数组转换为浮点型数组 np.asfarray() 选择题 关于以下代码说法错误的一项是? import numpy as np a1 np.array([1,2,3]) print("【显示】a1",a1) print("【执行】a…

网络工程(一) 简单的配置

网络工程 简单的配置 需求 两台交换机 两台路由器 两台PC AR1配置静态路由 system-view [HUAWEI]sysname ar1 [ar1]interface g 0/0/0 [ar1-G…0/0/0]ip address 192.168.2.1 24 [ar1-G…0/0/0]quit [ar1]interface g 0/0/1 [ar1-G…0/0/1]ip address 192.168.3.1 24 [ar1-G…