- 1、本文档共20页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第二章
2.3 格式化
我们已经解决了文档物理结构的表示问题。接着,我们需要解决的问题是怎样构造一个特殊物理结构,该结构对应于一个恰当地格式化了的文档。表示和格式化是不同的,记录文档物理结构的能力并没有告诉我们怎样得到一个特殊格式化结构。
2.3 格式化
封装格式化算法
用户可能会指定边界宽度、缩进大小和表格形式、是否隔行显示以及其他可能的许多格式限制条件。 Lexi的格式化算法必须考虑所有这些因素。因而格式化过程不容易被自动化。实际上人们已经有很多不同能力和缺陷的格式化算法。
因为Lexi是一个所见即所得编辑器,所以一个必须考虑的重要权衡之处在于格式化的质量和格式化的速度之间的取舍。我们通常希望在不牺牲文档美观外表的前提下,能得到良好的反映速度。这种权衡受许多因素影响,而并不是所有因素在编译时刻都能确定的。
例如,用户也许能忍受稍慢一点的响应速度,以换取较好的格式。这种选择也许导致了比当前算法更适用的彻底不同的格式化算法。又或者很有可能为了缓存更多的信息而降低格式化速度。
因为格式化算法趋于复杂化,因而可以考虑将它们包含于文档结构之中,但最好是将它们彻底独立于文档结构之外。理想情况下,我们能够自由地增加一个Glyph子类而不用考虑格式算法。反过来,增加一个格式算法不应要求修改已有的图元类。
因而,我们可以定义一个封装格式化算法的对象的类层次结构,它支持许多格式化算法的接口。没个子类实现这个接口以执行特定的算法。
Compositor和Composition
我们为能封装格式化算法的对象定义一个Compositor类。它的接口(见下表)可让Compositor获知何时去格式化哪些图元。它所格式化的图元是一个被称为Composition的特定图元的各个子图元。一个Composition在创建时得到一个Compositor子类实例,并在必要的时候(如用户改变文档的时候)让Compositor对它的图元作Compose操作。
Compositor和Composition
我们为能封装格式化算法的对象定义一Compositor类。它的接口可让Compositor获知何时去格式化哪些图元。它所格式化的图元是一个被称为Composition的特定图元的各个子图元。一个Composition在创建时得到一个Compositor子类实例,并在必要的时候(如用户改变文档的时候)让Compositor对它的图元作Compose操作。
Compositor接口
Composition和Compositor类之间的关系
一个未格式化的Composition对象只包含组成文档基本内容的可见图元。它并不包含像行和列这样的决定文档物理结构的图元。 Composition对象只在刚被创建并以待格式化的图元进行初始化后,才处于这种状态。当Composition需要格式化时,调用它的Compositor的Compose操作。 Compositor依次遍历Composition的各个子图元,根据分行算法插入新的行和列图元。
上图显示了得到的对象结构。图中由Compositor创建和插入到对象结构中的图元以灰色背景显示。
Compositor-Composition类的分离确保了支持文档物理结构的代码和支持不同格式化算法的代码之间的分离。我们能增加新的Compositor子类而不触及Glyph类,反之亦然。事实上,我们通过给Composition的基本图元接口增加一个SetCompositor操作,即可在运行时刻改变分行算法。
策略模式
定义一系列算法,将每一个算法封装起来,并让他们可以相互替换。策略模式让算法独立于使用它的客户而变化。
2.4修饰用户界面
我们针对Lexi用户界面考虑两种修饰,第一种是在文本编辑区域周围加边界以界定文本页;第二种是加滚动条让用户能看到同一页的不同部分。
为了便于增加和去除这些修饰(特别是在运行时刻),我们不应该通过继承方式将它们加到用户界面。如果其他用户界面对象不知道存在这些修饰,那么我们就获得了最大的灵活性。这使我们无需改变其他的类就能增加和移去这些修饰。
透明围栏
从程序设计角度出发,修饰用户界面涉及到扩充已存在的代码。我们可以用继承的方式完成这种扩充,但如此运行时刻对这些修饰作重新安排则十分困难。并且同样严重的问题是,基于类继承方法通常会引起类爆炸现象。
对象组合提供了一种潜在的更有效和更灵活的扩展机制,但是我们组合一些什么对象呢?既然我们知道要修饰的是已有的图元,我们就可以把修饰本身看作对象(如,类Border的实例)。这样我们有了两个组合候选对象:图元(Glyph)和边界(Border)。
两种组合方法
在边界中包含图元
这给人以边界在屏幕上包围了图元的感觉。
可以将
文档评论(0)