YYW'S BLOG

知识的分享就是知识的获得
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

探讨抽象工厂与建造模式

Posted on 2006-11-23 22:45  阿武  阅读(2482)  评论(11编辑  收藏  举报


      在 GoF(Gang of Four) 的23种设计模式中,单件模式(Singleton)、简单工厂模式(Simple Factory)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、建造模式(Builder)、原型模式(Prototype)都归属于创建型模式。但其中最让容易让初学者混淆的就是抽象工厂模式和生成器模式。本文将通过一个实例来说明抽象工厂模式与建造都模式之间的区别及它们各自使用的场景。

      假设我们想要创建一个窗体 Form,而且这个 Form 应该是支持多种主题的,Form 的基本组成部分是一个 Panel、三个按钮(最大化、最小化和关闭按钮),还有一个状态栏,
为了设计的简单和易于理解我们暂且将标题栏、标题栏图标、菜单栏和工具栏忽略,因为即使没有它们我们照样可以把这东西叫做窗体。我们现在要做的就是如何去创建两种不同主题的窗体,就把它定为蓝色 Xp 和新鲜出炉令人赏心悦目的 Vista 为例。当然它还必须支持“开-闭”原则(OCP),它样我们可以很容易的扩展更多主题。

      第一步: 创建接口

      创建出三个接口 IPanel,IButton(IButton再派生出三个子接口 IMaximizeBox、IMinimizeBox、ICloseBox 分别对应最大化、最小化、关闭按钮),IStatusBar,或许它们还应该同归属于 Controls ,但本文不考虑这些额外的东西。接着创建我们最终想要的产品接口 IForm 。

      类图如下(点击可查看大图,下同):



      接口仅仅是抽象的,为了得到产品的实例我们必须为它创建具体类型。




      第二步:抽象工厂模式  (窗体零件制造厂)

      下面将是抽象工厂登场亮相的时候了,抽象工厂的用意是向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,创建多个产品族中的产品对象。

      在这里我们的抽象工厂类 FormFactory 将创建出一个个 XP 风格或 Vista 风格的窗体零部件,当然窗体除外,因为在这里窗体不属于零部分,它是最终的成品,它的创建工作是留给建造模式的。

      下面是抽象工厂创建窗体零件的类图:



      第三步:建造模式  (窗体组装厂)

      在这里我们的客户 Client 已经可以通过工厂来创建出一个或者多个零件并添加到我们的窗体上了,事实上大多数的窗体都是由这些零部件组成,在这里我们仅利用建造模式搭建出一个最基本的窗体,它由一个 Panel、三个按钮(最大化、最小化和关闭按钮)和状态栏组成。

      下面是通过建造模式组装一个窗体的类图:



      这里的 FormBuilder 充当了上一图中的 Client 角色。现在我们就可以通过 FormBuilder 创建出一个 Xp 风格或者 Vista 风格的窗体了,由于设计模式都支持软件设计的第一原则 OCP ,所以我们也可以很方便地扩展出其它第三方主题出来,这时就可以让我们的用户尽情地发挥想象力了。

      这里还想说明的是 FormDirector 类的 Construct 方法并非简单地去把 FormBuilder 中的 BuildX 方法顺序地执行一遍,我们可以只 BuildClosseBox 而不 BuildMaximizeBox 和 BuildMinimizeBox,这样我们就建造出了一个不能最大化和最小化的模式窗体的窗体,或者执行多次 BuildPanel 创建出一个多面板组成的窗体。

      建造模式将产品的结构和产品的零件建造过程对客户端隐藏起来,把对建造过程进行指挥的责任和具体建造者零件的责任分割开来,达到责任划分和封装的目的。


      写到这里我们已经可以创建出一个想要的窗体了,主要是想通过这个例子说明抽象工厂模式和建造模式其实是责职和用意都相差得比较远的模式,而且它们也经常可以通过这种方式组合使用,达到互补。

      下面简单概括一下这两种模式之间的相同和不同点。

      相同点:
      1、同属于创建型模式;
      2、创建同属于几个产品族的对象的模式;


      不同点:
      1、抽象工厂模式注重的是对象的创建过程,这里的对象指的是零部件或者最终成品,毕竟有些对象自身就组成了我们想要的一个成型的产品; 
      2、建造模式注重的是产品建造最终的结果,这里的产品指的是成品,即用户最终希望得到的;

      最后上一张完整图。于对模式的理解和善处于学习阶段,文中不免有不合理或错误的地方,欢迎批评指出。




参考资料:
Java与模式》
《设计模式(中文版)》
 C#面向对象设计模式纵横谈