.NET абстрактные классы - PullRequest
       34

.NET абстрактные классы

2 голосов
/ 17 сентября 2008

Я разрабатываю иерархию навигации по сайту. Это дерево узлов.

Большинство узлов - это страницы. Некоторые узлы являются ссылками (например, ярлыки в Windows).

Большинство страниц содержат HTML-контент. Некоторые исполняют код.

Я бы хотел представить их как коллекцию классов и абстрактных (MustInherit) классов & hellip;

class diagram

Это таблица базы данных, в которой я собираюсь хранить все это & ​​hellip;

таблица базы данных http://img178.imageshack.us/img178/8573/nodetablefm8.gif

Вот где я в тупике. Узлы страниц могут быть или не быть корнями.

Как мне обращаться с корневым классом?

class diagram

Я не хочу иметь все четыре из & hellip;

  • HtmlPageNode
  • CodePageNode
  • Html Root PageNode
  • Код Root PageNode

Я хочу, чтобы классы HtmlPageNode и CodePageNode наследовали либо от PageNode, либо от RootPageNode. Это возможно?


Уточнение: существует несколько корневых узлов, и корни могут иметь родительские узлы. Каждый является корнем только поддерева, которое имеет различные стили. Подумайте о разных цветовых отделах. (Возможно, root - плохой выбор имени. Предложения?)


Обновление: по поводу "корневого" имени ...
Я спросил: Есть ли конкретное имя для узла, который coresponds к поддереву?

Ответы [ 6 ]

2 голосов
/ 17 сентября 2008

Как уже отмечалось, составной шаблон может быть хорошим решением.

Если это не работает для вас, может быть проще - если это уместно - определить Root как интерфейс и применять его по мере необходимости.

Конечно, это не позволяет вам предоставить какую-либо реализацию для Root ...
Если Root должен иметь реализацию, вы можете использовать Pattern Decorator.

2 голосов
/ 17 сентября 2008

Используйте составной шаблон .


Что касается ваших корневых узлов, есть ли различия в функциональности или это только внешний вид? Если разница только в внешнем виде, я предлагаю вам связать отдельный класс стилей с вашим PageNode.

Если есть различия в функциональности И у вас много типов страниц, подумайте об использовании Pattern Decorator .

1 голос
/ 17 сентября 2008

Уточнение: существует несколько корневых узлов, и корни могут иметь родительские узлы. Каждый является корнем только поддерева, которое имеет различные стили. Подумайте о разных цветовых отделах. (Возможно, root - плохой выбор имени. Предложения?)

Корень - плохой выбор имени, потому что он (несколько иронично) принят явно как верхний уровень древовидной структуры, потому что дерево начинается там, где корень выходит из-под земли. Любой узел за этим является ветвью или листом и не связан напрямую с корнем.

Лучшим именем было бы что-то вроде IsAuthoritativeStyleNode, IsCascadingStyleNode, IsStyleParentNode или вместо этого его можно квалифицировать: например, IsDepartmentRootNode. Предоставление четких однозначных названий - это одна из тех вещей, которая значительно улучшает читабельность / легкость понимания.

Вы не можете реально достичь того, чего хотите, просто с помощью абстрактных базовых классов / наследования. Согласно другим предложениям, рассмотрите интерфейсы вместо этого.

Я бы также подумал о том, чтобы позволить схеме базы данных слишком сильно влиять на дизайн класса на стороне клиента. Не сказать, что это нужно изменить в этом случае, но об этом, по крайней мере, нужно подумать. Подумайте, как можно разделить свойства на отдельные таблицы, ссылающиеся на общую таблицу «Узлы», и нормализовать их, чтобы минимизировать пустые значения и / или дублировать идентичные данные.

1 голос
/ 17 сентября 2008

Я хочу, чтобы классы HtmlPageNode и CodePageNode наследовали либо от PageNode, либо от RootPageNode. Это возможно?

Да, это возможно. Вы должны иметь HtmlPageNode и codePageNode иметь объект, который будет абстрактным классом, который будет наследовать PageNode, и RootPageNode тоже. В конструкторе HtmlPageNode и codePageNode вы принимаете ваш новый класс Abstract, который будет в вашем случае PageNode OR RootPageNode. Таким образом, у вас есть 2 разных класса с одинаковыми методами, но два разных объекта. Надеюсь, что это поможет вам!

1 голос
/ 17 сентября 2008

На самом деле, поскольку «корневой» узел является особым случаем узла, возможно, вам нужен 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;
      }
   }
}

Предполагается, что каждый узел имеет ссылку на своего родителя.

Это стало гораздо более важным, так как я не знаю точный дизайн.

0 голосов
/ 17 сентября 2008

Должен ли класс PageNode просто иметь свойство типа Root?

alt text

Это противоречит идее, что PageNode - это Root. Или они не являются "корнем", потому что только некоторые из них являются корнями?

И означает ли это, что свойство может пересекать дерево в поисках корневого предка? Или это только у меня?

...