Я знаю, что такое Шаблон посетителя и как его использовать; этот вопрос не является дубликатом этого одного .
У меня есть библиотека, в которую я помещаю большую часть кода, который я могу повторно использовать, и на который я ссылаюсь в большинстве своих проектов.
Часто мне нужно добавлять функции в некоторые классы, но без добавления этих новых функций в библиотеку. Позвольте мне привести реальный пример:
В этой библиотеке у меня есть класс Shape
, унаследованный от CircleShape
, PolygonShape
и CompositeShape
.
Сейчас я разрабатываю графическое приложение, в котором мне нужно визуализировать эти Shape
, но я не хочу помещать виртуальную функцию render
в базовый класс Shape
, так как некоторые из моих проектов, которые используют Shape
не выполняет никакого рендеринга, и другие графические проекты могут использовать другие механизмы рендеринга (я использую Qt для этого проекта, но для игры я бы использовал OpenGL, поэтому функция render
потребует других реализаций).
Самый известный способ сделать это, конечно, использовать Visitor Pattern, но это вызывает у меня несколько сомнений:
Любой класс любой библиотеки может быть расширен как мой Shape
. Большинство публичных библиотек (почти все) не предоставляют никакой поддержки Шаблон посетителя; Зачем? почему я должен?
Шаблон посетителя - это способ симуляции двойной диспетчеризации в C ++. Он не является родным в C ++ и требует явной реализации, что делает интерфейс класса более сложным: я не думаю, что функция applyVisitor
должна быть на том же уровне, что и функции моего класса, я вижу это как нарушение абстракции.
Явное повышение качества Shape
с dynamic_cast
дороже, но для меня это выглядит как более чистое решение.
Итак, что мне делать? Реализация двойной диспетчеризации во всех моих библиотечных классах? Что если библиотека, предоставляющая Shape
, не моя, а какая-то библиотека GPL, найденная в Интернете?