导航

Design Patterns: Abstract Factory

Posted on 2007-11-16 16:41  康康  阅读(139)  评论(0编辑  收藏  举报

    最近在啃英文版 设计模式 圣经《Design Patterns     Elements of Reusable Object-Oriented Software》一书,还没看完,但已有不少收获。下面记录一下学习笔记。
    以前也看过不少关于设计模式的书,看得似懂非懂,看上去都用过,但在使用的时候几乎没感觉自己在使用设计模式方法。看了这本书,对于部分模式的理解加深不少。

    用个例子来说明一下抽象工厂模式的使用:

    设计一软件,要求可以在多平台上运行(如:windows,linux等),如果我们需要使用 OS 的 控件 (如:产生一个 button,一个text框等等)时,必须对不同 OS 不同对待,这是显而易见的。因此可能我们要在多个地方使用不同的OS的相关对象的创建,这样一来我们在实现多平台特性的时候就受到了巨大的限制,但我们在设计此类软件时不希望受到 OS 的限制或者少受限制,并能在以后扩展功能时提供方便(如日后再实现一个Unix版本之类的)。

    怎么办呢?我们可以将需要 OS 特性的地方包装一下,并设计一套接口(如:IButton,ITextBox等),再针对不同 OS 设计一套对象(如WinButton,LnxButton等),以Button为例,使我们的Button实现上述接口(IButton),而在软件本身功能的实现中一律使用接口编程,这样我们就可以成功摆脱 OS 的限制了。然而我们最终必定要在某一处实例化这些对象,到时候扩展性又如何保证呢?我们可以用工厂类来提供实例化方法,该方法对不同OS创建不同的Button实例,并返回实例,这样创建的过程集中在工厂类中,扩展时可以修改工厂类,并设计实现一套新的类即可(如UxButton)。
    
    好了,我们已经简单的解决了对多平台特性的封装,但其中有个问题,那就是在日后我们需要扩展功能时,必须对已成功运行的那些代码进行修改并重新编译,而那些代码可能因为之前一直运行稳定,或者有部分机密而不希望被修改,更极端的是可能之前的代码就已经找不到了,没有了,怎么办?难道反编译?可能不太现实。那我们问什么不从第一次设计该软件的时候就考虑并解决这个问题呢?解决方法就是,设计一工厂接口(IFactory),该接口定义了各个对象的实例化方法,并对不同 OS 设计一具体工厂类( ConcreteFactory ),并用与本 OS 相关类来实现接口定义的方法。这样作可以为我们带来很大的灵活性,设想如果有一天我们的这个软件必须提供 Unix 版本,那我们只需要再另新写一个工厂类,并继承 IFactory接口,用Unix的相关方法来实现各个类(Button之类)的接口,在其具体工厂类中创建各个类(Button之类)的实例。并用反射的方法将此工厂类挂到我们的软件上就可以了,而且这样做可以最大可能性的减小耦合性,增强其扩展能力.