可扩展体系结构的研究(五)--对codon的概述
每一个codon需要一个ID来作为在树上的一个标示;codon则被插入树上,扩展路径上加+‘/’+id。因此id是所有codons的一个required common(必须的通用的)属性。菜单项的label属性对于菜单项codon来说是个必要属性。Class属性也许对于菜单项codon被考虑成一个可选的属性,但是一个codon制定一个类的情况非常普遍,它就是个通用属性。
菜单项codon是很多一般概念的codon中的特别的一个。让我们来考虑一个拥有超过一个实例的对象的情况,我们可以把他们放进一个集合,从而被其他人扩展。如果这样的对象是codon形式的将会非常有价值,因此我们可以这样做,使得这个扩展这个对象,而不用深入挖掘它的xml定义。
注:我们几乎可以将任何事物定义成codon。我们可以不仅仅定义GUI元素和他的动作,我们甚至可以扩展算法或复杂子系统的行为。
排列codon
我们会有这样的需求,菜单项必须以某种顺序被排列。这就意味着我们会有一个菜单项的codon要被插在菜单项x和y中间。当我们仅仅用单一的xml定义文件时,这没有问题(因为xml可以定义出顺序和层次)。但当我们将定义写到不同的文件中时问题就产生了(事实上在实际情况不同codon的xml定义文件都是分开部署的)。
因此所有codon有通用的属性insertafter 和 insertbefore,如: <MenuItem id = "MyMenu" insertafter = "File" label = "MyMenu">
这就确保了我们的菜单项可以被插到了file菜单的后面。
Insertbefore属性的工作方式跟insertafter属性一样。如果指定超过一个的codon,那么使用逗号作为名字分隔符。你必须给你想插入的codon指定一个ID。ID是一个节点的区分属性。我们要确保不能再一棵树的同一层有两个相同的节点有相同的ID,因为这样会使应用程序抛出异常。尽管codon将会是拓扑分类的,但要记住,会有超过一个的合法的拓扑分类。有时候当你插入一个codon时,会碰到不可预知的结果,因为可能会插到离它本应该被插到的地方有一定距离的地方。“after”并没有暗示一个正确的插入点是在指定点后的直接的第一个可能的位置(这同样适用于before)。
多层次的codon
在菜单项的情况下,我们可能会有主菜单包含多层子树的菜单定义。在下面的例子中,我们使用了一种更简明的方法来描述这种情况:
<Extension path = "/NCvs/Workspace/MainMenu">
<MenuItem id = "File" label = "&File"/>
</Extension>
<Extension path = "/NCvs/Workspace/MainMenu/File">
<MenuItem id = "Separator1" label = "-"/>
<MenuItem id = "Exit"
label = "E&xit"
class = "NCvs.Gui.Commands.ExitCommand"/>
</MenuItem>
</Extension>
using instead:
<Extension path = "/NCvs/Workspace/MainMenu">
<MenuItem id = "File" label = "&File">
<MenuItem id = "Separator1" label = "-"/>
<MenuItem id = "Exit"
label = "E&xit"
class = "NCvs.Gui.Commands.ExitCommand"/>
</MenuItem>
</Extension>
我们看到file菜单的codon没有包含子菜单项,取而代之的是在树结构中作为file codon的后代。使用这种简略的方式并不是强制的,但我们可以使得定义更加可读。