Элемент с подэлементами
От: sax0n Украина  
Дата: 25.11.10 13:01
Оценка:
привет.
есть некий интерфейс IElement. В иерархии есть класс IGroup, который имеет все свойства интерфейса IElement, но отличается лишь тем, что может внутри хранить другие элементы и группы (некое дерево).

вопрос в том, какой паттерн используется для работы с такой иерархией?

class IElement
{
public:
  virtual std::string GetName() = 0;
  virtual void Export() = 0;
};

class IGroup: public IElement
{
public:
  virtual std::string GetName() = 0;
  virtual void Export() = 0;
};

class Group: IGroup
{
public:
  virtual std::string GetName(){ return ""; }
  virtual void Export(){}
private:
  std::vector< IElement > m_children;
};


Как это описать так, чтобы с одной стороны я всегда знал, какой тип у m_children[i], и с другой стороны мог работать с группой, как с элементом?
Пока в голову пришел только Посетитель (GoF): создать итератор на основе посетителя всей иерархии.
есть какие-то стандартные приемы, примеры?
Re: Элемент с подэлементами
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 25.11.10 13:58
Оценка:
Здравствуйте, sax0n, Вы писали:

S>есть какие-то стандартные приемы, примеры?

Обычно в таких случаях элемент сразу делается группой, т.е. не создают два класса — Элемент и Группа, а используют один. В качестве примера могу сослаться на объект Окно в Win32 API. Оно имеет указатель на родителя, входит в список сиблингов и хранит указатель на список чайлдов.

Другой вариант — сделать, как сделали Вы. Тогда смотрите в сторону паттерна Компоновщик.

P.S.: А для чего Вам нужна иерархия элементов? За выполнение каких обязанностей будет отвечать класс Элемент?
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[2]: Элемент с подэлементами
От: sax0n Украина  
Дата: 25.11.10 14:37
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Обычно в таких случаях элемент сразу делается группой, т.е. не создают два класса — Элемент и Группа, а используют один. В качестве примера могу сослаться на объект Окно в Win32 API. Оно имеет указатель на родителя, входит в список сиблингов и хранит указатель на список чайлдов.


скиньте, пожалуйста, пример. для ГУИ тоже очень интересно посмотреть пример.
кстати, в примере из вики по ссылке ниж, по сути, элемент и есть группа (по интерфейсу).

КЛ>Другой вариант — сделать, как сделали Вы. Тогда смотрите в сторону паттерна Компоновщик.


В том примере компоновщик делает проверку во время выполнения. такое и я могу сделать. а я хочу во время компиляции, а лучше вообще без доступа к группирующим методам

КЛ>P.S.: А для чего Вам нужна иерархия элементов? За выполнение каких обязанностей будет отвечать класс Элемент?

В целом, у меня есть набор элементов (IElement) в пределах определенной области.
В этой области я могу создавать свои объекты (IObject), свойства которых могут быть основаны на свойствах 1+ IElement.
в иерархии IObject есть такие, которые могут хранить в себе другие IObject (IGroup).

В итоге у меня есть дерево IObject, по которому я могу пройтись, но я так же хочу иметь возможность сохранить информацию о типе, т.е. знать, что конкретный IObject есть IGroup или его наследник.
Возможно, я в корне неправильно составил иерархию.

Примером аналогии могут быть теги из HTML, например, <div> — сам по себе это ITag, но у него есть children()
вот что-то типа такого нужно сделать.
Re: Элемент с подэлементами
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 25.11.10 14:55
Оценка:
Здравствуйте, sax0n, Вы писали:

S>Как это описать так, чтобы с одной стороны я всегда знал, какой тип у m_children[i], и с другой стороны мог работать с группой, как с элементом?

S>Пока в голову пришел только Посетитель (GoF): создать итератор на основе посетителя всей иерархии.
S>есть какие-то стандартные приемы, примеры?

В GoF это будет Composite.

"итератор на основе посетителя" — это сильно
Re[2]: Элемент с подэлементами
От: sax0n Украина  
Дата: 25.11.10 14:58
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>"итератор на основе посетителя" — это сильно

это не самое худшее, что приходило в голову
нужно еще разок GoF перечитать.. как-то не собирается воедино все.
Re[3]: Элемент с подэлементами
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 25.11.10 15:08
Оценка: -1
Здравствуйте, sax0n, Вы писали:

I>>"итератор на основе посетителя" — это сильно

S>это не самое худшее, что приходило в голову
S>нужно еще разок GoF перечитать.. как-то не собирается воедино все.

Для паттернов, возьми книгу например Джошуа Кериевски, "Рефакторинг с использованием шаблонов".

В ней паттерны расписываются гораздо лучше и понятнее, автор злоупотребил Фаулером, но в целом очень, очень сильно.

Кроме того, есть книга Кента Бека "Экстремальное программирование. Разработка через тестирование" — просто адская вещь.

GoF это вобщем то словарь, что бы можно было читать книги вроде перечисленых. Без них она смысла в ней мало.
Re[4]: Элемент с подэлементами
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 25.11.10 15:47
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Кроме того, есть книга Кента Бека "Экстремальное программирование. Разработка через тестирование" — просто адская вещь.

Это не та книжка, в которой Кент Бек объяснял пользу юнит-тестирования на примерчиках:

assertFalse(Money.franc(5).equals(Money.dollars(5)));


?
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[3]: Элемент с подэлементами
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 25.11.10 15:55
Оценка:
Здравствуйте, sax0n, Вы писали:

S>скиньте, пожалуйста, пример. для ГУИ тоже очень интересно посмотреть пример.


Посмотрите здесь.

S>В том примере компоновщик делает проверку во время выполнения. такое и я могу сделать. а я хочу во время компиляции, а лучше вообще без доступа к группирующим методам


Зачем?

S>Возможно, я в корне неправильно составил иерархию.


ИМХО, слишком сложно. Да и непонятно, зачем нужны разные типы. Создайте один объект — Узел дерева. Он может быть и листом, и поддеревом. И в любой момент преобразоваться из листа в поддерево, а из поддерева — в лист (путём добавления или удаления дочерних элементов).

Если уж такое решение кажется некрасивым, то создайте два класса — Элемента и Группа и преобразуйте один к другому в ран-тайме.

А вообще, дизайн сильно зависит от того, какие операции Вы будете выполнять над этим деревом. Пока что Вы описали его в статике, а чтобы посоветовать что-то конкретное хорошо бы знать динамику.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[5]: Элемент с подэлементами
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 25.11.10 16:08
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

I>>Кроме того, есть книга Кента Бека "Экстремальное программирование. Разработка через тестирование" — просто адская вещь.

КЛ>Это не та книжка, в которой Кент Бек объяснял пользу юнит-тестирования на примерчиках:

КЛ>
КЛ>assertFalse(Money.franc(5).equals(Money.dollars(5)));
КЛ>


КЛ>?


Да, она. Только там не про пользу юнит-тестирования, а про решение задачи с использованием юнит-тестирования.
Re[6]: Элемент с подэлементами
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 26.11.10 08:33
Оценка: +1 -2
Здравствуйте, Ikemefula, Вы писали:

I>Да, она. Только там не про пользу юнит-тестирования, а про решение задачи с использованием юнит-тестирования.


В таком случае, я бы не стал рекомендовать эту книгу по двум основаниям.

Во-первых, соотношения курсов валют определяют финансовые площадки, а не непонятный класс Money.

Во-вторых, дизайн, в котором названия валют зашиты в виде функций, ни к чему хорошему не приведёт: код придётся изменять при желании поддержать новую валюту.

Резюме: подход к проектированию, который не позволяет вовремя просечь эти вещи, ИМХО, не является работоспособным.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[6]: Элемент с подэлементами
От: sax0n Украина  
Дата: 26.11.10 08:49
Оценка:
КЛ>>
КЛ>>assertFalse(Money.franc(5).equals(Money.dollars(5)));
КЛ>>


Книжку многие рекомендуют, так что почитать стоит. но конкретно этот вырванный из контекста код выглядит немного некрасиво ( Money.dollars )
Re[7]: Элемент с подэлементами
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 26.11.10 08:57
Оценка: -1
Здравствуйте, sax0n, Вы писали:

S>Книжку многие рекомендуют, так что почитать стоит. но конкретно этот вырванный из контекста код выглядит немного некрасиво ( Money.dollars )


Там везде такой код.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[4]: Элемент с подэлементами
От: sax0n Украина  
Дата: 26.11.10 09:43
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Посмотрите здесь.

WinAPI в теме про ООП — не особо хороший пример ИМХО. C-style со своими плюшками. Или я не туда посмотрел?

S>>В том примере компоновщик делает проверку во время выполнения. такое и я могу сделать. а я хочу во время компиляции, а лучше вообще без доступа к группирующим методам

КЛ>Зачем?
Александреску начитался =)
а вообще, почему Зачем?! для легкости и однозначности использования, типобезопасности и т.д.

КЛ>ИМХО, слишком сложно. Да и непонятно, зачем нужны разные типы. Создайте один объект — Узел дерева. Он может быть и листом, и поддеревом. И в любой момент преобразоваться из листа в поддерево, а из поддерева — в лист (путём добавления или удаления дочерних элементов).


КЛ>Если уж такое решение кажется некрасивым, то создайте два класса — Элемента и Группа и преобразуйте один к другому в ран-тайме.


почему же сложно?
я хочу, чтобы в моем интерфейсе IElement только в нужный момент появлялись методы интерфейса IGroup, чтобы они были вообще недоступны для обычных элементов (а не были заглушки).
не хочется делать так для всех элементов:

structure< IElement >::iterator iter;
if ( iter->hasChildren() ){}


а хочется точно знать, что у этого элемента могут быть (0+ штук) или не могут быть элементы вообще и т.д. Можно сделать и так, как вы предлагаете. просто есть возможность еще поиграться и выбрать самую удобную, красивую и безопасную архитектуру.
Re[8]: Элемент с подэлементами
От: sax0n Украина  
Дата: 26.11.10 10:55
Оценка:
КЛ>Там везде такой код.
беда, беда..

встречный вопрос, а что тогда почитать?
у меня лежит GoF и Фаулер "Проектирование корпоративных приложений".
Хочется чего-то практического, а не просто справочник полистать по паттернам.
Re[9]: Элемент с подэлементами
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 26.11.10 11:03
Оценка:
Здравствуйте, sax0n, Вы писали:

S>встречный вопрос, а что тогда почитать?


Посмотрите здесь и здесь.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[7]: Элемент с подэлементами
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 26.11.10 11:03
Оценка:
Здравствуйте, sax0n, Вы писали:

КЛ>>>
КЛ>>>assertFalse(Money.franc(5).equals(Money.dollars(5)));
КЛ>>>


S>Книжку многие рекомендуют, так что почитать стоит. но конкретно этот вырванный из контекста код выглядит немного некрасиво ( Money.dollars )


Конкретно этот кусок кода это из теста в процессе разработки.

Загляни в книгу, там можешь конечный результат увидеть
Re[7]: Элемент с подэлементами
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 26.11.10 11:07
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

I>>Да, она. Только там не про пользу юнит-тестирования, а про решение задачи с использованием юнит-тестирования.


КЛ>В таком случае, я бы не стал рекомендовать эту книгу по двум основаниям.


КЛ>Во-первых, соотношения курсов валют определяют финансовые площадки, а не непонятный класс Money.


Если бы ты читал книгу, то там бы и прочел, что Кент Бек и говорит, что Money описывает валюту, а не курсы валют.

Курсы валют для класса Money это внешняя сущность. Задача, на которой он показывал TDD, была исключительно про валюту.

КЛ>Во-вторых, дизайн, в котором названия валют зашиты в виде функций, ни к чему хорошему не приведёт: код придётся изменять при желании поддержать новую валюту.


У меня еще одно сомнение, что ты читал книгу.

КЛ>Резюме: подход к проектированию, который не позволяет вовремя просечь эти вещи, ИМХО, не является работоспособным.


См. выше.
Re[10]: Элемент с подэлементами
От: sax0n Украина  
Дата: 26.11.10 11:13
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Здравствуйте, sax0n, Вы писали:


S>>встречный вопрос, а что тогда почитать?


КЛ>Посмотрите здесь и здесь.

не совсем подходит. нужна 1-2 книжки, а не 100500..
Re[8]: Элемент с подэлементами
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 26.11.10 22:14
Оценка: :)
Здравствуйте, Кирилл Лебедев, Вы писали:

S>>Книжку многие рекомендуют, так что почитать стоит. но конкретно этот вырванный из контекста код выглядит немного некрасиво ( Money.dollars )


КЛ>Там везде такой код.


Враньё !

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

Ты книги не читал, лучше б молчал
Re[9]: Элемент с подэлементами
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 26.11.10 22:26
Оценка:
Здравствуйте, sax0n, Вы писали:

S>встречный вопрос, а что тогда почитать?

S>у меня лежит GoF и Фаулер "Проектирование корпоративных приложений".
S>Хочется чего-то практического, а не просто справочник полистать по паттернам.

Фаулер это немного другая область.

Попробуй те книги что я тебе предложил.

Если уж сильно не доверяешь Кенту Беку, посмотри книгу Физерса "Legacy Code" или Роберта Мартина "Чистый код", но это достаточно сложные книги.

Одно плохо — у Фаулер, Физерс, Мартин, Бек, Кериевски, Эванс, Канингем — это одна и таже банда.

Они все дизайн выводят через тестирование/рефакторинг/итерации.

Если ты хочешь посмотреть деяния другой ОПГ — попробуй Буча или Лармана, там совершенно другой подход к проектированию. Но лично я плохо знаком с работами этих товарищей.

Кстати, есть такая вещь, как Funq, автор — Daniel Cazzulino записал серию скринкастов как он разрабатывал этот фреймворк.

Там используется именно тот подход, который описывает Кент Бек в книге про TDD.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.