Design Pattern – Composite Pattern
Composite Pattern (合成模式) 主要用来描述部分与整体之间的关系, 可以用树形图来进行描述,以abstract class或者interface为根节点,形成树节点和叶节点, 通过根节点的abstract class或者interface对该结构的抽象,使客户端可以将单个节点与复合元素节点(即枝节点,因每个枝节点都包含若干个枝节点或者叶节点,故称作复合元素节点)当做相同的对象来对待处理。
Composite Pattern有两种实现方式:
透明方式:在根节点中声明所有管理子节点的方法,这样的好处在于所有的构建类(包括叶节点,或者枝节点)都具有相同的接口,这样客户端可以等同的对待所有对象。缺点在于安全性不高,因为枝节点可以包含操作叶节点的方法,如果根节点接口中声明了这样的方法,这些方法在叶节点中是无效的,而且只会在运行时出错,编译时不会出错。
安全方式:所有操作子类的方法放在枝节点中定义,这样的好处在于安全性高,缺点在于叶节点和合成类具有不同的接口。
举一个不算特别恰当的例子,一篇文章,以word为最小单位的话,word即为叶节点,每个段落paragraph可以包含多个paragraph或者word(虽然不太恰当,暂时这样理解好了),则安全方式的定义如下:
其中paragraph的构造函数,属性以及方法内部逻辑均省略。 具体实现时Paragraph类中应该有一个IElement的集合类型的属性,此处省略掉了。
若用透明方式实现,即将下例的两个接口合并即可,但是需要注意Word中的Add()方法是无意义的 -- 非安全的地方。
Code Snippers
- public interface IElement
- {
- void Display(int depth);
- }
- public interface IElementContainer
- {
- void Add(IElement element);
- }
- public class Word : IElement
- {
- #region IElement Members
- public void Display(int depth)
- {
- // Word display logic implementation.
- }
- #endregion
- }
- public class Paragraph : IElement, IElementContainer
- {
- #region IElement Members
- public void Display(int depth)
- {
- // Paragraph display logic implementation.
- }
- #endregion
- #region IElementContainer Members
- public void Add(IElement element)
- {
- // Paragraph add new element logic implementation.
- }
- #endregion
- }
此设计模式较为简单,类图就不画了。