.NET抽象类。
我正在设计一个网站导航层次结构。这是一棵节点树。
大多数节点是页面。某些节点是链接(在Windows中请考虑快捷方式)。
大多数页面包含HTML内容。一些执行代码。
我想以这些类和抽象(MustInherit)类的集合表示这些
类图http://img396.imageshack.us/img396/1711/nodeclassinheritanceej0.gif
这是我要存储所有这些的数据库表
数据库表http://img178.imageshack.us/img178/8573/nodetablefm8.gif
这就是我感到难过的地方。 PageNodes可以是根,也可以不是根。
我应该如何处理根类?
类图http://img396.imageshack.us/img396/5758/rootclasshf9.gif
我不想拥有全部四个
- HtmlPageNode
- CodePageNode
- HtmlRootPageNode
- CodeRootPageNode
我希望HtmlPageNode和CodePageNode类继承自PageNode或者RootPageNode。那可能吗?
说明:有多个根节点,并且根可能有父节点。每个仅是具有不同样式的子树的根。想想不同的,用颜色编码的部门。 (也许root是一个较差的名字选择。建议吗?)
更新:关于"根"名称...
我问过:是否有对应于子树的节点的特定名称?
解决方案
回答
实际上,由于"根"节点是节点的一种特例,因此我们可能需要RootHtmlPageNode:HtmlPageNode。
另一个想法:由于我们没有指定"根"节点和普通节点之间的区别,因此,也许只需在节点中指定一个标志(指定它是否为根节点)也是一个不错的设计。
编辑:根据说明,普通节点与根节点之间没有功能上的区别,因此,一个简单的标志就足够了(或者属性IsRootNode)。如果"根"节点仅提供样式数据(或者其本身及其子级的任何其他数据),则可以将该样式数据放在单独的结构/类中并递归获取(基于IsRootNode):
class Node { private bool isRootNode; public bool IsRootNode; private StylingData stylingData; public StylingData StylingData { set { if (this.IsRootNode) this.stylingData = value; else throw new ApplicationException("The node is not root."); } get { if (this.IsRootNode) return this.stylingData; else return this.parent.StylingData; } } }
假设每个节点都有对其父节点的引用。
由于我不知道确切的设计,它已成为无法解决的问题。
回答
使用复合图案。
关于根节点,功能上是否存在差异,还是外观完全不同?如果只是外观上的区别,我建议我们与PageNode中的单独的Style类有关联。
如果功能上存在差异,并且我们有许多类型的页面,请考虑使用装饰器模式。
回答
I want the HtmlPageNode and CodePageNode classes to inherit either from PageNode or else from RootPageNode. Is that possible?
是的,有可能。我们需要使HtmlPageNode和codePageNode具有一个对象,该对象将是PageNode将继承的Abstract类,也是RootPageNode。在HtmlPageNode和codePageNode的构造函数中,我们将接受新的Abstract类,在情况下将是PageNode或者RootPageNode。这样,我们就可以使用相同的方法创建2个不同的类,但使用两个不同的对象。希望对我们有所帮助!
回答
PageNode类是否应该仅具有Root类型的属性?
替代文字http://img206.imageshack.us/img206/2968/rootpropertygg0.gif
这与PageNode是-Root的想法背道而驰。或者,它们不是"仅是根",因为其中只有一部分是根吗?
这是否意味着该属性可能会遍历树以寻找根祖先?还是那只是我?
回答
如上所述,复合图案可能是一个很好的解决方案。
如果这对我们不起作用,则将"根"定义为接口并根据需要应用它可能会更简单。
当然,这不能让我们提供任何针对Root的实现...
如果根必须具有实现,则可以使用装饰器模式。
回答
Clarification: There are multiple root nodes and roots may have parent nodes. Each is the root of only a sub-tree that has distinct styling. Think of different, color-coded departments. (Perhaps root is a poor name choice. Suggestions?)
根是一个较差的名称选择,因为(有点讽刺意味地)将根明确地接受为树结构的顶层,因为树从根伸出地面的地方开始。除此之外的任何节点都是分支或者叶,并且不直接连接到根。
更好的名称应该是IsAuthoritativeStyleNode,IsCascadingStyleNode,IsStyleParentNode之类的名称,或者改为限定名称:例如IsDepartmentRootNode。给事物明确的明确名称是极大提高可读性/易于理解的事情之一。
仅通过抽象基类/继承就不能真正实现所需的功能。根据其他建议,请考虑使用接口。
我还要考虑是否让数据库架构过多地驱动客户端类设计。在这种情况下,不必说需要更改,但至少应该考虑一下。考虑一下如何将属性分解到引用公共"节点"表的单独表中,并对它们进行规范化以最小化空值和/或者重复的相同数据。