Как стать автором
Обновить

Комментарии 17

А если состояний 25? Писать 25 классов и для всех городить этот велосипед? Оно и не факт что более безопасно. Если методы у экранов похожи то возникнет копипаст, а если не копипаст а выдрать часть в отдельную функцию то опять один код на двоих будет. Странное решение.
25 состояний одного уровня — это не очень хороший дизайн (если эти состояния действительно различаются по логике, а не просто номер в каком-то списке). При таком кол-ве состояний, их бы стоило разбивать на какие-то подгруппы. И логика выделения каждому состоянию класса предполагает, что внутри этого класса могут быть свои вложенные состояния.
НЛО прилетело и опубликовало эту надпись здесь
Про цвет — если это выглядит как массив более-менее однородных объектов, то и 25, и 125 — норма. Просто для этого и нужно использовать не вариант а какой-то вариант массива и итератора на него.

Т.е. образно: 25 элементов в массиве — хорошо, 25 членов в структуре — плохо.

Какой еще диагноз? Я абсолютно здоров :)
Да, я постоянно ищу что-то новое, но внимательно слежу за тем, чтобы это новое было реально полезно на практике.
Очень просто — если у вас будет 25 экранов, то не факт, что у всех будет присутствовать метод get_elements и далеко не факт, что как выбрать эти элементы можно будет сказать заранее. Поэтому мы оставляем за Visitor-ом возможность переопределения функции get_elements для каждого типа экрана. Ежели, например, у десяти экранов будет метод одинаков, то автор отнаследует их от базового класса, у визитора появится новый метод operator() — который как параметр возьмет, именно базовый класс.
Вообще в топик, хорошая иллюстрация к симбиозу, паттерна Visitor из книжки Гаммы, и одного из правил по книжке Мейера «Предпочитайте ошибки компиляции ошибкам времени исполнения»
Не совсем понял изначальную проблему, но если я ее понял правильно, то городить все это нет особого смысла.

Если реализация методов отличается, то создается абстрактный интерфейс (IScreen) и производные классы наследуюся от данного интерфейса.
Либо используются виртульные методы.

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

PS: за boost::static_visitor спасибо — не знал про такой.
IScreen не дает возможности определять логику обработки модели снаружи. Вы обязаны определить в нем конкретные ф-ции DoDraw, SoSmthElse. С визиторами, вы для одной и той же модели можете добавлять различные инструменты восприятия. Разумеется, есть механизм визиторов и на интерфейсах, но он тоже не обеспечивает ран-таймовой корректности состояний.
Поправьте меня, если я неправ, но в приведенном примере можно было бы применить обычное наследование от интерфейса. Если вы хотели показать полезность подхода, стоило бы привести пример, в котором явно видно, чем он лучше такого наследования. Я с ходу не увидел.
Да, чтото спорное решение. Тут актуальнее либо обычное наследование или интерфейс, либо шаблонный метод.
Более сложные задачи требуют более мощных инструментов для решения.
Или наоборот — с более мощными инструментами, вы можете решать более сложные задачи.
Теорема Пифагора — оно, конечно, хорошо, но зачем-то уже в наше время придумали тензоры и еще кучу странных вещей. Которые для многих выглядят весьма сложными на первый взгляд.
Не так уж оно и сложно как кажется, если попробовать применить.
Более сложные задачи требуют более мощных инструментов для решения.
Или наоборот — с более мощными инструментами, вы можете решать более сложные задачи.
Теорема Пифагора — оно, конечно, хорошо, но зачем-то уже в наше время придумали тензоры и еще кучу странных вещей. Которые для многих выглядят весьма сложными на первый взгляд.
Не так уж оно и сложно как кажется, если попробовать применить.
Идея интересная, но действительно не совсем понятно — почему в данном случае нельзя было применить обычный runtime-полиморфизм на виртуальных функциях? Приведённое решение хорошо подходит для варианта, когда набор типов, для которых требуется обеспечить полиморфное поведение, недоступен для модификации (third-party-классы, нативные типы). Чтобы не городить огород из собственных классов-обёрток variant + static_visitor — вполне подходят. А вот в приведённом примере…
Пример с экранами выбран исключительно для наглядности. В похожих ситуациях в реальности я лично применял оба подхода (и интерфейсный, и вариантный) в разное время.
И знаете, чисто субъективно вариантный мне нравится больше. Как-то в нем более строгое связывание получается. Модель данных — это чистая модель, незамутненная логикой обработки себя. Логика отрисовки (преобразование в html или еще что) выделена как отдельная сущность, как-то в стороне от модели.
И знаете, чисто субъективно вариантный мне нравится больше. Как-то в нем более строгое связывание получается. Модель данных — это чистая модель, незамутненная логикой обработки себя. Логика отрисовки (преобразование в html или еще что) выделена как отдельная сущность, как-то в стороне от модели.

Зато имеет существенный недостаток — высокая степень связности. Если в интерфейсной реализации поставщик данных зависит только от интерфейса потребителя (который может быть весьма «узким»), то в вариантном — требуется доступ к полному определению. Причём всех потребителей. В простых случаях на это можно пойти. В общем случае — не самое удачное архитектурное решение.
Согласен, связность повышается. При изменении объекта, вы должны тут же изменить визиторы его обработки.

Если речь о взаимодействии различных модулей, использование интерфейсов может быть эффективнее.
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории