我正在设计一个网站导航层次结构。它是节点树。
大多数节点都是页面。有些节点是链接(想想Windows中的快捷方式)。
大多数网页都包含HTML内容。有些人执行代码。
我想把它们表示为类和抽象(MustInherit)类的集合......
这是我要存储所有这些的数据库表......
database table http://img178.imageshack.us/img178/8573/nodetablefm8.gif
这是我难倒的地方。 PageNodes可能是也可能不是root。
我应该如何处理根类?
我不想拥有所有四个......
我希望HtmlPageNode和CodePageNode类从PageNode继承 ,或者从RootPageNode继承。这可能吗?
澄清:有多个根节点,根可能有父节点。每个都只是具有不同样式的子树的根。想想不同的颜色编码部门。 (也许根是一个糟糕的名字选择。建议?)
更新:关于“Root”名称...
我问过:Is there a specific name for the node that coresponds to a subtree?
答案 0 :(得分:2)
关于根节点,功能上是否存在差异,或者它的外观是否完全不同?如果差异只是外观,我建议您与PageNode中的单独Style类关联。
如果功能存在差异并且您有很多类型的网页,请考虑使用Decorator Pattern。
答案 1 :(得分:2)
如上所述,复合模式可能是一个很好的解决方案。
如果这对您不起作用,则可能更简单 - 如果适用 - 将Root定义为接口,并根据需要应用它。
当然,这并不能让你为Root提供任何实现。
如果Root必须具有实现,则可以使用Decorator模式。
答案 2 :(得分:1)
实际上,由于“根”节点是节点的特例,可能需要RootHtmlPageNode:HtmlPageNode。
另一个想法:因为你没有指定“root”和普通节点之间的区别,可能只是节点中的一个标志,指明它是否为root也是一个很好的设计。
编辑:根据您的澄清,普通节点和根节点之间没有功能差异,因此一个简单的标志应该足够(或属性IsRootNode)。如果“root”节点仅提供样式数据(或其自身及其子项的任何其他数据),则可以将此样式数据放在单独的结构/类中并递归获取(基于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;
}
}
}
这假设每个节点都有一个对它的父节点的引用。
由于我不知道确切的设计,因此它已成为一个难以理解的问题。
答案 3 :(得分:1)
我希望HtmlPageNode和CodePageNode类继承自PageNode或RootPageNode。这可能吗?
是的,这是可能的。你需要让HtmlPageNode和codePageNode有一个对象,它将是PageNode将继承的Abstract类和RootPageNode。在HtmlPageNode和codePageNode的构造函数中,您接受将在您的案例中的PageNode或RootPageNode的新Abstract类。这样,您有2个具有相同方法的不同类,但有两个不同的对象。希望能帮到你!
答案 4 :(得分:1)
澄清:有多个根节点,根可能有父节点。每个都只是具有不同样式的子树的根。想想不同的颜色编码部门。 (也许根是一个糟糕的名字选择。建议?)
Root是一个糟糕的名字选择,因为它(有点讽刺地)被明确地接受为树结构的顶层,因为树从根出来的地方开始。除此之外的任何节点都是分支或叶子,而不是直接连接到根。
更好的名称可能是IsAuthoritativeStyleNode,IsCascadingStyleNode,IsStyleParentNode,或者取而代之的是:例如: IsDepartmentRootNode。明确无误的名称是明显提高可读性/易于理解的事情之一。
你无法通过抽象基类/继承实现你想要的。根据其他建议,请考虑接口。
我还要考虑是否让数据库模式过多地驱动客户端类设计。并不是说在这种情况下它需要改变,但至少应该考虑它。考虑如何将属性分解为引用公共“节点”表的单独表,并将它们标准化以最小化空值和/或重复的相同数据。
答案 5 :(得分:0)
PageNode类应该只具有Root类型的属性吗?
这是否反对PageNode is-a Root的想法。或者,它们不是“is-a Root”,因为只有某些是根?
这是否意味着该属性可能遍历树寻找根祖先?或者只是我?