Eclipse官方FAQ翻译系列
FAQ How do I use a model reconciler?
original link :http://wiki.eclipse.org/FAQ_How_do_I_use_a_model_reconciler% 3F
功能强大的文本编辑器,比如那些程序语言或WEB开发的编辑器,通常在底层都有一个对应于编辑器显示的元素的模型(model)对象。这些模型对于语义操作通常是很有用的,比如重构、查询。作为一个编辑器的用户类型对象,编辑器的文本可能不能很好的与底层模型同步。比如,一个HTML编辑器可能拥有一个包含链入和链出文档的超链接的信息的模型。当用户编辑文档,添加或删除链接或锚记,底层的模型肯定会变得过期。如果其他工具此时查询过时的模型,错误的结果就会返回。
当一个编辑器正在操作workspace中的一个文件,解决这个问题的一个方法就是使用增量的项目构建器(incremental project builder)来更新底层模型。当自动构建是可用状态,则模型将在用户每次保存文档时被更新。然而,如果自动构建被关闭,则会导致底层模型在很长的一段时间是过期的。关掉自动构建的唯一原因可能是更新模型是一个开销很大的计算过程,通过关闭自动构建,用户可以控制构建的频率。
对于可以花很小开销就更新的轻量级模型,经常性的更新模型则更好。这就是文本编辑器的调解器(reconciler)出现的原因。当编辑器安装了一个调解器,一个队列就被用于记录编辑器发生的所有改变。每个改变(change)由一个DitryRegion(脏区域)对象表示,而这些区域被添加到一个脏区域队列中(DirtyRegionQueue)。调解器从队列中移除元素并以此更新模型。如果在调解器更新模型前发生了多次编辑事件,队列中的DirtyRegion对象会被恰当的合并。例如,连续的在编辑器中输入将创建一个大的脏区域,而不是为每个输入的字符创建一个独立的脏区域。调解器可以分析DirtyRegion对象来了解文本的哪些部分已经无效,并以此来更好的优化它的更新。
在SourceViewerConfiguration类中定义了getReconciler方法,你的子类可以通过重载这个方法来安装一个调解器。你可以从一组内建的调解器实现中选择,也可以直接实现IReconciler接口来提供你自己的调解器。多数情况下,你可以使用MonoReconciler,这个调解器对于文档的不同分区同一而视。MonoReconciler运行在一个低优先级的后台线程中,允许在处理前,把文档的多个改变添加到队列中。它异步的对文本和模型进行调解,以允许用户在调解的过程中继续编辑文档,尽管这仍然会导致文档在很短的时期内是过期的。
注意,调解器通常无法替换构建器(builder),但作为补充角色,它是够用的。比如,在JDT插件中,当用户改写了某个class,调解器就对class进行分析。而分析器则搜集足够的信息来更新Java模型,以此设置正确的内容辅助,支持重构和其他的一些操作。当用户保存并构建这些文件,一个增量构建器对这些改变的文件执行一次完整的编译,生成class文件,并重新编译其他受本次改变影响的文件。通过这个方式,代价昂贵的处理被推迟了,而域模型(domain model)则总是保持最新。