设计模式从入门到精通之(二)抽象工厂模式

news2024/12/26 23:57:34

抽象工厂模式:不同工厂背后的协作秘密

在上一期中,我们聊到了工厂模式,讲述了如何用一家咖啡店来帮我们制作不同类型的咖啡。那么,如果你不仅需要咖啡,还需要配套的甜品,比如蛋糕或饼干,这时应该怎么办呢?今天我们将引出一个进阶版的工厂模式:抽象工厂模式,来解决这个问题。


1. 什么是抽象工厂模式?

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一组用于创建相关或依赖对象的接口,而无需指定它们的具体类。换句话说,抽象工厂模式就像一个连锁品牌,你可以在这个品牌的任何分店下单,无论是咖啡、蛋糕还是饼干,所有的产品都是相互匹配的。


2. 用现实中的故事引出抽象工厂模式

还是用咖啡店的例子。假设你今天去咖啡店喝咖啡,发现菜单上不仅有咖啡,还有甜品搭配,比如:

  • 美式咖啡 + 巧克力曲奇
  • 拿铁咖啡 + 芝士蛋糕

你只需要告诉咖啡师你想要哪种套餐,他们就会为你准备好匹配的饮品和甜品,而不需要你逐一选择。这背后就是抽象工厂的思想:

  1. 一个工厂负责生产一组相关的产品。
  2. 通过选择工厂,统一获取搭配好的产品。

3. 抽象工厂模式的代码实现

我们用代码来模拟这个场景,看看如何用抽象工厂模式来制作咖啡和甜品。

3.1 抽象产品类

首先,定义两个抽象产品:咖啡和甜品。

// 抽象咖啡类
abstract class Coffee {
    public abstract String getName();
}

// 抽象甜品类
abstract class Dessert {
    public abstract String getName();
}

3.2 具体产品类

实现不同种类的咖啡和甜品。

// 美式咖啡
class AmericanCoffee extends Coffee {
    @Override
    public String getName() {
        return "American Coffee";
    }
}

// 拿铁咖啡
class LatteCoffee extends Coffee {
    @Override
    public String getName() {
        return "Latte Coffee";
    }
}

// 巧克力曲奇
class ChocolateCookie extends Dessert {
    @Override
    public String getName() {
        return "Chocolate Cookie";
    }
}

// 芝士蛋糕
class Cheesecake extends Dessert {
    @Override
    public String getName() {
        return "Cheesecake";
    }
}

3.3 抽象工厂

定义一个抽象工厂接口,负责创建相关的咖啡和甜品。

interface DessertFactory {
    Coffee createCoffee();
    Dessert createDessert();
}

3.4 具体工厂类

实现具体的工厂类,每个工厂负责创建一组相关的产品。

// 美式风味工厂
class AmericanFactory implements DessertFactory {
    @Override
    public Coffee createCoffee() {
        return new AmericanCoffee();
    }

    @Override
    public Dessert createDessert() {
        return new ChocolateCookie();
    }
}

// 意式风味工厂
class ItalianFactory implements DessertFactory {
    @Override
    public Coffee createCoffee() {
        return new LatteCoffee();
    }

    @Override
    public Dessert createDessert() {
        return new Cheesecake();
    }
}

3.5 客户端代码

客户端只需要选择一个工厂,就可以得到匹配的产品。

public class CoffeeShop {
    public static void main(String[] args) {
        // 创建美式风味工厂
        DessertFactory americanFactory = new AmericanFactory();
        Coffee americanCoffee = americanFactory.createCoffee();
        Dessert chocolateCookie = americanFactory.createDessert();
        System.out.println("Order: " + americanCoffee.getName() + " and " + chocolateCookie.getName());

        // 创建意式风味工厂
        DessertFactory italianFactory = new ItalianFactory();
        Coffee latteCoffee = italianFactory.createCoffee();
        Dessert cheesecake = italianFactory.createDessert();
        System.out.println("Order: " + latteCoffee.getName() + " and " + cheesecake.getName());
    }
}

运行结果:

Order: American Coffee and Chocolate Cookie
Order: Latte Coffee and Cheesecake

4. 抽象工厂模式的优缺点

优点:

  1. 产品族一致性:保证创建的产品彼此匹配。
  2. 可扩展性强:可以很方便地新增一个产品族(比如法式风味工厂)。
  3. 解耦:客户端代码与具体产品类完全解耦。

缺点:

  1. 复杂性提高:系统中会增加更多的类。
  2. 不够灵活:增加新产品(而非产品族)时,需要修改所有工厂类。

5. 总结

抽象工厂模式是工厂模式的升级版,适用于需要创建"一组相关产品"的场景。在实际开发中,它可以帮助我们更好地管理复杂的依赖关系,同时保持代码的高内聚和低耦合。

在下一篇专栏中,我们将介绍另一个重要的设计模式:单例模式,看看如何确保你的工厂在系统中只存在一个实例。


思考问题:
如果你需要为每个工厂增加一个新产品(比如茶饮),如何修改代码才能保持现有的结构?欢迎在评论区讨论!

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

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

相关文章

android 登录界面编写

1、登录页面实现内容 1.实现使用两个EditText输入框输入用户名和密码。 2.使用CheckBox控件记住密码功能。 3.登录时候,验证用户名和密码是否为空。 4.当前CheckBox控件记住密码勾上时,使用SharedPreferences存储用户名和密码。 5.登录时候使用Prog…

多目标应用(一):多目标麋鹿优化算法(MOEHO)求解10个工程应用,提供完整MATLAB代码

一、麋鹿优化算法 麋鹿优化算法(Elephant Herding Optimization,EHO)是2024年提出的一种启发式优化算法,该算法的灵感来源于麋鹿群的繁殖过程,包括发情期和产犊期。在发情期,麋鹿群根据公麋鹿之间的争斗分…

设计模式——装饰模式

文章目录 1.定义2. 结构组成3. 组合模式结构4. 示例代码5. 模式优势6. 应用场景 1.定义 装饰模式就像是给你的对象穿上不同的 “时尚服装”,在程序运行时,你可以随意地给对象搭配各种 “服装” 来增加新的功能,而且完全不用对对象本身的 “身…

python+reportlab创建PDF文件

目录 字体导入 画布写入 创建画布对象 写入文本内容 写入图片内容 新增页 画线 表格 保存 模板写入 创建模板对象 段落及样式 表格及样式 画框 图片 页眉页脚 添加图形 构建pdf文件 reportlab库支持创建包含文本、图像、图形和表格的复杂PDF文档。 安装&…

<数据集>芝麻作物和杂草识别数据集<目标检测>

数据集下载链接 <数据集>芝麻作物和杂草识别数据集<目标检测>https://download.csdn.net/download/qq_53332949/90181548数据集格式:VOCYOLO格式 图片数量:1300张 标注数量(xml文件个数):130…

Python爬虫:速卖通aliexpress商品详情获取指南

在数字化时代,数据已成为企业竞争的关键资源。对于电商行业而言,获取竞争对手的商品信息是洞察市场动态、优化自身产品策略的重要手段。速卖通(AliExpress)作为全球知名的跨境电商平台,其商品信息的获取自然成为了许多…

【绿色碳中和】全国各省各地级市绿色金融数据(1990-2022年)

数据介绍:绿色金融指数采用熵值法进行测算,综合评价体系如下: 绿色金融指标体系 二级指标 三级指标 指标说明 绿色信贷 高能耗行业利息支出占比 六大高能耗行业利息支出/工业总利息 A股上市公司环保企业新增银行贷款占比 …

React引入Echart水球图

在搭建React项目时候,遇到了Echart官方文档中没有的水球图,此时该如何配置并将它显示到项目中呢? 目录 一、拓展网站 二、安装 三、React中引入 1、在components文件夹下新建一个组件 2、在组件中引入 3、使用水波球组件 一、拓展网站 …

Vue使用Tinymce 编辑器

目录 一、下载并重新组织tinymce结构二、使用三、遇到的坑 一、下载并重新组织tinymce结构 下载 npm install tinymce^7 or yarn add tinymce^7重构目录 在node_moudles里找到tinymce文件夹,把里面文件拷贝一份放到public下,如下: -- pub…

STM32-笔记10-手写延时函数(SysTick)

1、什么是SysTick Systick,即滴答定时器,是内核中的一个特殊定时器,用于提供系统级的定时服务。该定时器是一个24位的倒计数定时器‌。它从设定的初值(即重载值)开始计数,每经过一个系统时钟周期&#xff0…

Elasticsearch-脚本查询

脚本查询 概念 Scripting是Elasticsearch支持的一种专门用于复杂场景下支持自定义编程的强大的脚本功能,ES支持多种脚本语言,如painless,其语法类似于Java,也有注释、关键字、类型、变量、函数等,其就要相对于其他脚本高出几倍的性…

C项目 天天酷跑(下篇)

上篇再博客里面有&#xff0c;接下来我们实现我们剩下要实现的功能 文章目录 碰撞检测 血条的实现 积分计数器 前言 我们现在要继续优化我们的程序才可以使这个程序更加的全面 碰撞的检测 定义全局变量 实现全局变量 void checkHit() {for (int i 0; i < OBSTACLE_C…

设计模式详解(建造者模式)

1、简述 建造者模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;它通过将对象的构造过程与表示分离&#xff0c;使得相同的构造过程可以创建不同的表示。建造者模式尤其适用于创建复杂对象的场景。 2、什么是建造者模式&#xff1f; 建造者模式…

【Git 常用操作:pull push】

Git 基本概念 Git 是一个先进的开源的分布式版本控制系统&#xff0c;常用于管理工作内容、项目代码等功能。 Git 工作流程 图片来源&#xff1a;https://www.runoob.com/git/git-basic-operations.html 说明&#xff1a; workspace&#xff1a;工作区staging area&#xff…

个人笔记:ORM数据库框架EFCore使用示例,运行通过,附源码

个人笔记&#xff1a;ORM数据库框架EFCore使用示例&#xff0c;运行通过&#xff0c;附源码 0.新建项目1. 设置环境1.1. 添加 NuGet 包1.2. 创建模型类 2. 创建上下文类3. 创建数据库和表3.1. 启用迁移3.2. 更新数据库 4. 插入数据5. 查询数据6. 更新数据7. 删除数据8. 完整示例…

IndexOf Apache Web For Liunx索引服务器部署及应用

Apache HTTP Server 是一款广泛使用的开源网页服务器软件,它支持多种协议,包括 HTTP、HTTPS、FTP 等 IndexOf 功能通常指的是在一个目录中自动生成一个索引页面的能力,这个页面会列出该目录下所有的文件和子目录。比如网上经常看到的下图展现的效果,那么接下来我们就讲一下…

Ubuntu 24.04.1 LTS快速源码安装postgresql15

虽然在Ubuntu中我们可以通过apt直接获取postgresql安装&#xff0c;但有些时候&#xff0c;为了自行配置postgresql安装路径和部分组件参数&#xff0c;我们需要源码安装postgresql。今天我们就通过源码编译postgresql15源码进行安装。 一、获取安装包 我们登录postgresql官网…

数据结构之栈,队列,树

目录 一.栈 1.栈的概念及结构 2.栈的实现 3.实现讲解 1.初始化栈 2.销毁栈 3.压栈 4.出栈 5.返回栈顶元素 6.返回栈内元素个数 7.判断栈内是否为空 二.队列 1.队列的概念及结构 2.队列的实现 3.实现讲解 1.初始化队列 2.销毁队列 3.单个成员入队列 4.单个成员…

Git基本操作快速入门(30min)

Git基本操作快速入门&#xff08;30min&#xff09; 文章目录 Git基本操作快速入门&#xff08;30min&#xff09;1. 建立本地仓库2. 本地仓库链接到远端仓库3. 将本地仓库推送到远端4. Git常用命令 作为一名程序员&#xff0c;使用Github来进行代码的版本管理是必修课&#xf…

汽车IVI中控开发入门及进阶(42):OpenVG

概览: OpenVG是一个无版权、跨平台的API,它为高级用户界面和矢量图形库(如SVG)提供了一个低级硬件加速接口。OpenVG主要针对需要便携式加速高质量矢量图形以获得引人注目的用户界面和文本的消费电子产品、手持设备、可穿戴设备和汽车设备,同时使硬件加速能够在非常低的功…