Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> полиморфная модификация объектов 
:(
    Опции темы
azesmcar
Дата 10.11.2011, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Добрый вечер,

В общем есть программа, которая по совместительству является фреймворком. В программе этой есть классы всяких объектов, геометрических фигур, типа rectangle, polygon, text и так далее и естественно у них есть общий предок, пусть будет object.
Необходимо иметь возможность модифицировать, копировать и делать другие нехорошие вещи с этим объектами. На данный момент все это сделано через одно место, от меня требуется сделать это через другое.
В общем надо заменить безобразие типа
Код

if (is_rectangle) copy_rectangle();

на что-то более вразумительное.
Здесь на помощь приходит полиморфизм, но
С одной стороны мне не очень хочется обогащать интерфейс несчастного класса object такими функциями, как copy, move, rotate...и так далее. Здесь по моему довольно неплохо справится шаблон visitor, это позволит добавлять новый функционал объектам, не затрагивая при этом самих объектов, но...
С другой стороны это фреймворк, другая группа может добавить свой тип объектов, который не обязательно можно перемещать или переворачивать, к тому же добавив новый объект, ему также придется добавлять новую функцию в моем visitor-е, чтобы компиляция прошла. Можно конечно добавить шаблонный метод visit, который будет принимать все остальное и генерировать исключения, но все равно другой группе придется ковыряться в моих "посетителях", на что мне в принципе наплевать, но чтобы сделать объект копируемым и модифицируемым, ему придется добавлять три функции в трех разных классах.
Выходит вроде как что с одной стороны хорошо, с другой плохо. Возможно здесь подойдет что-то вроде query interface-а, т.е.
Код

if (i_movable *obj = object->query_interface<i_movable>())
{
    obj->move();
} else
{
    throw std::runtime_error("нельзя двигать недвижимость!");
}

но тогда все функции смешивается в кучу.
В общем давайте дружно обсуждать качества и недостатки подходов.


Это сообщение отредактировал(а) azesmcar - 10.11.2011, 17:46
PM   Вверх
spyswamp
Дата 10.11.2011, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 349
Регистрация: 18.8.2006

Репутация: 1
Всего: 7



Голосую за полиморфизм. Один раз посидишь, потратишь время, зато не будет дикого оверхеда. Подход должен быть удобный в использовании и очевидный при чтении. А то получится COM какой-то. smile


--------------------
- why you call it beta?
- cuz it's betta then nothin'
PM MAIL   Вверх
Earnest
Дата 10.11.2011, 19:00 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Вопрос, насколько вероятно расширение состава объектов и насколько часто это может происходить.
Если редко, и визитеров предполагается немного, то я бы поставила на визитеров (с доп. шаблоном Visit и т.д.). 
С другой стороны, простая реализация визитера предполагает (как вариант), что в интерфейсе объекта есть ф-я типа Apply (Vis), а визитер наследуется от абстрактного класса, имеющего метод для каждого существующего класса. Таким образом, если конкретных визитеров много, добавление хотя бы одного типа объекта превращается в тихий ужас. Здесь и могут помочь примесные интерфейсы IMove, ICopy и т.д. Но код 
Код

if (i_movable *obj = object->query_interface<i_movable>())
{
    obj->move();
} else
{
    throw std::runtime_error("нельзя двигать недвижимость!");
}

( в каждом месте, где нужно перемещать) - это тоже тихий ужас.
Поэтому можно совместить ежа с ужом, т.е. засунуть это дело в визитера, который может содержать методы для всех "стабильных" объектов, а может switch, а может просто преобразовывать obj к IMove... Зачем нам QueryInterface, если есть dynamic_cast. В общем в каждом случае визитера можно реализовывать как удобно. Есть же не только линейные иерархии. Например, полигон - это та же полилиния, но замкнутая, и т.д. Это, конечно, не совсем визитер уже будет, скорее просто некий функциональный объект, напускаемый на фигуры... Но от необходимости добавлять в интерфейс объекта все эти Move точно избавит.



--------------------
...
PM   Вверх
mes
Дата 10.11.2011, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Earnest @  10.11.2011,  18:00 Найти цитируемый пост)
 в каждом месте, где нужно перемещать  - это тоже тихий ужас

не надо пугать людей.. все это хорошо прячется (внутри функции обертки) и никаких неудобств не причиняет smile

Добавлено через 3 минуты и 34 секунды
Цитата(Earnest @  10.11.2011,  18:00 Найти цитируемый пост)
 насколько вероятно расширение состава объектов и насколько часто это может происходить.

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




Это сообщение отредактировал(а) mes - 10.11.2011, 19:05


--------------------
PM MAIL WWW   Вверх
spyswamp
Дата 10.11.2011, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 349
Регистрация: 18.8.2006

Репутация: 1
Всего: 7



Лучше не примеры, а UML того, что есть сейчас: общая и детальная.


--------------------
- why you call it beta?
- cuz it's betta then nothin'
PM MAIL   Вверх
Earnest
Дата 10.11.2011, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(mes @  10.11.2011,  20:05 Найти цитируемый пост)
все это хорошо прячется (внутри функции обертки) и никаких неудобств не причиняет 

Ну я, собственно, обертку и предложила... и комбинацию... smile 
Цитата(mes @  10.11.2011,  20:05 Найти цитируемый пост)
вообще картина описана слишком скудно

Ну да, ну да...
Вот у меня в программе как раз для графических объектов реализован вариант простого визитера. Типы объектов давно фиксированы. Но вот подумываю добавить еще один тип (и больше, видимо, долго не понадобится). Вроде все ничего, но визитеров разных развелось просто тьма, по всей программе... При добавлении нового типа, конечно, компилятор поможет - вопить будет. Но править придется много. А если представить, что это делать пришлось бы другой команде... В общем, подумавши, прихожу к выходу, что тут важнее не частота изменений вширь\вглубь, а наличие разных команд. Т.е. нужно строить код так, чтобы "чужие" ковырялись только в собственном...


--------------------
...
PM   Вверх
azesmcar
Дата 10.11.2011, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(mes @  10.11.2011,  19:05 Найти цитируемый пост)
вообще картина описана слишком скудно..

не хотелось сразу грузить тему большим количество деталей, а то вдруг не прочтут smile 

сейчас, сейчас..только вернулся. чуть попозже попробую добавить побольше деталей.
PM   Вверх
azesmcar
Дата 10.11.2011, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(mes @  10.11.2011,  19:05 Найти цитируемый пост)
еслиб парочка конкретных примеров была бы потребованиям, то можно было бы думать.. а так остается только перечислить подходы, и напомнить что может выйграть не чистый вид, а комбинация.. 

Операций свыше десятка, объектов тоже немало, я затрудняюсь ответить чего здесь больше.
Желательно максимально облегчить труд другим группам, при добавлении новых объектов, но при этом не потерять красоты решения.
Я сейчас не вспомню все типов и операций, но пусть это будет десяток объектов и операции copy, move, rotate, scale, split, save.
Новые команды в принципе добавляются не так часто, объекты тоже, но объекты в основном добавляются совершенно другой группой и труд им желательно максимально облегчить, будет не совсем приятно заставлять их копаться в наших посетителях, это все таки фреймворк и должен предоставлять удобные средства для расширения.

Цитата(spyswamp @  10.11.2011,  18:23 Найти цитируемый пост)
Голосую за полиморфизм

А я ни о чем другом и не писал, все варианты в так или иначе реализуют полиморфизм. Вопрос в том, как его реализовать.

Цитата(mes @  10.11.2011,  19:05 Найти цитируемый пост)
может выйграть не чистый вид, а комбинация

Вот об этом я и думаю, как бы скомбинировать.

Цитата(spyswamp @  10.11.2011,  18:23 Найти цитируемый пост)
Подход должен быть удобный в использовании и очевидный при чтении

Полиморфизм в голом виде здесь лишь будет засорять интерфейс базового класса, тем более, что не объекты не будут поддерживать все возможные операции. Скажем объект типа point нельзя переворачивать или масштабировать.
PM   Вверх
mes
Дата 10.11.2011, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(azesmcar @  10.11.2011,  20:24 Найти цитируемый пост)
Операций свыше десятка, объектов тоже немало, я затрудняюсь ответить чего здесь больше.
Желательно максимально облегчить труд другим группам, при добавлении новых объектов, но при этом не потерять красоты решения.

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

Добавлено через 2 минуты и 35 секунд
какие принципиально отличительные от геометрических фигур бывают объекты, которые разделяют с мими часть команд ?



--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 10.11.2011, 21:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(mes @  10.11.2011,  21:33 Найти цитируемый пост)
какая задача все таки стоит перед фреймворком ?  математические расчеты, визуальный редактор или что то другое ?

и то и другое + сохранение результатов в специальный формат файлов, загрузка этих файлов, конвертация... и много чего другого.

Цитата(mes @  10.11.2011,  21:33 Найти цитируемый пост)
какие принципиально отличительные от геометрических фигур бывают объекты, которые разделяют с мими часть команд ?

это могут быть линейки, флаги, тексты и тому подобное. Другими словами - объекты для разметки.

Это сообщение отредактировал(а) azesmcar - 10.11.2011, 21:53
PM   Вверх
spyswamp
Дата 10.11.2011, 23:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 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'
PM MAIL   Вверх
mes
Дата 10.11.2011, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



тогда делить надо не по сущностям, а по функционалу.. 

например так :

Код

struct figure_kind
{
     bool moveable;
     bool rotateable;  
     uint figure_uid;
};

struct figure_render 
{
   void draw (figure_block const& block)
   {
       _map[block.get_figure_uid] (block);
   }
   
   std::map<uint, figure_render_method*> _map;
};


struct figure_block {

      bool can_move () const;
      void move ();
      
      bool can_rotate () const;
      void rotate ();
      
      figure_block (figure_kind const&)..

   private:           
      figure_kind figure_kind;      
};

namespace figure_kind_type {

figure_kind point = { true, false, 0001  },
            rect  = { true, true,  0100  },
            circle = { true, true, 0200  };



}

на скорую руку но суть я думаю видна.. 


Добавлено @ 23:56
Цитата(spyswamp @  10.11.2011,  22:24 Найти цитируемый пост)
кроме метода, скажем, draw? 

а должен ли быть этот метод, тоже вопрос..


Это сообщение отредактировал(а) mes - 11.11.2011, 01:45


--------------------
PM MAIL WWW   Вверх
mes
Дата 11.11.2011, 00:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



1. выделено понятие блок с которым можно проводить некоторе кол-во операций
2. возможность операций определяется дескриптором
3. позволено создание нового типа фигуры, путем определения дескриптора
и регистрации необходимых методов, как например figure_render_method..
4. uid  позволяет связывать методы разных производителей.. 




--------------------
PM MAIL WWW   Вверх
baldina
Дата 11.11.2011, 00:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



когда возможно расширение и классов и методов помогает аспектно-ориентированный подход. для него, увы, нет достаточных средств в С++ (да и во многих других популярных языках) поэтому применяются препроцессоры типа AspectC++ и иже с ими.
если задача не слишком сложна, можно привлечь метапрограммирование шаблонов.
если есть явный перекос в сторону расширения объектов (либо методов), то принимается одно из соответствующих решений, остальное врукопашную.
в данном случае похоже объекты будут чаще добавляться, чем методы.
Цитата(azesmcar @  10.11.2011,  17:36 Найти цитируемый пост)
query interface
 в этом случае как-то не очень...

PM MAIL   Вверх
azesmcar
Дата 11.11.2011, 09:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(mes @  10.11.2011,  23:54 Найти цитируемый пост)
тогда делить надо не по сущностям, а по функционалу.. 

Тогда модификация какой либо конкретно функции превращается в кошмар.
Например чтобы изменить функцию копирования, в этом случае придется модифицировать код в каждом классе. Это уже затрудняет мою дальнейшую работу.
Я понимаю, что мне хочется угодить все, что в принципе нереально, потому хочется найти золотую середину.

Цитата(Earnest @  10.11.2011,  19:24 Найти цитируемый пост)
Т.е. нужно строить код так, чтобы "чужие" ковырялись только в собственном... 

согласен smile 
потому чистый visitor не подходит.

Цитата(Earnest @  10.11.2011,  19:00 Найти цитируемый пост)
Поэтому можно совместить ежа с ужом, т.е. засунуть это дело в визитера, который может содержать методы для всех "стабильных" объектов, а может switch, а может просто преобразовывать obj к IMove... 

Думаю такое разделение на "стабильных" и не "стабильных" сильно затруднит понимание и чтение кода.

Цитата(baldina @  11.11.2011,  00:27 Найти цитируемый пост)
если задача не слишком сложна, можно привлечь метапрограммирование шаблонов.

проект огромен, так что задача сложна smile 

Цитата(baldina @  11.11.2011,  00:27 Найти цитируемый пост)
 в этом случае как-то не очень...

по какой причине?

Цитата(baldina @  11.11.2011,  00:27 Найти цитируемый пост)
в данном случае похоже объекты будут чаще добавляться, чем методы.

Сложно сказать. У нас редко добавляется и то и другое, но скорее всего так и есть. Методы добавляются редко, объекты добавляют другие, так-что мы часто и не в курсе, это уже другой продукт.

Цитата(mes @  10.11.2011,  23:54 Найти цитируемый пост)
а должен ли быть этот метод, тоже вопрос..

нет, но это уже совсем другая задача.


Это сообщение отредактировал(а) azesmcar - 11.11.2011, 09:36
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1240 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.