首页 > 其他分享 >设计模式之抽象工厂模式(学习笔记)

设计模式之抽象工厂模式(学习笔记)

时间:2024-07-17 17:41:58浏览次数:16  
标签:std const 笔记 工厂 抽象 产品 shared 设计模式

定义

抽象工厂模式是一种创建型设计模式,它提供一个接口,用于创建一系列相关或依赖的对象,而无需指定它们的具体类。抽象工厂模式将对象的创建过程抽象化,允许子类通过实现具体工厂类来定制对象的创建。

为什么使用抽象工厂模式

  1. 产品族的一致性

    • 抽象工厂模式确保同一产品族中的对象之间的一致性。
  2. 部分遵循开闭原则

    • 可以通过添加新的具体工厂类来扩展新的产品族,而不需要修改现有代码,符合开闭原则。
    • 增加新的产品类型时,需要修改抽象工厂接口及其所有具体实现,不完全符合开闭原则。
  3. 隐藏对象创建细节

    • 抽象工厂模式将具体产品的创建过程隐藏起来,客户端只需要使用工厂提供的接口来获取对象。

实现步骤

  1. 定义抽象产品类

    • 定义所有具体产品类的共同接口,客户端将通过这个接口来使用具体产品。
  2. 实现具体产品类

    • 实现产品接口的具体产品类,这些类包含了产品的实际业务逻辑。
  3. 定义抽象工厂类

    • 定义一个抽象工厂类,包含用于创建一系列相关或依赖对象的抽象方法,子类将实现这些方法来创建具体产品对象。
  4. 实现具体工厂类

    • 继承抽象工厂类并实现其抽象方法,具体工厂类负责创建具体产品对象。

优缺点和适用场景

优点

  1. 产品族的一致性

    • 确保同一产品族中的对象之间的一致性。
  2. 部分符合开闭原则

    • 可以通过添加新的具体工厂类来扩展新的产品族,符合开闭原则。
  3. 隐藏对象创建细节

    • 客户端无需知道具体产品的创建过程,只需要通过工厂接口获取对象。

缺点

  1. 增加系统复杂性

    • 引入了更多的类,增加了系统的复杂性。
  2. 不完全符合开闭原则

    • 增加新的产品类型时,需要修改抽象工厂接口及其所有具体实现,不完全符合开闭原则。

适用场景

  1. 系统需要创建一系列相关或依赖的对象

    • 当系统需要创建一系列相关或依赖的对象,并且确保这些对象之间的一致性时,适合使用抽象工厂模式。
  2. 产品族扩展

    • 当系统需要通过增加新的产品族来扩展功能,而不需要修改现有代码时,适合使用抽象工厂模式。

简单工厂模式、工厂方法模式与抽象工厂模式的比较

特性 简单工厂模式 工厂方法模式 抽象工厂模式
创建对象的职责 单一工厂类负责所有产品创建 子类决定创建具体对象 子类决定创建一系列相关对象
遵循开闭原则 不符合,增加新产品需修改工厂类 符合,增加新产品无需修改工厂类 部分符合,增加产品族符合
系统复杂性 较低 中等 较高
产品族一致性支持 不支持 不支持 支持

咖啡店的例子

我们可以使用抽象工厂模式来实现一个咖啡店系统,该系统可以创建不同种类的咖啡及其配套的杯子和勺子。
#include <iostream>
#include <memory>
#include <string>


// 抽象产品类:咖啡
class Coffee {
public:
    virtual ~Coffee() {}
    virtual std::string getDescription() const = 0;
    virtual double cost() const = 0;
};


// 具体产品类:美式咖啡
class Americano : public Coffee {
public:
    std::string getDescription() const override {
        return "Americano";
    }
    double cost() const override {
        return 5.0;
    }
};


// 抽象产品类:咖啡杯
class CoffeeCup {
public:
    virtual ~CoffeeCup() {}
    virtual std::string getDescription() const = 0;
};


// 具体产品类:美式咖啡杯
class AmericanoCup : public CoffeeCup {
public:
    std::string getDescription() const override {
        return "Americano Cup";
    }
};


// 抽象产品类:咖啡勺
class CoffeeSpoon {
public:
    virtual ~CoffeeSpoon() {}
    virtual std::string getDescription() const = 0;
};


// 具体产品类:美式咖啡勺
class AmericanoSpoon : public CoffeeSpoon {
public:
    std::string getDescription() const override {
        return "Americano Spoon";
    }
};


// 抽象工厂类
class CoffeeFactory {
public:
    virtual ~CoffeeFactory() {}
    virtual std::shared_ptr<Coffee> createCoffee() const = 0;
    virtual std::shared_ptr<CoffeeCup> createCoffeeCup() const = 0;
    virtual std::shared_ptr<CoffeeSpoon> createCoffeeSpoon() const = 0;
};


// 具体工厂类:美式咖啡工厂
class AmericanoFactory : public CoffeeFactory {
public:
    std::shared_ptr<Coffee> createCoffee() const override {
        return std::make_shared<Americano>();
    }
    std::shared_ptr<CoffeeCup> createCoffeeCup() const override {
        return std::make_shared<AmericanoCup>();
    }
    std::shared_ptr<CoffeeSpoon> createCoffeeSpoon() const override {
        return std::make_shared<AmericanoSpoon>();
    }
};


int main() {
    // 创建美式咖啡及其配套杯子和勺子
    std::shared_ptr<CoffeeFactory> americanoFactory = std::make_shared<AmericanoFactory>();
    std::shared_ptr<Coffee> americano = americanoFactory->createCoffee();
    std::shared_ptr<CoffeeCup> americanoCup = americanoFactory->createCoffeeCup();
    std::shared_ptr<CoffeeSpoon> americanoSpoon = americanoFactory->createCoffeeSpoon();


    std::cout << "Coffee: " << americano->getDescription() << ", Cost: " << americano->cost() << std::endl;
    std::cout << "Cup: " << americanoCup->getDescription() << std::endl;
    std::cout << "Spoon: " << americanoSpoon->getDescription() << std::endl;


    return 0;
}

 

标签:std,const,笔记,工厂,抽象,产品,shared,设计模式
From: https://www.cnblogs.com/best-doraemon/p/18307485

相关文章

  • 设计模式之代理模式
    定义代理模式(ProxyPattern)是软件工程中的一种设计模式,它属于结构型模式,用于在不直接访问实际对象的情况下,通过一个或多个代理对象来间接访问某个对象或执行某些操作。目的这种模式的主要目的是:控制访问:代理可以在访问真实对象之前或之后添加额外的操作,如权限检查、延迟初始......
  • 19集 两款ESP32开发板如何选择?-《MCU嵌入式AI开发笔记》
    19集两款ESP32开发板我们用哪款?-《MCU嵌入式AI开发笔记》有两款ESP32的开发板分别是ESP32S3和C3的,我们该如何选择?1、ESP32-S3-BOX-3在乐鑫官网上,https://www.espressif.com.cn/zh-hans/products/devkits有ESP32S3BOX开发板,链接如下:https://github.com/espressif/es......
  • 机器学习实战笔记2特征编码
    特征编码我们要做的就是将数据的一列目标字段编码importpandasaspddata={'size':['XL','L','M','L','M'],'color':['red','green','blue','green','red']......
  • 机器学习实战笔记3乳腺癌数据集
    乳腺癌数据集1.加载数据集fromsklearn.datasetsimportload_breast_cancerbreast_cancer=load_breast_cancer()print(breast_cancer["DESCR"])输出乳腺癌数据集的详细描述,通常包括数据集的来源、特征的解释、数据集的版权信息等。2.查看data和targetdata=breast_can......
  • 机器学习实战笔记4线性回归
    线性回归首先看一下线性回归方程,就是用代码来编写方程1.numpy正规方程线性回归importnumpyasnpimportpandasaspddf=pd.DataFrame({'years':[1,2,3,4,5,6],'salary':[4000,4250,4500,4750,5000,5250]})df生成dfm=len(df)m输出:6x1=df......
  • 负载均衡-Ribbon-微服务核心组件【分布式微服务笔记03】
    负载均衡-Ribbon-微服务核心组件【分布式微服务笔记03】负载均衡-Ribbon基本介绍SpringCloudRibbon是基于NetflixRibbon实现的一套客户端负载均衡的工具。Ribbon主要功能是提供客户端负载均衡算法和服务调用Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等......
  • CDQ 分治学习笔记
    CDQ分治的流程大致是将对于区间\([l,r]\)中点\(x,y\)的计数分为两类处理:\(x,y\)均位于\([l,mid]\)或\([mid+1,r]\)中,这样的点对贡献可以递归解决。\(x,y\)分别位于\([l,mid]\)和\([mid+1,r]\)中,这样的点对通过一些操作来统计贡献。显然这两类贡献之和即为......
  • 恢复 iPhone 上误删除笔记的 5 种绝佳方法
    您想知道如何恢复iPhone上误删除的笔记吗?阅读本指南,了解5种简单方法,可直接或通过iTunes/iCloud备份检索iPhone上丢失或删除的笔记。iPhoneNotes应用程序提供了一种方便的方式来记录重要信息,包括文本、图片、链接和许多其他类型的信息。但是,各种原因仍可能导致iPhon......
  • PYTHON学习笔记(二、python结构语句)
    (1)顺序语句结构neme=input('请输入你的名字:')year=eval(input('请输入你的年龄:'))number=eval(input('请输入你的中奖号码:'))print('我爱中国!!')print('我爱CSDN!!')运行终端后,我可以看到以下结果:(2)分支语句结构(if语句的基本格式)neme=input('请输入你的名字:......
  • 服务注册/发现-Eureka-微服务核心组件【分布式微服务笔记02】
    服务注册/发现-Eureka-微服务核心组件【分布式微服务笔记02】服务注册/发现-Eureka目前主流的服务注册&发现的组件是Nacos,但是Eureka作为一个老牌经典的服务注册&发现技术还是有必要学习一下,原因:一些早期的分布式微服务项目使用的是Eureka,在工作中,完全有可能遇到.后......