上一篇的工厂方法模式引入了工厂等级结构,解决了在原来简单工厂模式中工厂类职责太重的原则,但是由于工厂方法模式的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,从而增加系统开销。那么,我们应该怎么来重构?似乎,我们可以考虑将一些相关的产品组成一个“产品族”,由同一个工厂来统一生产,这就是本次将要学习的抽象工厂模式的基本思想。
抽象工厂模式(Abstract Factory) | 学习难度:★★★★☆ | 使用频率:★★★★★ |
一、界面皮肤库的初始设计
M公司IT开发部接到一个开发任务,想要对以前的一个系统开发一套界面皮肤库,可以对该桌面系统软件进行界面美化。这样,用户就可以在使用时通过菜单来选择皮肤,不同的皮肤将提供视觉效果不同的按钮、文本框以及组合框等界面元素,其结构示意图如下所示:
该皮肤库需要具备良好的灵活性和可扩展性,用户可以自由选择不同的皮肤,开发人员也可以在不修改既有代码的基础上增加新的皮肤。
M公司的开发人员针对上述需求,决定现学现卖,在上次使用了工厂方法模式之后对工厂方法模式大为赞赏,决定使用工厂方法模式来进行系统的设计,为了保证系统的灵活性和可扩展性,提供一系列具体工厂来创建按钮、文本框以及组合框等界面元素,客户端针对抽象工厂来编程,初始结构如下图所示:
从上图可以看出,此方案提供了大量的工厂来创建具体的界面组件,可以通过配置文件来更换具体界面组件从而改变界面的风格,但是,此方案存在以下问题:
(1)需要增加新的皮肤时,虽然不需要更改现有代码,但是需要增加大量的类,针对每一个新增具体组件都要增加一个具体工厂,类的个数会成对增加。这无疑会导致系统越来越庞大,从而增加了系统的维护成本和运行开销。
(2)由于同一种风格的不同界面组件通常需要一起显示,因此需要为每个组件都选择一个具体工厂,用户在使用时必须逐个进行设置,如果某个具体工厂选择失误将会导致界面显示混乱,虽然可以适当增加一些约束语句,但是客户端代码和配置文件都较为复杂。
综上所述,如何减少系统中类的个数并保证客户端每次始终就只使用一种风格的具体界面组件?这是萦绕在M公司开发人员心头的两个问题。