1) Adapter
Indent: Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
转换一个类的接口. 我们最容易想到的方法就是把现有类包装一下, 对外提供兼容接口. Adapter模式就是这么干的, 这是一个object adapter. 而另一个被称为class adapter的东西用的则是类的继承.
代码看这里: http://en.wikipedia.org/wiki/Adapter_pattern. 注意其中什么时候用extends, 什么时候用implements.
2) Bridge
Indent: Decouple an abstraction from its implementation so that the two can vary independently.
把抽象和实现相分离, 这是什么东西, 好像很废话啊. 所谓的bridge, 实际上是在抽象类和具体类中间再加一层关系.
书上的说法很有朦胧美的感觉, 反正我没完全看懂. 不过这里有两个图很直观: http://sourcemaking.com/design_patterns/bridge. 还附带了代码: http://sourcemaking.com/design_patterns/bridge/c%2523
也就是说Implementor接口仅提供基本操作(比如操作系统相关), 而Abstraction则定义了基于这些基本操作的较高层次的操作.
3) Composite
Indent: Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
这个应该好理解的, 我就不多说了. 想象一下写java的时候, JPanel是一个JComponent, 可以装到一个JContainer(一个composite)里, 而它本身也可以装其它的JComponent.
代码可以参考: http://en.wikipedia.org/wiki/Composite_pattern
4) Decorator
Indent: Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
如果你用Java, 那么一定写过这样的代码, 事实上用的就是Decorator模式:
BufferedInputStream bis = new BufferedInputStream(new DataInputStream(new FileInputStream("foo.txt")));Decorator模式的好处是, 它给某个对象, 而不是类添加功能, 即时使用, 避免在层次结构高层的类有太多的特征. 这些都是相对于使用继承的好处.
还记得Strategy模式么? 我又觉得这个东西跟Decorator模式很像了. 书上说, 前者用来控制对象的guts, 而后者控制对象的skin. Strategy从内部改变对象, 不需要继承之类的东西, 需要的只是对象的对外接口. Decorator从外部改变对象, 因此对象对于这些decorator无需任何了解.
代码: http://sourcemaking.com/design_patterns/decorator/c++/2
5) Facade
Indent: Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
没什么好说的, 就是一个复杂系统对外提供一个简单接口. 比如一个http server, 只要提供start(), stop()以及一些配置相关的操作就可以了, 用户并不需要知道具体一个http request是怎么被处理的.
代码: http://en.wikipedia.org/wiki/Design_Pattern_-_Facade
6) Flyweight
Indent: Use sharing to support large numbers of fine-grained objects efficiently.
关键字: 共享. 我觉得这个模式有点诡异的. 每个flyweight对象被要求分为extrinsic和intrinsic两部分. 而intrinsic即内部的数据便是我们要共享的数据. 无论是书上还是wikipedia上的代码, 事实上都实现了一个类似object pool的factory类用来做cache和share. 这些东西又很自然的让我想到了http server中thread pool的概念. 那些thread可以重用, thread具体要做的工作实际上是用外部数据的方式传递给它的.
书上的代码和图例我一点也没看懂, 还是看wikipedia的: http://en.wikipedia.org/wiki/Flyweight_pattern
7) Proxy
Indent: Provide a surrogate or placeholder for another object to control access to it.
额..控制对象访问, 也就是在一个类外面在套一层. 为什么那么麻烦呢? 为了控制对象访问..囧... 有4种类型的proxy分别是: remote proxy, virtual proxy, protection proxy, smart reference. 不过, 有的时候不用proxy也能解决问题. 比如一个protection proxy, 我为什么一定要再加一个proxy类判断而不自己判断呢? 的确, 不过我觉得这就是一种功能和逻辑相分离的做法.
难道所有的类, 我们都要再加一个proxy类? 累死人的. 可以看一下4中分类需要实现的附加功能是否有必要先. 另外, 我觉得可以和Facade模式之间取舍. 一个针对一个class, 另一个针对一个subsystem.
代码: http://en.wikipedia.org/wiki/Proxy_pattern
8) 总结:
以上7种都是结构型模式, 描述的是对象的组件. 其实不外乎是两种方法, 一种是继承(inheritance), 一种是组合(composite). 对于继承来说, 一直觉得有很多弊端, 用用多态就可以了, 用来扩展或是其它功能, 要做好真的是有很大难度的, 且还不一定能做好. 又或者就直接定接口(interface), 尽量不要用实现了的类. bridge, composite, decorator模式利用了interface的特点. 而组合则能很好的控制对外接口, adaptor, facade, proxy模式实际上都用到了这一点.
书后有各个模式的一些比较, 可以参考. 其实, 只要弄明白每个模式要解决的问题是什么就容易区分了, 这也是为什么我要用粗体字表明的原因.



