Аннотация:
Очень часто в программах встречаются сложные структуры, представляющие собой дерево или граф, состоящий из разнотипных узлов. И, конечно же, при этом имеется необходимость обрабатывать этот граф. Самое очевидное решение — добавить в базовый класс виртуальный метод, который перекрыть в наследниках для выполнения нужного действия и осуществления дальнейшей навигации по дереву.
Однако у этого приема есть серьезный недостаток: в нем структура данных оказывается увязанной с обрабатывающими ее алгоритмами. Если нам понадобится алгоритм, отличный от реализованного, то придется добавлять еще один виртуальный метод. Еще хуже, если классы, составляющие дерево, содержатся в недоступном для модификации коде.
Одним из вариантов решения проблемы высокой связности в данном случае является паттерн Посетитель.
АК>Авторы: АК> Андрей Корявченко
АК>Аннотация: АК>Очень часто в программах встречаются сложные структуры, представляющие собой дерево или граф, состоящий из разнотипных узлов. И, конечно же, при этом имеется необходимость обрабатывать этот граф. Самое очевидное решение — добавить в базовый класс виртуальный метод, который перекрыть в наследниках для выполнения нужного действия и осуществления дальнейшей навигации по дереву. АК>Однако у этого приема есть серьезный недостаток: в нем структура данных оказывается увязанной с обрабатывающими ее алгоритмами. Если нам понадобится алгоритм, отличный от реализованного, то придется добавлять еще один виртуальный метод. Еще хуже, если классы, составляющие дерево, содержатся в недоступном для модификации коде. АК>Одним из вариантов решения проблемы высокой связности в данном случае является паттерн Посетитель.
Я могу ошибаться но когда этот патерн становился известным — то мотивация использования была совсем другая ?
Здравствуйте, Дм.Григорьев, Вы писали:
ДГ> Кстати, а зачем нужна эта статья, если в книге все разжевано?
Я бы не сказал, что в книге уж так все подробно разжевано.
Здравствуйте, DangerRSDN, Вы писали:
DRS>А зачем внутри класса лишний раз дергать функции get_Type1Nodes и get_Type2Nodes:
Нет там в реальности никакого лишнего дерганья — JIT без проблем с такой ситуацией справляется и устраняет лишний вызов. А гибкость кода при прямом обращении к полям снижается — мало ли какую логику понадобится в свойства вставить? Например ленивую инициализацию коллекций.
Возник вопрос о целесообразности IContextVisitor<,>, то есть о возможности передачи параметра в метод Visit(…).
Какие есть резумные примеры передачи дополнительно параметра? Не лучше ли его обработку возложить на сам Посетитель?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Возник вопрос о целесообразности IContextVisitor<,>, то есть о возможности передачи параметра в метод Visit(…). _FR>Какие есть резумные примеры передачи дополнительно параметра?
Когда в процессе обработки нужно состояние.
_FR> Не лучше ли его обработку возложить на сам Посетитель?
В смысле? Хранить состояние в полях посетителя? Не очень хороший дизайн, потому что чреват нарушениями инвариантов. И несовместим с функциональным стилем.
... << RSDN@Home 1.2.0 alpha rev. 725 on Windows Vista 6.0.6000.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Не очень хороший дизайн, потому что чреват нарушениями инвариантов. И несовместим с функциональным стилем.
Спасибо. Не обратил внимание, что реализация Visit(…) никак на контекст не влияет, а просто передаёт его visitor-у, так же, как и this. В таком разрезе вопрос снят
Help will always be given at Hogwarts to those who ask for it.
Тупо не понимаю , почему "сложные структуры, представляющие собой дерево или граф, состоящий из разнотипных узлов. И, конечно же, при этом имеется необходимость обрабатывать этот граф." речь идет о стрктурах данных ?
Двойная диспечеризация, разделение алгоритма обработки от структуры и структура и метод обхода данных это все строго ортогональные вещи, почему например этот патерн декларируется для обхода дерева и не может применяться для обхода списка или массива?
Здравствуйте, minorlogic, Вы писали:
M>речь идет о стрктурах данных ?
Речь идет о структуре экземпляров классов в памяти.
M>Двойная диспечеризация, разделение алгоритма обработки от структуры и структура и метод обхода данных это все строго ортогональные вещи
Конечно. Поэтому в статье я постарался максимально разделить эти понятия.
M>, почему например этот патерн декларируется для обхода дерева и не может применяться для обхода списка или массива?
Там нигде не написано, что он не может применятся для обхода списка. Просто деревья — наиболее распространенный случай применения.
... << RSDN@Home 1.2.0 alpha rev. 725 on Windows Vista 6.0.6000.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Там нигде не написано, что он не может применятся для обхода списка. Просто деревья — наиболее распространенный случай применения.
Но например для меня очевидно , что обход дерева и операция с элементом дерева это Ортогональные вещи. Как пример разделения моей уверенности может служить архитектура STL , где обход дерева или массива скрыты за итераторами.
В примере на википедии рассматривается только двойная диспечирезация и нет речи об структурах данных. Кстати в примере "VisitorBase" это очевидно обычный итератор по дереву который еще и двойную диспечеризацию прокидывает. Так же сразу очевидны недостатки и ограниченность этого паттерна , в невозможности расширять базовую иерархию классов и поощрение плохой функциональной декомпозиции базового класса (речь идет о том что функциональность не полностью прописанна через интерфейс и приходится кастить тип наверх).
Здравствуйте, minorlogic, Вы писали:
M>Но например для меня очевидно , что обход дерева и операция с элементом дерева это Ортогональные вещи.
Ну да. И что?
M>В примере на википедии рассматривается только двойная диспечирезация и нет речи об структурах данных.
Ну, с википедией это не ко мне.
M> Кстати в примере "VisitorBase" это очевидно обычный итератор по дереву который еще и двойную диспечеризацию прокидывает.
В этом и суть — объединение итератора и посетителя в случае, если итератор этот единственно возможный.
... << RSDN@Home 1.2.0 alpha rev. 725 on Windows Vista 6.0.6000.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, minorlogic, Вы писали:
M>>Но например для меня очевидно , что обход дерева и операция с элементом дерева это Ортогональные вещи.
AVK>Ну да. И что?
В том что я не вижу пользы от Объединения ортогональных вещей , какая польза от объединения зеленого и шершавого ?
M>> Кстати в примере "VisitorBase" это очевидно обычный итератор по дереву который еще и двойную диспечеризацию прокидывает.
AVK>В этом и суть — объединение итератора и посетителя в случае, если итератор этот единственно возможный.
В этом месте я начинаю терять суть патерна , в чем его польза ? Он как бы состоит из 2-х отдельных приемов. Двойная диспечирезация имеет довольно ограниченное применение. В статье нет реального примера где была бы продемонстрированна его полезность и преимущества. На данный момент меня интересует именно это, кажется с технической частю все более не менее понятно.
Здравствуйте, minorlogic, Вы писали:
M>В том что я не вижу пользы от Объединения ортогональных вещей
Ради бога. Это тебя беспокоит? Хочешь поговорить об этом?
AVK>>В этом и суть — объединение итератора и посетителя в случае, если итератор этот единственно возможный.
M>В этом месте я начинаю терять суть патерна , в чем его польза ?
В том, что это самое примитивное решение, позволяющее это сделать. То что есть и другие — никто не спорит.
M>В статье нет реального примера где была бы продемонстрированна его полезность и преимущества.
Статья не о двойной диспетчеризации, а о паттерне Посетитель. И упоминается она там исключительно в контексте одной из возможных реализаций этого паттерна.
... << RSDN@Home 1.2.0 alpha rev. 725 on Windows Vista 6.0.6000.0>>
M>>В этом месте я начинаю терять суть патерна , в чем его польза ?
AVK>В том, что это самое примитивное решение, позволяющее это сделать. То что есть и другие — никто не спорит.
что ЭТО ? и какие преимущества дает делая ЭТО ?
M>>В статье нет реального примера где была бы продемонстрированна его полезность и преимущества.
AVK>Статья не о двойной диспетчеризации, а о паттерне Посетитель. И упоминается она там исключительно в контексте одной из возможных реализаций этого паттерна.
Вот и суть патерна от меня ускользает , я попробую еще почитать на тему. Суть двойной диспечирезации вроде как ясна ...