首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

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

编程知识
2024年07月17日 16:39

定义

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

为什么使用抽象工厂模式

  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;
}

 

From:https://www.cnblogs.com/best-doraemon/p/18307485
本文地址: http://www.shuzixingkong.net/article/130
0评论
提交 加载更多评论
其他文章 iOS开发基础102-后台保活方案
iOS系统在后台执行程序时,有严格的限制,为了更好地管理资源和电池寿命,iOS会限制应用程序在后台的运行时间。然而,iOS提供了一些特定的策略和技术,使得应用程序可以在特定场景下保持后台运行(即“后台保活”)。以下是iOS中几种常见的后台保活方案,并附上示例代码: 一、后台任务 利用beginBac
玄机-第一章 应急响应- Linux入侵排查
玄机-第一章 应急响应- Linux入侵排查 简介 账号:root 密码:linuxruqin ssh root@IP 1.web目录存在木马,请找到木马的密码提交 2.服务器疑似存在不死马,请找到不死马的密码提交 3.不死马是通过哪个文件生成的,请提交文件名 4.黑客留下了木马文件,请找出黑客的服
玄机-第一章 应急响应- Linux入侵排查 玄机-第一章 应急响应- Linux入侵排查 玄机-第一章 应急响应- Linux入侵排查
给博客园的几点现实建议
博客园又遇到了生存危机,老实说,意料之中。 因为,付费会员就能支撑一个完全免费的网站,这种商业模式还没成功过。 博客园的理念我完全理解,但是多听听现实性的建议才是正道。 第一计:祸水东引 博客园不接广告这种坚持我理解,但是,你就不能注册个小号? 比如注册个:hotspot.dev&#160;开发热点
企业级环境部署:在 Linux 服务器上如何搭建和部署 Python 环境?
在大部分企业里,自动化测试框架落地都肯定会集成到Jenkins服务器上做持续集成测试,自动构建以及发送结果到邮箱,实现真正的无人值守测试。 不过Jenkins搭建一般都会部署在公司的服务器上,不会在私人电脑里,而服务器大部分都是Linux操作系统的。所以,我们如果要在Linux上的Jenkins服务
企业级环境部署:在 Linux 服务器上如何搭建和部署 Python 环境? 企业级环境部署:在 Linux 服务器上如何搭建和部署 Python 环境? 企业级环境部署:在 Linux 服务器上如何搭建和部署 Python 环境?
给博客园的寄语
39岁大龄C#开发程序员,今天看到了博客园的求救信,内心不禁一阵触动,故而写下这一篇文章,以此来缅怀我和博客园一起走过的青春。 博客园虽然之前也发过几次求救了,但当时都觉得不至于吧,因为想着坚持这么多年用户基数不小的网站,再怎样维持生存应该不难吧。但这次看到了博客园团队为了运营不惜在借贷维持,我才觉
如何解决 CentOS 7 官方 yum 仓库无法使用的问题
一、背景介绍 2024 年 7 月 1 日,在编译基于 CentOS 7.6.1810 镜像的 Dockerfile 过程中,执行 yum install 指令时,遇到了错误:Could not resolve host: mirrorlist.centos.org; Unknown error。
AI时代你一定要知道的Agent概念
这两年,随着人工智能(AI)和计算能力的发展,AI应用的落地速度大大加快。以ChatGPT为代表的AI应用迅速火遍全球,成为打工人的常用工具。紧接着,多模态、AI Agent等各种高大尚的名词也逐渐进入大众视野,吸引了大量关注。那么,到底什么是AI Agent?下文半支烟将带你详细了解这个概念。 1
AI时代你一定要知道的Agent概念 AI时代你一定要知道的Agent概念
njs最详细的入门手册:Nginx JavaScript Engine
NJS是Nginx的Javascript引擎,具有极度轻量小巧,强大性能等特色,是全部同步的nginx-Lua替代品 但是网上教程太少了,无奈花一天时间写了这篇文章,讲了NJS的常见用法,希望能帮到大家
njs最详细的入门手册:Nginx JavaScript Engine