一个实例搞懂抽象工厂模式

简介: Sunny软件公司欲开发一套界面皮肤库,可以对Java桌面软件进行界面美化。为了保护版权,该皮肤库源代码不打算公开,而只向用户提供已打包为jar文件的class字节码文件。用户在使用时可以通过菜单来选择皮肤,不同的皮肤将提供视觉效果不同的按钮、文本框、组合框等界面元素。

关于工厂模式三兄弟(简单工厂、工厂方法、抽象工厂),前两个兄弟比较容易懂,基本一看就明白,第三位兄弟初看起来确实有些抽象,网上看到一个例子讲的很好,分享给大家,保证一看就明白。


文末给出系列文章出处。


Sunny软件公司欲开发一套界面皮肤库,可以对Java桌面软件进行界面美化。为了保护版权,该皮肤库源代码不打算公开,而只向用户提供已打包为jar文件的class字节码文件。用户在使用时可以通过菜单来选择皮肤,不同的皮肤将提供视觉效果不同的按钮、文本框、组合框等界面元素,其结构示意图如图所示:


1.jpg


图1 界面皮肤库结构示意图


该皮肤库需要具备良好的灵活性和可扩展性,用户可以自由选择不同的皮肤,开发人员可以在不修改既有代码的基础上增加新的皮肤。


Sunny软件公司的开发人员针对上述要求,决定使用工厂方法模式进行系统的设计,为了保证系统的灵活性和可扩展性,提供一系列具体工厂来创建按钮、文本框、组合框等界面元素,客户端针对抽象工厂编程,初始结构如图所示:


2.jpg


图2 基于工厂方法模式的界面皮肤库初始结构图


在图2中,提供了大量工厂来创建具体的界面组件,可以通过配置文件更换具体界面组件从而改变界面风格。但是,此设计方案存在如下问题:


(1) 当需要增加新的皮肤时,虽然不要修改现有代码,但是需要增加大量类,针对每一个新增具体组件都需要增加一个具体工厂,类的个数成对增加,这无疑会导致系统越来越庞大,增加系统的维护成本和运行开销;


(2) 由于同一种风格的具体界面组件通常要一起显示,因此需要为每个组件都选择一个具体工厂,用户在使用时必须逐个进行设置,如果某个具体工厂选择失误将会导致界面显示混乱,虽然我们可以适当增加一些约束语句,但客户端代码和配置文件都较为复杂。


如何减少系统中类的个数并保证客户端每次始终只使用某一种风格的具体界面组件?这是Sunny公司开发人员所面临的两个问题,显然,工厂方法模式无法解决这两个问题,别着急,本文所介绍的抽象工厂模式可以让这些问题迎刃而解。


Sunny公司开发人员使用抽象工厂模式来重构界面皮肤库的设计,其基本结构如图所示:


3.jpg


如果需要更换皮肤,只需修改配置文件即可,在实际环境中,我们可以提供可视化界面,例如菜单或者窗口来修改配置文件,用户无须直接修改配置文件。如果需要增加新的皮肤,只需增加一族新的具体组件并对应提供一个新的具体工厂,修改配置文件即可使用新的皮肤,原有代码无须修改,符合“开闭原则”。


扩展


在真实项目开发中,我们通常会为配置文件提供一个可视化的编辑界面,类似Struts框架中的struts.xml编辑器,大家可以自行开发一个简单的图形化工具来修改配置文件,实现真正的纯界面操作。


本文并没有展开讲抽象工厂模式的方方面面,只是用一个例子,让大家对这个设计模式有个直观的感受,让它“落地”到实例中,建议大家看看下面的系列文章(认真看用不了多久),我也是从这里摘取的例子。

相关文章
|
消息中间件 数据可视化 Java
自顶向下学习 RocketMQ(一): QuickStart
采用源码编译安装,注意请提前将 maven 安装调试好。 操作系统 macOS RocketMQ 版本:4.9.2 Maven 版本 3.3.9 JDK 版本 1.8.0_181
自顶向下学习 RocketMQ(一): QuickStart
|
算法 开发工具 git
时间紧任务急,如何在LeetCode刷题
很多公司都会面试算法题,然而很多小伙伴平时工作很忙,没有时间或没有养成刷题的习惯,面试准备周期时间也很紧张,没办法刷完LeetCode,往往慌慌张张刷了一些题,然而其实效果也不好。 当然这里还是建议大家平时多看看算法题,毕竟程序=数据结构+算法,对你以后的编程工作来说是大有好处的。
时间紧任务急,如何在LeetCode刷题
|
小程序
微信小程序:本地开发环境和线上环境配置
微信小程序:本地开发环境和线上环境配置
976 0
|
2月前
|
物联网 虚拟化 Windows
Windows 10 version 22H2 中文版、英文版下载 (2025 年 7 月更新)
Windows 10 version 22H2 中文版、英文版下载 (2025 年 7 月更新)
593 0
|
安全 关系型数据库 测试技术
基于SpringBoot+Vue的社团管理系统的设计与实现(源码+部署说明+演示视频+源码介绍)(2)
基于SpringBoot+Vue的社团管理系统的设计与实现(源码+部署说明+演示视频+源码介绍)
208 1
|
JavaScript Java 关系型数据库
基于SpringBoot+Vue的社团管理系统的设计与实现(源码+部署说明+演示视频+源码介绍)(1)
基于SpringBoot+Vue的社团管理系统的设计与实现(源码+部署说明+演示视频+源码介绍)
361 1
|
设计模式 前端开发 算法
Java编程技巧之样板代码
在日常编码的过程中,可以总结出很多“样板代码”,就像”活字印刷术中的“活字”一样。当我们编写新的代码时,需要用到这些“活字”,就把“样板代码”拷贝过来,修改替换一下就可以了,写起代码来“极为神速”。“样板代码”其实就是一种样例、一种模式、一种经验……总结的“样板代码”越多,编写代码的格式越规范、质量越高、速度越快。
Java编程技巧之样板代码
java使用FileChannel的transferTo方法拷贝大于2G文件
java使用FileChannel的transferTo方法拷贝大于2G文件
346 0
|
安全 Java 网络安全
HTTPS的TLS/SSL协议详解及Java代码示例
HTTPS的TLS/SSL协议详解及Java代码示例
925 0
|
Java 对象存储 Spring
Javaweb之SpringBootWeb案例之 @ConfigurationProperties的详细解析
Javaweb之SpringBootWeb案例之 @ConfigurationProperties的详细解析
282 0
Javaweb之SpringBootWeb案例之 @ConfigurationProperties的详细解析