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

Поиск:

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


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


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

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



azesmcar, 
Цитата(azesmcar @  15.11.2011,  15:22 Найти цитируемый пост)
Давайте перед началом сравнения проясним кое-что. Я не нашел в Вашем примере где Вы вообще обрабатываете объекты? Вы вызвали обработчик, но где ему передается rectangle, polygon и тому подобное?

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

А вспомнил еще один недостаток монолитного QI, при множественном наследовании может возникнуть коллизия имен.. ( ну и пра затруднительное проксирование я уже говорил)... 

я кажись придумал откуда надо плясать.. 




Это сообщение отредактировал(а) mes - 15.11.2011, 16:56


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


uploading...
****


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

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



Цитата(mes @  15.11.2011,  16:50 Найти цитируемый пост)
Я бы предпочел вариант,  "что я от этого выигрываю"... 

Но ведь что я теряю - это тоже важно, потому вариант не подходит smile

Добавлено через 1 минуту и 15 секунд
Цитата(mes @  15.11.2011,  16:54 Найти цитируемый пост)
А вспомнил еще один недостаток монолитного QI, при множественном наследовании может возникнуть коллизия имен.. ( ну и пра затруднительное проксирование я уже говорил)... 

Да, это есть, но это не так страшно. В данном случае меня больше всего волнует монолитность класса и использование кастов. Здесь я вижу самый большой минус.

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


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


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

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



Цитата(azesmcar @  15.11.2011,  15:54 Найти цитируемый пост)
Но ведь что я теряю - это тоже важно, потому вариант не подходит 

Так по большему счеты вы ничего не теряете, просто переводите в другую плоскость.. 



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


uploading...
****


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

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



Попробую еще раз сформулировать свою позицию.
Ваш пример сильно усложняет дизайн и чтение кода, добавляет работы, при этом он конечно вносит некоторое количество плюсов, 90% которых в данном случае не нужны и использоваться не будут.
Единственное его достоинство, которое в моей задаче является большим плюсом - это ослабленная монолитность, но я пока не чувствую, что оно того стоит.

Цитата(mes @  15.11.2011,  16:58 Найти цитируемый пост)
Так по большему счеты вы ничего не теряете, просто переводите в другую плоскость.. 

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

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


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


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

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



Цитата(azesmcar @  15.11.2011,  15:54 Найти цитируемый пост)
 В данном случае меня больше всего волнует монолитность класса и использование кастов.

вот о жертвах..  при правильном подходе монолитности не будет и при подходе с интерфейсами, только придется прикрутить, QI
рeгистрацию интерфейсов и ту же кучу кода как при Command.. 

преимущества : получение полноценного интерфейса.. 
несдостатки усложненость при составлении цепочки ответсвенностей.. 

у Command акценты расставлены наоборот..






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


uploading...
****


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

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



Цитата(mes @  15.11.2011,  17:04 Найти цитируемый пост)
вот о жертвах..  при правильном подходе монолитности не будет и при подходе с интерфейсами, только придется прикрутить, QI

Каким образом? Где будет реализован интерфейс, если не в самих классах?

Добавлено через 2 минуты и 37 секунд
Цитата(mes @  15.11.2011,  17:04 Найти цитируемый пост)
при правильном подходе монолитности не будет и при подходе с интерфейсами, только придется прикрутить, QI

давайте подумаем в этом направлении.


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


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


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

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



Цитата(azesmcar @  15.11.2011,  15:59 Найти цитируемый пост)
Единственное его достоинство, которое в моей задаче является большим плюсом - это ослабленная монолитность

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

и так, у нас есть набор интерфейсов, предполагается маличие QI, как получить ослабленную монолитность.. 
сейчас должен отойти, чуть позже напишу пример.. 


Цитата(azesmcar @  15.11.2011,  15:59 Найти цитируемый пост)
И в общем-то я не уверен, что у меня получится.

Да от понимания концепции сильно зависит реализация.. Тогда следующие решения буду предлагать с учетом этого.. вышеобсужденные требовани оставляю в силе smile

Добавлено через 1 минуту и 18 секунд
Цитата(azesmcar @  15.11.2011,  16:06 Найти цитируемый пост)
давайте подумаем в этом направлении.

я как раз об этом написал.. значит нашли точку соприкосновения.. дальше нужно стараться не потерять, а то у насдо этого получалось переливание оз пустого в порожнее smile



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


uploading...
****


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

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



Цитата(mes @  15.11.2011,  17:11 Найти цитируемый пост)
Да от понимания концепции сильно зависит реализация

Я имел ввиду, не уверен, что у меня получиться объяснить. smile 

Цитата(mes @  15.11.2011,  17:11 Найти цитируемый пост)
Еще раз.. я не знаю вашу задачу поэтому не могу подобрать правильно подходящее решение

Я действительно не могу описать ее всю целиком, мне надо будет рассказывать всю архитектуру проекта, а это займет пару дней smile 
В принципе основные ключевые моменты я описал, остальное приходится рассказывать по мере необходимости.
PM   Вверх
mes
Дата 15.11.2011, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



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


Это сообщение отредактировал(а) mes - 15.11.2011, 17:20


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


uploading...
****


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

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



Цитата(mes @  15.11.2011,  17:18 Найти цитируемый пост)
пока вы тут, опишите фигуру, кроме перемещения и поворота что она умеет, ив каких случаях она не должна.. 

mirroring, scale, смена layer-а.
там на самом деле не только фигуры, есть флаги, точки, которые нельзя передвигать или вращать, зато можно копировать или сохранять в файл, т.е. нужна сериализация. Третье лицо может добавить свой топ, который нельзя копировать, в общем вариаций много.
PM   Вверх
azesmcar
Дата 15.11.2011, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



вот что пока что получилось, сейчас надо бежать, позже буду дорабатывать, просто выложил в качестве сырья и объекта для обсуждения написанный на скорую руку.
Код

#include <iostream>
#include <map>

struct geom;
struct rectangle;

struct i_interface
{
    virtual ~i_interface() {};
};

struct i_serilization: i_interface
{
    enum { iid = 1 };
    virtual std::string serilize() const = 0;
};

template <typename T> struct object_serialization: i_serilization
{
public:
    object_serialization(const T* o): object(o) {}
protected:
    const T* get_object() const
    {
        return object;
    }
private:
    const T* object;
};

struct rectangle_serialization: object_serialization<rectangle>
{
    rectangle_serialization(const rectangle* o): object_serialization(o) {}
    std::string serilize() const
    {
        std::cout << "rectangle " << get_object() << std::endl;
        return "";
    }
};

struct geom
{
public:
    template <typename T> void register_interface(T* iface)
    {
        interfaces[T::iid] = iface;
    }
    template <typename T> T* query_interface()
    {
        auto it = interfaces.find(T::iid);
        if (it != interfaces.end())
        {
            return dynamic_cast<T*>(it->second);
        }
        return 0;
    }
private:
    std::map<int, i_interface*> interfaces;
};

struct rectangle : geom
{
    rectangle()
    {
        register_interface(new rectangle_serialization(this));
    }
};

int main()
{
    geom *obj = new rectangle();
    if (i_serilization * i = obj->query_interface<i_serilization>())
    {
        i->serilize();
    }
}



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


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


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

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



Цитата(azesmcar @  15.11.2011,  16:47 Найти цитируемый пост)
  template <typename T> void register_interface(T* iface)
    {
        interfaces[T::iid] = iface;
    }
    template <typename T> T* query_interface()
    {
        auto it = interfaces.find(T::iid);
        if (it != interfaces.end())
        {
            return dynamic_cast<T*>(it->second);
        }
        return 0;
    }
private:
    std::map<int, i_interface*> interfaces;

ага, в pпринципе именно то, только не у geom, а у object.. 

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

Это сообщение отредактировал(а) mes - 15.11.2011, 18:16


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


Эксперт
****


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

Репутация: 8
Всего: 72



Вот рабочий пример по моей идее - ни одного dynamic_cast<>:
Код

#include <string>
#include <iostream>
#include <map>
using namespace std;
template<typename T>
  struct IControl {
    virtual T get() const = 0;
    virtual void set(T t) = 0;
  };
template<typename T>
  struct IRangeControl : IControl<T> {
    virtual T min() const = 0;
    virtual T max() const = 0;
  };

struct Object;

struct IController {
  static int getId(const string& s) { 
    if (ids.find(s)==ids.end()) { return reg(s, ++lastId); }
    return ids[s];
  }
  virtual IControl<bool> * getBoolControl(int id) { return 0; }
  virtual IRangeControl<int> * getIntControl(int id) { return 0; }
  virtual IRangeControl<double> * getDoubleControl(int id) { return 0; }
  virtual Object* create() = 0;
  virtual string name() const = 0;

  IControl<bool> * getBoolControl(const string& s) { return getBoolControl(getId(s)); }
  IRangeControl<int> * getIntControl(const string& s) { return getIntControl(getId(s)); }
  IRangeControl<double> * getDoubleControl(const string& s) { return getDoubleControl(getId(s)); }

protected:
  static int reg(const string& s, int id) { if (ids.find(s)==ids.end()) ids[s] = id; return id; }
  static map<string,int> ids;
  static int lastId;
};

map<string,int> IController::ids;
int IController::lastId = 0;

struct Object {
  virtual ~Object() {}
  virtual IController& getController() = 0;
};

struct Rect : Object {
  int x,y,w,h;

  enum { X=-1, Y=-2, W=-3, H=-4 };

  struct Control : IRangeControl<int> {
    int* p;
    virtual int get() const { return *p; }
    virtual void set(int v) { if (v >= min() && v <= max()) *p = v; }
    virtual int min() const { return 0; }
    virtual int max() const { return 1000; }
  };

  struct Controller : IController {
    Controller() { reg("x",X); reg("y",Y);  reg("w",W);  reg("h",H); }
    virtual Object* create() { Rect* r = new Rect; setRect(r); return r; }
    virtual string name() const { return "Rect"; }
    virtual IRangeControl<int> * getIntControl(int id) {
      switch(id) {
        case X: return &x;
        case Y: return &y;
        case W: return &w;
        case H: return &h;
      }
      return 0;
    }
    void setRect(Rect* r) { rect = r; x.p = &r->x; y.p = &r->y; w.p = &r->w; h.p = &r->h; }
    Rect* rect;
    Control x;
    Control y;
    Control w;
    Control h;
  };
  static Controller controller;

  virtual IController& getController() {
    controller.setRect(this);
    return controller;
  }
};
Rect::Controller Rect::controller;

struct RectF : Object {
  double x,y,w,h;

  enum { X=-1, Y=-2, W=-3, H=-4 };

  struct Control : IRangeControl<double> {
    double* p;
    virtual double get() const { return *p; }
    virtual void set(double v) { if (v >= min() && v <= max()) *p = v; }
    virtual double min() const { return 0; }
    virtual double max() const { return 1000; }
  };

  struct Controller : IController {
    Controller() { reg("x",X); reg("y",Y);  reg("w",W);  reg("h",H); }
    Object* create() { RectF* r = new RectF; setRect(r); return r; }
    virtual string name() const { return "RectF"; }
    virtual IRangeControl<double> * getDoubleControl(int id) {
      switch(id) {
        case X: return &x;
        case Y: return &y;
        case W: return &w;
        case H: return &h;
      }
      return 0;
    }
    // Можно добавить getIntControl(), который бы делал конвертацию типов
    void setRect(RectF* r) { rect = r; x.p = &r->x; y.p = &r->y; w.p = &r->w; h.p = &r->h; }
    RectF* rect;
    Control x;
    Control y;
    Control w;
    Control h;
  };
  static Controller controller;

  virtual IController& getController() {
    controller.setRect(this);
    return controller;
  }
};
RectF::Controller RectF::controller;

void setInts(Object&r) {
IController& c = r.getController();
c.getIntControl("x")->set(10);
c.getIntControl("y")->set(10);
c.getIntControl(Rect::W)->set(100);
c.getIntControl(Rect::H)->set(100);
}

void setDoubles(Object&r) {
IController& c = r.getController();
c.getDoubleControl("x")->set(10.);
c.getDoubleControl("y")->set(10.);
c.getDoubleControl(RectF::W)->set(100.);
c.getDoubleControl(RectF::H)->set(100.);
}

void printInts(Object&r) {
IController& c = r.getController();
cout << c.name() << endl;
cout << c.getIntControl("x")->get() << endl;
cout << c.getIntControl("y")->get() << endl;
cout << c.getIntControl("w")->get() << endl;
cout << c.getIntControl("h")->get() << endl;
}

void printDoubles(Object&r) {
IController& c = r.getController();
cout << c.name() << endl;
cout << c.getDoubleControl("x")->get() << endl;
cout << c.getDoubleControl("y")->get() << endl;
cout << c.getDoubleControl("w")->get() << endl;
cout << c.getDoubleControl("h")->get() << endl;
}

int main() {
Rect r; setInts(r);
printInts(r);
RectF rf; setDoubles(rf);
printDoubles(rf);
Object* o = rf.getController().create();
IController& c1 = r.getController();
IController& c = o->getController();
// Поскольку Controller - статический, так нельзя делать для копирования одинаковых типов
// Но это можно исправить.
c.getDoubleControl("x")->set(c1.getIntControl("x")->get());
c.getDoubleControl("y")->set(c1.getIntControl("y")->get());
c.getDoubleControl("w")->set(c1.getIntControl("w")->get());
c.getDoubleControl("h")->set(c1.getIntControl("h")->get());
printDoubles(*o);
return 0;
}


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


uploading...
****


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

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



Цитата(mes @  15.11.2011,  18:00 Найти цитируемый пост)
ага, в pпринципе именно то, только не у geom, а у object.. 

Не совсем понял о чем речь.

Цитата(mes @  15.11.2011,  18:00 Найти цитируемый пост)
ну вот есть у нас эти интерфейсы.. кто ими пользоваться будет ?

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

Цитата(mes @  15.11.2011,  18:00 Найти цитируемый пост)
если пользователь, то ему удобнее узнать фигура , текст, это ли что другое..
если это прослойка для комманд, то не вижу разделение на слои.. 

Тут тоже не совсем понял о чем речь.

Добавлено через 28 секунд
math64

спасибо, мне надо это переварить, понадобиться время smile 
PM   Вверх
mes
Дата 16.11.2011, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(azesmcar @  15.11.2011,  20:52 Найти цитируемый пост)
Тут тоже не совсем понял о чем речь.

немного размышлений о том , как я это представляю.. 
задачу можно разделить на несколько слоев, каждый из который соответсвует определенной концепции..  срез представляет "оголенные" интерфейсы.. в зависимости от того какие слои будут соприкасаться, зависит какими интерфейсы должен предоставлять слой... в некоторых случаях бывает нужным сделать прослойку/адаптер.. Зачастую чтоб не забивать голову, просто лепят мониолит..  К слоям относятся не только программные компоненты, но в том числе оборудование и юзер.. Так например например между консольной программой и юзером один тип среза, а между юзером и ГУИ совсем другой, поэтому отличается подход по формированию.. При Этом слои вполне могут располагаться как консолька<->Гуи<->Юзер.. Саму программу также можно условно разделить на слои : например  первый - предметная область, второй взаимодействие с базой,взаимодействие с юзером.. для того чтоб представить задачу нужно понять о каком слое идет речь, другими словами определить, что на входе, а что на выходе..

Добавлено @ 00:20
так например  если я описываю предметную область, то все эти moveable вообще не нужны, гораздо ближе "родные " названия самих типов..
если я хочу интерактивное взаимодействие, то я выбрал бы динамический интерфейс (в основе которого паттерн комманда) и по запросу о поддержке команд формировал бы  юзеру меню возможных вариантов... 
ну и дальше в таком же духе..

Добавлено через 10 минут и 52 секунды
применительно к вашей задаче :
есть набор фигур - предметная область , тут вроде все понятно.. но это одна часть
а вот вторая : есть какой то фреймворк, который что то там делает с набором фигур, и который еще кто-то будет использовать как то, по своему усмотрению.. 
но там имеются еще команды и интерпретатор.. вот так я вижу этот слой на основе ваших деталей smile Осмелюсь предположить, что и у других форумчан представление о нем не намного детализированней smile Поэтому приходится идтина ощупь smile

Добавлено через 11 минут и 39 секунд
Но задача вроде интересная smile будем надееться что не только из за покрывала таинственности smile


Это сообщение отредактировал(а) mes - 16.11.2011, 00:21


--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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