![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Добрый вечер,
В общем есть программа, которая по совместительству является фреймворком. В программе этой есть классы всяких объектов, геометрических фигур, типа rectangle, polygon, text и так далее и естественно у них есть общий предок, пусть будет object. Необходимо иметь возможность модифицировать, копировать и делать другие нехорошие вещи с этим объектами. На данный момент все это сделано через одно место, от меня требуется сделать это через другое. В общем надо заменить безобразие типа
на что-то более вразумительное. Здесь на помощь приходит полиморфизм, но С одной стороны мне не очень хочется обогащать интерфейс несчастного класса object такими функциями, как copy, move, rotate...и так далее. Здесь по моему довольно неплохо справится шаблон visitor, это позволит добавлять новый функционал объектам, не затрагивая при этом самих объектов, но... С другой стороны это фреймворк, другая группа может добавить свой тип объектов, который не обязательно можно перемещать или переворачивать, к тому же добавив новый объект, ему также придется добавлять новую функцию в моем visitor-е, чтобы компиляция прошла. Можно конечно добавить шаблонный метод visit, который будет принимать все остальное и генерировать исключения, но все равно другой группе придется ковыряться в моих "посетителях", на что мне в принципе наплевать, но чтобы сделать объект копируемым и модифицируемым, ему придется добавлять три функции в трех разных классах. Выходит вроде как что с одной стороны хорошо, с другой плохо. Возможно здесь подойдет что-то вроде query interface-а, т.е.
но тогда все функции смешивается в кучу. В общем давайте дружно обсуждать качества и недостатки подходов. Это сообщение отредактировал(а) azesmcar - 10.11.2011, 17:46 |
||||
|
|||||
spyswamp |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 349 Регистрация: 18.8.2006 Репутация: 1 Всего: 7 |
Голосую за полиморфизм. Один раз посидишь, потратишь время, зато не будет дикого оверхеда. Подход должен быть удобный в использовании и очевидный при чтении. А то получится COM какой-то.
![]() -------------------- - why you call it beta? - cuz it's betta then nothin' |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Вопрос, насколько вероятно расширение состава объектов и насколько часто это может происходить.
Если редко, и визитеров предполагается немного, то я бы поставила на визитеров (с доп. шаблоном Visit и т.д.). С другой стороны, простая реализация визитера предполагает (как вариант), что в интерфейсе объекта есть ф-я типа Apply (Vis), а визитер наследуется от абстрактного класса, имеющего метод для каждого существующего класса. Таким образом, если конкретных визитеров много, добавление хотя бы одного типа объекта превращается в тихий ужас. Здесь и могут помочь примесные интерфейсы IMove, ICopy и т.д. Но код
( в каждом месте, где нужно перемещать) - это тоже тихий ужас. Поэтому можно совместить ежа с ужом, т.е. засунуть это дело в визитера, который может содержать методы для всех "стабильных" объектов, а может switch, а может просто преобразовывать obj к IMove... Зачем нам QueryInterface, если есть dynamic_cast. В общем в каждом случае визитера можно реализовывать как удобно. Есть же не только линейные иерархии. Например, полигон - это та же полилиния, но замкнутая, и т.д. Это, конечно, не совсем визитер уже будет, скорее просто некий функциональный объект, напускаемый на фигуры... Но от необходимости добавлять в интерфейс объекта все эти Move точно избавит. -------------------- ... |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
не надо пугать людей.. все это хорошо прячется (внутри функции обертки) и никаких неудобств не причиняет ![]() Добавлено через 3 минуты и 34 секунды
вообще картина описана слишком скудно.. все зависит от насыщенности, куда делить вглубь или вширь.. еслиб парочка конкретных примеров была бы потребованиям, то можно было бы думать.. а так остается только перечислить подходы, и напомнить что может выйграть не чистый вид, а комбинация.. Это сообщение отредактировал(а) mes - 10.11.2011, 19:05 |
|||
|
||||
spyswamp |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 349 Регистрация: 18.8.2006 Репутация: 1 Всего: 7 |
Лучше не примеры, а UML того, что есть сейчас: общая и детальная.
-------------------- - why you call it beta? - cuz it's betta then nothin' |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Ну я, собственно, обертку и предложила... и комбинацию... ![]() Ну да, ну да... Вот у меня в программе как раз для графических объектов реализован вариант простого визитера. Типы объектов давно фиксированы. Но вот подумываю добавить еще один тип (и больше, видимо, долго не понадобится). Вроде все ничего, но визитеров разных развелось просто тьма, по всей программе... При добавлении нового типа, конечно, компилятор поможет - вопить будет. Но править придется много. А если представить, что это делать пришлось бы другой команде... В общем, подумавши, прихожу к выходу, что тут важнее не частота изменений вширь\вглубь, а наличие разных команд. Т.е. нужно строить код так, чтобы "чужие" ковырялись только в собственном... -------------------- ... |
|||
|
||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
||||
|
||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Операций свыше десятка, объектов тоже немало, я затрудняюсь ответить чего здесь больше. Желательно максимально облегчить труд другим группам, при добавлении новых объектов, но при этом не потерять красоты решения. Я сейчас не вспомню все типов и операций, но пусть это будет десяток объектов и операции copy, move, rotate, scale, split, save. Новые команды в принципе добавляются не так часто, объекты тоже, но объекты в основном добавляются совершенно другой группой и труд им желательно максимально облегчить, будет не совсем приятно заставлять их копаться в наших посетителях, это все таки фреймворк и должен предоставлять удобные средства для расширения. А я ни о чем другом и не писал, все варианты в так или иначе реализуют полиморфизм. Вопрос в том, как его реализовать. Вот об этом я и думаю, как бы скомбинировать.
Полиморфизм в голом виде здесь лишь будет засорять интерфейс базового класса, тем более, что не объекты не будут поддерживать все возможные операции. Скажем объект типа point нельзя переворачивать или масштабировать. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
какая задача все таки стоит перед фреймворком ? математические расчеты, визуальный редактор или что то другое ? Добавлено через 2 минуты и 35 секунд какие принципиально отличительные от геометрических фигур бывают объекты, которые разделяют с мими часть команд ? |
|||
|
||||
azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
и то и другое + сохранение результатов в специальный формат файлов, загрузка этих файлов, конвертация... и много чего другого.
это могут быть линейки, флаги, тексты и тому подобное. Другими словами - объекты для разметки. Это сообщение отредактировал(а) azesmcar - 10.11.2011, 21:53 |
||||
|
|||||
spyswamp |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 349 Регистрация: 18.8.2006 Репутация: 1 Всего: 7 |
azesmcar, я имел ввиду унифицированный базовый интерфейс.
Таким образом было очень легко поддерживать кучу элементов технического анализа графиков свечных функций + добавлять новые инструменты, не обязательно связанные с анализом, а просто имеющие возможность присутствовать на графике. Ну, это если не брать в рассчет сами координатные оси и т.п. Они таким же макаром были организованы от базовых графических объектов. Добавлено через 9 минут и 4 секунды azesmcar, естественно, основной базовый класс все в себе не хранит, от него идет несколько абстрактных веток, чтобы разделить объекты по логическим типам и конкретным возможным операциям. Иначе это даже логичным назвать нельзя. Ведь что общего между стрелкой и засечкой со значением на линейке, ГРУБО ГОВОРЯ, кроме метода, скажем, draw? На мой взгляд, подводить все объекты под один базовый тип, это очень сомнительное удовольствие. Это сообщение отредактировал(а) spyswamp - 10.11.2011, 23:27 -------------------- - why you call it beta? - cuz it's betta then nothin' |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
тогда делить надо не по сущностям, а по функционалу..
например так :
на скорую руку но суть я думаю видна.. Добавлено @ 23:56 а должен ли быть этот метод, тоже вопрос.. Это сообщение отредактировал(а) mes - 11.11.2011, 01:45 |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
1. выделено понятие блок с которым можно проводить некоторе кол-во операций
2. возможность операций определяется дескриптором 3. позволено создание нового типа фигуры, путем определения дескриптора и регистрации необходимых методов, как например figure_render_method.. 4. uid позволяет связывать методы разных производителей.. |
|||
|
||||
baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
когда возможно расширение и классов и методов помогает аспектно-ориентированный подход. для него, увы, нет достаточных средств в С++ (да и во многих других популярных языках) поэтому применяются препроцессоры типа AspectC++ и иже с ими.
если задача не слишком сложна, можно привлечь метапрограммирование шаблонов. если есть явный перекос в сторону расширения объектов (либо методов), то принимается одно из соответствующих решений, остальное врукопашную. в данном случае похоже объекты будут чаще добавляться, чем методы. в этом случае как-то не очень... |
|||
|
||||
azesmcar |
|
||||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Тогда модификация какой либо конкретно функции превращается в кошмар. Например чтобы изменить функцию копирования, в этом случае придется модифицировать код в каждом классе. Это уже затрудняет мою дальнейшую работу. Я понимаю, что мне хочется угодить все, что в принципе нереально, потому хочется найти золотую середину.
согласен ![]() потому чистый visitor не подходит. Думаю такое разделение на "стабильных" и не "стабильных" сильно затруднит понимание и чтение кода.
проект огромен, так что задача сложна ![]() по какой причине?
Сложно сказать. У нас редко добавляется и то и другое, но скорее всего так и есть. Методы добавляются редко, объекты добавляют другие, так-что мы часто и не в курсе, это уже другой продукт. нет, но это уже совсем другая задача. Это сообщение отредактировал(а) azesmcar - 11.11.2011, 09:36 |
||||||
|
|||||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |