Нет ли лучшего способа отображения объекта, чем использование иерархии? - PullRequest
3 голосов
/ 09 октября 2008

У меня есть иерархия классов как таковая:

        +-- VirtualNode
        |
INode --+                  +-- SiteNode
        |                  |
        +-- AbstractNode --+
                           |
                           +-- SiteSubNode

И соответствующий класс NodeCollection, основанный на INode. Для отображения NodeCollection мне нужно знать окончательный тип каждого члена. Поэтому мне нужна такая функция

foreach (INode n in myNodeCollection)
{
    switch(n.GetType())
    {
        case(typeof(SiteNode)):
        // Display n as SiteNode
    }
}

Теперь, это действительно не объектно-ориентированный способ сделать это. По вашему мнению, есть ли какие-то шаблоны или рекомендуемые способы сделать то же самое?

EDIT
Я уже думал о добавлении метода Display или Render в интерфейс INode. У этого есть побочный эффект соединения взгляда с моделью, которого я действительно хотел бы избежать.

Ответы [ 3 ]

1 голос
/ 09 октября 2008

Полиморфизм:

Когда у вас есть оператор выбора, использующий тип объекта, он является основным кандидатом для рефакторинга полиморфизма.

Проверьте книгу Рефакторинг Мартина Фаулера:

"Одним из наиболее очевидных симптомов объектно-ориентированного кода является его сравнительное отсутствие переключения (или дела) заявления. Проблема с инструкциями switch по существу заключается в дублировании. Часто ты найти один и тот же оператор switch, разбросанный по программе в разных местах. Если вы добавите новый В предложении к переключателю вы должны найти все эти переключатели, операторы и изменить их. Отклоненный Понятие полиморфизма дает вам элегантный способ справиться с этой проблемой.

В большинстве случаев вы видите оператор switch, вы должны учитывать полиморфизм. Вопрос в том, где полиморфизм должен произойти. Часто оператор switch включает код типа. Ты хочешь метод или класс, который содержит значение кода типа. Так что используйте метод извлечения, чтобы извлечь переключатель оператор, а затем метод Move, чтобы получить его в классе, где необходим полиморфизм. В В этот момент вы должны решить, заменить ли код типа на подклассы или заменить Введите код с государством / стратегии. Когда вы настроили структуру наследования, вы можете использовать Заменить условное на полиморфизм. "

Вот один из подходов к использованию полиморфизма в вашей ситуации:

  1. Определить абстрактный метод в AbstractNode назвал что-то вроде Дисплей ().

  2. Затем на самом деле реализовать Display () в каждый из SiteNode и SiteSubNode классы.

  3. Затем, когда вам нужно отобразить эти узлы, вы можете просто повторить через коллекцию, содержащую элементы типа AbstractNode и вызова Дисплей () для каждого.

  4. вызов Display () будет автоматически разрешить до фактического конкретная реализация для реального тип этого предмета.

  5. Примечание: вы также можете переместить Метод Display () из AbstractNode к интерфейсу INode, если Виртуальный узел должен отображаться.

1 голос
/ 09 октября 2008

Что вам нужно, это шаблон посетителей , я думаю.

0 голосов
/ 09 октября 2008

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

Если вы не можете изменить базовый интерфейс - реализуйте методы расширения для каждого из классов и попросите их вернуть «представление» для каждого конкретного класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...