设计模式第二章第八节分析.ppt

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
既然CheckMe对于访问者并不合适,因为访问者不检查任何东西。故我们要使用一个更加通用的名字:Accept,其参数也应该改成Visitor,以反映它能接受任何一个访问者这一事实。现在定义一个新的分析只需要定义一个新的Visitor子类——我们无需触及任何图元类。通过在Glyph及其子类中增加这一操作,我们就可以支持以后的所有分析方法。 我们已经看到怎样做拼写检查了。我们可以在 HyphenationVisitor中使用类似的方法来累积文本,但一旦HyphenationVisitor的VisitCharacter操作用于处理整个单词,它的工作方式将略有不同。它并不是检查单词的拼写错误,而是使用一个连字符算法决定单词可能的连字符点的位置( 如果有的话)。然后在每一个连字符点,插入一个Discretionary 图元。 Discretionary图元是Glyph子类Discretionary的实例。 一个Discretionary图元有两种可能的外观,这决定于它是否是一行的最后一个字符。如果它是最后一个字符,那么Discretionary看起来像一个连字符;如果不是,那么Discretionary不显示任何东西。 Discretionary检查它的父对象(一个行对象)来判断它是否是最后的子女。 Discretionary在每次被激活画自己或计算它的边界时,都要作这个检查。格式化策略将Discretionary看成空格,将它们都作为行结束的标志。下图说明了一个嵌入的Discretionary是怎样显示的。 2.8.8 Visitor模式 我们这里所描述的是Visitor模式的一个应用。前面的Visitor类及其子类是该模式的主要参与者。Visitor模式记述了这样一种我们前面已使用过的技术,它允许对图元结构所作分析的数目不受限制地增加而不必改变图元类本身。访问者类的另一个优点是它不局限使用于像图元结构这样的组合者,也适用于其他任何对象结构。包括集合、列表,甚至无环有向图。再者,访问者所能访问的类之间无需通过一个公共父类关联起来。也就是说,访问者能跨越类层次结构。 2.8、拼写检查和断字处理 拼写检查和连字符点的计算也存在多种方法。因此,我们能同时希望支持多个算法。一组不同算法的集合能够提供时间/空间/质量选择时的权衡,我们也希望应该能很容易加进新的算法。因为拼写检查和连字符只是我们希望Lexi支持的许多潜在的文本分析中的两种。所以,我们要尽量避免将功能与文档结构紧密耦合,此时这个目标甚至比格式化设计更重要。 事实上这个难题可以分成两部分: 1)访问需要分析的信息,而它们是被分散在文档结构的图元中的;2)分析这些信息。我们将这两部分分开对待。 2.8.1、访问分散的信息 许多分析要求逐字检查文本,而我们需要分析的文本是分散在图元对象的层次结构中的。为了检查在这种结构中的文本,我们需要一个知道数据结构中所包含图元对象的访问机制。一些图元可能以连接表保存它们的子图元,另一些可能用数组保存,还有一些可能使用更复杂的数据结构。我们的访问机制应该能处理所有这些可能性。 更为复杂的情况是,不同分析算法将会以不同方式访问信息。大多数分析算法总是从头到尾遍历文本,但也有一些恰恰相反所以我们的访问机制必须能容纳不同的数据结构,并且我们还必须支持不同的遍历方法。 2.8.2 封装访问和遍历 假如我们的图元的接口使用一个整型数字索引,让客户引用子图元。尽管这对以数组储存子图元的图元类来说是合理的,但对使用连接表的图元类却是低效的。图元抽象的一个重要作用就是隐藏了存储其子图元的数据结构,我们可以在不影响其他类的情况下改变图元类的数据结构。 因而,只有图元自己知道它所使用的数据结构。可以有这样的推论:图元接口不应该偏重于某个数据结构。不应该像上面这样,即数组比使用连接表更好 我们有可能解决这个问题,并且同时支持多种遍历方式。我们可以将多个访问和遍历功能直接放到图元类中,并提供一种选择方式,这可能是通过增加一个枚举常量作为参数。类在遍历过程中传递该参数以确保所用的是同一种遍历方式,它们必须传递遍历过程中积累的任何信息。 我们可以给Glyph的接口增加如下的抽象操作来支持这种方法: Void First Traversal kind Void Next Bool IsDone Glyph* GetCurrent Void Insert Glyph* First、Next和IsDone操作控制遍历。First初始化遍历过程,它根据枚举类型Traversal的参数值确定执行何种遍历,其值可以是CHILDREN(只遍历图元的直接子图元)、PREORDER、 POSTORDER和INORDER。Next在遍历时前进到下一

文档评论(0)

bbnm58850 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档