内容学习范围:《设计模式:可复用面向对象软件的基础》
设计问题
1、文档表示结构:所有的编辑、格式安排、显示和文本分析等。
2、格式化:文本和图型怎么安排到行和列;哪些对象负责执行不同的策略;格式策略怎么在内部表述相互作用。
3、用户界面/以及其演化。
4、支持不同的look and feel标准。
5、支持多种窗口:以及多窗口下的不同视感。
6、用户的操作:如按钮或菜单。
7、拼写检查和连字符:分析操作/以及分析操作的增加。
一、文档表示结构
需要支持设计要点:
(1)保持文档的物理结构:文本、图形安排到行、列、表等。
(2)可视化生成和显示文档。
(3)根据显示位置来映射文档内部表示的元素。
(4)一致对待文本和图型。
(5)不该过分强调单个元素和元素组之间的差别;但是在检查拼写错误或连字符的同时,有需要对上下文本分析(存在矛盾)。
设计方案:
(1)递归结构
字符图片从左到右形成文档的一行,多行形成一列,多列形成一页。
每个节点对象,既可以作为基本元素,又可以作为结构化的元素。
对于这些每一个节点对象,都归为同一个抽象类图元(Glyph)。如图:
图元的三个基本责任:
1、怎么画出自己。
定义Rectangle子类重定义Draw。
void Rectangle::Draw(Window* w) {
w->DrawRect(_x0, _y0, _x1, _y1);
}
其中_x0,_x1,_y0,_y1是Rectangle的参数,DrawRect是显示操作
2、占用多大空间。
父图元需要知道子图元的空间信息,以便安排其跟其他子图元的安排位置,保证互相不会覆盖。
Bounds返回图元占用的矩形区域。
3、维护对应的父子图元。
对于子图元的Insert和Remove,
返回Child的链表对应index的子图元
返回Parent图元。
Composite模式描述了面向对象的递归组合的本质。
Composite模式:将对象组合树形结构以表示“部分-整体”的层次结构。使得客户对单个对象和符合对象的使用具有一致性。
二、格式化
将文本分列,分行,甚至一些用户指定边界的特殊功能。
这里讨论的“格式化”含义限制为将一个图元集合分解为若干行。对于分解成列与分解成页的技术同样适用。
需求:
格式化的算法日趋复杂化,我们期望其可以直接包含于文档结构中,最好是彻底独立于文档结构外。
理想情况下,能够自由地增加一个Glyph子类而不考虑算法。同时,增加算法也不需要特定化到图元类。
设计思路:
格式化的算法需要易于改变,可以在运行时刻改变这个算法,至少在编译时刻应该很方便地改变。
可以将算法独立出来,封装到对象中。甚至进一步的,定义该对象地类层次结构。其根节点将定义支持许多格式化算法地接口,每个子类实现这个接口以执行特定的算法。
让Glyph子类对象自动使用给定算法对象来排列其子图元。
Strategy模式:定义一系列的算法,把他们一个个封装起来,并且使得他们可相互替换。该模式使得算法的变化可以独立于使用它的客户。
设计方案:
为封装格式化算法的对象定义一个Compositor类。
假定其所格式化的图元是一个被称为Composition的特定图元的各个子图元。则Composition在被创建时,会得到一个Compositor子类实例。
其接口的工作为:获知何时格式化Compose、格式化的内容SetComposition。
在必要的时候,如用户改变文档的时候,让Compositor对其图元作Compose操作。
初始的时候,Composition对象只包含基本内容可见的图元。
当Composition需要格式化的时候,根据算法遍历Composition的每个子图元,根据分行算法插入新的行和列图元。
每一个Compositor子类都可以实现不同的分行算法。
Compositor-Composition类的分离,确保了物理结构的代码与支持不同格式化算法的代码的隔离。通过SetCompositor操作,可以运行时刻改变分行算法。
在对象中封装算法是Strategy模式的目的。模式的主要参与者是Strategy对象和其操作环境。Composition就是Compositor策略的环境。
Strategy模式应用的关键点在于为Strategy和它的环境设计足够通用的接口,来支持一系列的算法。