【设计模式-5】抽象工厂模式的代码实现及使用场景

 前面我们了解到工厂方法模式通过引入抽象工厂的概念,使得产品对象的创建可以依赖于具体工厂,但是这种设计模式最大的问题是会造成类的数量爆炸式增长。对于这个问题,抽象工厂模式通过引入两个新的概念:产品等级与产品簇,来解决工厂方法的工厂类过多的问题。

 在正式进入抽象工厂模式学习之前,我们先来了解一下这两个概念:

  • 产品等级(分类): 产品等级可以理解为一类相同的产品,可以理解为抽象产品下的子类实现。具体表现为,比如电视机是一类产品,可以有海尔电视机、小米电视机、TCL电视机等,这个电视系列就可以理解为一个产品等级。
  • 产品簇: 产品簇可以理解为一组不同等级产品的组合,但是这些产品都是一个工厂的产品。具体表现为,比如海尔工厂生产电视机、电冰箱、洗衣机等,这些海尔生产的电器产品组合在一起形成一个产品簇。
    在这里插入图片描述

1. 概述

抽象工厂模式:为创建一组对象提供了一种解决方案,与工厂方法模式相比,抽象工厂模式中的工厂角色不只创建一种产品,而是负责一个产品簇对象的生产。抽象工厂模式是一种创建型的设计模式。
 在抽象工厂模式中,包含4个角色:

  • 抽象工厂角色: 它声明了一组用于创建一个产品簇的方法,每个方法对应一种产品,它可以是接口或者抽象类。
  • 具体工厂角色: 它实现了在抽象工厂中声明的创建具体产品的方法,生成一组具体的产品,这些产品组成一个产品簇,每种产品都属于一个产品等级。
  • 抽象产品角色: 它是每种产品的抽象,可以是接口或者抽象类,声明产品的业务方法。
  • 具体产品角色: 它继承抽象产品,实现了抽象产品中声明的业务方法,多个具体产品可以组成一个产品簇。

2. 代码实现

 抽象工厂模式是一类比较复杂的对象创建型模式,复杂的地方在于产品簇和产品等级维度的划分,有时候业务界限比较模糊,这些都高度依赖于开发人员的业务素养和代码积累等。

 接下来我们就以刚才海尔、美的工厂生产冰箱和电视机的产品为例子,写一个demo:

  • 抽象的工厂接口
public interface AbstractFactory {// 创建电视的方法TelevisionProduct createTelevisionProduct();// 创建冰箱的方法RefrigeratorProduct createRefrigeratorProduct();
}
  • 具体的实现类
/*** 美的生产工厂*/
class MideaFactory implements AbstractFactory {// 实现创建电视的方法@Overridepublic TelevisionProduct createTelevisionProduct() {return new MideaTelevisionProduct();}// 创建冰箱的方法@Overridepublic RefrigeratorProduct createRefrigeratorProduct() {return new MideaRefrigeratorProduct();}
}/*** 海尔生产工厂*/
class HairFactory implements AbstractFactory {// 实现创建电视的方法@Overridepublic TelevisionProduct createTelevisionProduct() {return new HairTelevisionProduct();}// 创建冰箱的方法@Overridepublic RefrigeratorProduct createRefrigeratorProduct() {return new HairRefrigeratorProduct();}
}
  • 抽象的产品角色
// 产品簇-冰箱产品
public interface RefrigeratorProduct {void displayColor();
}// 产品簇-电视机产品
public interface TelevisionProduct {void displayShape();
}
  • 具体的产品角色
// 海尔冰箱
public class HairRefrigeratorProduct implements RefrigeratorProduct {@Overridepublic void displayColor() {System.out.println("海尔冰箱");}
}
// 海尔电视机
public class HairTelevisionProduct implements TelevisionProduct{@Overridepublic void displayShape() {System.out.println("海尔电视机");}
}
// 美的冰箱
public class MideaRefrigeratorProduct implements RefrigeratorProduct {@Overridepublic void displayColor() {System.out.println("美的冰箱");}
}
// 美的电视机
public class MideaTelevisionProduct implements TelevisionProduct{@Overridepublic void displayShape() {System.out.println("美的电视机");}
}
  • 客户端及运行结果
class Client {public static void main(String[] args) {// 美的工厂的产品簇AbstractFactory mideaFactory = new MideaFactory();RefrigeratorProduct mideaRefrigerator = mideaFactory.createRefrigeratorProduct();mideaRefrigerator.displayColor();TelevisionProduct mideaTelevision = mideaFactory.createTelevisionProduct();mideaTelevision.displayShape();System.out.println("========分割线========");// 海尔工厂的产品簇HairFactory hairFactory = new HairFactory();RefrigeratorProduct hairRefrigerator = hairFactory.createRefrigeratorProduct();hairRefrigerator.displayColor();TelevisionProduct hairTelevision = hairFactory.createTelevisionProduct();hairTelevision.displayShape();}
}
美的冰箱
美的电视机
========分割线========
海尔冰箱
海尔电视机

3. UML类图

 基于上面的这个抽象工厂的Demo,我们来画一下抽象工厂模式的UML类图。

在这里插入图片描述

4. 总结

 抽象工厂模式是工厂方法模式的进一步延伸,在一些框架和API的类库设计中都得到了广泛的使用。下面,我们来总结一下这种设计模式的优缺点

4.1 优点

  • 对象的创建和使用过程分离,用户无需关注对象的创建,只需要会使用工厂模式即可;
  • 抽象工厂模式使得同一个产品簇的对象可以同时被创建,可以使得用户能同时使用这一个产品簇的对象;
  • 产品簇维度的扩展很方便,直接增加实现即可,符合开闭原则。

4.2 缺点

 抽象工作的缺点也很明显,像扩展产品分类是比较麻烦的,涉及到多个接口和类的关联修改,违背了开闭原则。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

219. 存在重复元素

给你一个整数数组 nums 和一个整数 k &#xff0c;判断数组中是否存在两个 不同的索引 i 和 j &#xff0c;满足 nums[i] nums[j] 且 abs(i - j) < k 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;num…

Docker基础学习(配置、命令)

镜像加速 登录阿里云 docker run hello-world分析命令&#xff1a; 开始–>docker在本机中寻找镜像–>有–>以该镜像为模版生产容器实例运行&#xff1b; 开始–>docker在本机中寻找镜像–>无–>去远端下载镜像并运行&#xff0c;若远端无此镜像则返回错误…

2023年终总结(脚踏实地,仰望星空)

回忆录 2023年&#xff0c;经历非常多的大事情&#xff0c;找工作、实习、研究生毕业、堂哥结婚、大姐买车、申博、读博、参加马拉松&#xff0c;有幸这一年全家人平平安安&#xff0c;在稳步前进。算是折腾的一年&#xff0c;杭州、赣州、武汉、澳门、珠海、遵义来回跑。完成…

ChatGPT怎么帮我上班的

1.解放生产力 1&#xff09;标准格式&#xff0c;完美输出。GPT对于公文等具有一定标准格式的文件&#xff0c;可以进行完美仿写&#xff0c;随随便便以假乱真那都是小菜一碟&#xff0c;这对于经常要开展规范成文的人来说&#xff0c;简直就是个福音&#xff0c;只要前期调教…

厚积薄发11年,鸿蒙究竟有多可怕

​12月20日中国工程院等权威单位发布《2023年全球十大工程成就》。本次发布的2023全球十大工程成就包括“鸿蒙操作系统”在内。入围的“全球十大工程成就”&#xff0c;主要指过去五年由世界各国工程科技工作者合作或单独完成且实践验证有效的&#xff0c;并且已经产生全球影响…

Databend 的安装配置和使用

介绍 Databend 是一个内置在 Rust 中的开源、弹性和工作负载感知的云数据仓库&#xff0c;为 Snowflake 提供了具有成本效益的替代方案&#xff0c;专门对最大的数据集进行复杂分析而设计。 性能&#xff1a; 在存储对象上&#xff0c;能快速进行数据分析。没有索引和分区&a…

C-数据类型的内存表示

目录 刷语法题 把字符串转换成整数 1时遇到数值溢出问题&#xff0c;借此机会回顾一下相关知识。 以下ChatGPT的回复&#xff1a; 数据类型的二进制表示是什么&#xff1f; 数据类型的二进制表示是指如何在计算机内存中用二进制&#xff08;即由 0 和 1 组成&#xff09;的形式…

XMLHttpRequest

目录 创建 XMLHttpRequest 对象配置请求设置请求头发送请求处理响应取消请求loadend XMLHttpRequest 是一个 JavaScript API&#xff0c;它提供了一种在客户端与服务器进行数据交换的方式&#xff0c;可以在不刷新页面的情况下异步更新部分网页内容。虽然现代开发中越来越多地使…

深入浅出XTTS:Oracle数据库迁移升级利器

演讲大纲&#xff1a; 1. 什么是XTTS 2. 适用场景 3. XTTS的基本操作步骤 4. XTTS案例分享 今天主要跟大家分享一下XTTS,在网上曾看过相关讨论,但发现按网上讲的那些去实际操作的话,还是会遇到一些坑,并不能实际落下来,所以今天想跟大家分享一些实战干货. 一、什么是XTTS …

Redis偶发Cannot determine a partition for slot报错问题

Redis偶发Cannot determine a partition for slot报错问题 一、背景二、问题定位1、报错位置2、lettuce定时刷新任务3、本地缓存masterCache先清理后写入的问题 三、解决方案&#xff1a;版本升级 一、背景 线上系统&#xff08;springboot&#xff09;经常报错Cannot determi…

Linux内存管理:(六)页交换算法

文章说明&#xff1a; Linux内核版本&#xff1a;5.0 架构&#xff1a;ARM64 参考资料及图片来源&#xff1a;《奔跑吧Linux内核》 Linux 5.0内核源码注释仓库地址&#xff1a; zhangzihengya/LinuxSourceCode_v5.0_study (github.com) 1. 引言 在Linux操作系统中&#x…