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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> есть ли библиотечный шаблон, облегчающий реализацию Декоратора 
:(
    Опции темы
Alek86
Дата 10.11.2007, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 21
Всего: 25



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

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

Это сообщение отредактировал(а) Alek86 - 10.11.2007, 23:49


--------------------
user posted image    user posted image
PM MAIL   Вверх
Fazil6
Дата 11.11.2007, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 35
Всего: 60



Цитата(Alek86 @  10.11.2007,  23:41 Найти цитируемый пост)
если кто использовал Декоратор, то, наверное, согласится, что делегировать все функции интерфейса иногда бывает довольно утомительно. и, по сути, это копипаст. при том, что обычно меняется только одна-две функции

вот тут довольно толково про декоратор

http://www.insidecpp.ru/patterns/decorator/

думаю, что твои проблемы как раз о томже
PM MAIL   Вверх
Alek86
Дата 11.11.2007, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 21
Всего: 25



вах, какой гон на декоратор...

кстати, тот декоратор, что я знаю, реализуется путем агрегации и ни в коем случае не наследования. и ВСЕ проблемы, что там описаны там просто не существуют. кроме одной:
Цитата

В третьих, если вы будете замещать какую-то функциональность, то вам придется полностью сохранить имена и интерфейс замещаемых функций.

дело в том, что в той реализации паттерна, что я знаю для его реализации НЕОБХОДИМО иметь интерфейс

такое ощущение, что автор того гона просто не читал Design Patterns smile


--------------------
user posted image    user posted image
PM MAIL   Вверх
Fazil6
Дата 11.11.2007, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 35
Всего: 60



Цитата(Alek86 @  11.11.2007,  10:33 Найти цитируемый пост)
кстати, тот декоратор, что я знаю, реализуется путем агрегации и ни в коем случае не наследования. и ВСЕ проблемы, что там описаны там просто не существуют. кроме одной:

что ж это за декоратор такой? Смысл декоратора в использовании его через интерфейс базового. Агрегация там есть, но и открытое наследование тоже должно быть
Цитата(Alek86 @  11.11.2007,  10:33 Найти цитируемый пост)
такое ощущение, что автор того гона просто не читал Design Patterns

скорее ты не читал. Твоё описание скорее похоже на Proxy
PM MAIL   Вверх
Alek86
Дата 11.11.2007, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 21
Всего: 25



[B]
Цитата(Fazil6 @  11.11.2007,  12:08 Найти цитируемый пост)
но и открытое наследование тоже должно быть


да, должно. от интерфейса. а декорируемый класс является полем, потому второй проблемы нет.
я привык к такой схеме:

Код

class IC {};                   // интерфейс
class C1 : public IC {}; // реализация1
class C2 : public IC {    // реализация2 (с помощью декоратора)
public:
    /*делегирование + реализация того, что нужно поменять*/
private:
    IC* m_pC; /* = new C1*/
};


изменение интерфейса, конечно, скажется на обоих классах, но именно эту проблему я и хочу свести к минимуму. ведь очевидно, что при добавлении новой фукнции C2 должен просто делегировать реализацию от m_pC, при удалении фукнции C2 это должно волновать ТОЛЬКО если он в ней что-то менял по сравнению с m_pC, то же и при изменении имени+параметров функции.

Добавлено @ 12:30

тут был бред, удалил

Это сообщение отредактировал(а) Alek86 - 11.11.2007, 12:41


--------------------
user posted image    user posted image
PM MAIL   Вверх
Fazil6
Дата 11.11.2007, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 35
Всего: 60



Цитата(Alek86 @  11.11.2007,  12:29 Найти цитируемый пост)
изменение интерфейса, конечно, скажется на обоих классах, но именно эту проблему я и хочу свести к минимуму. ведь очевидно, что при добавлении новой фукнции C2 должен просто делегировать реализацию от m_pC, при удалении фукнции C2 это должно волновать ТОЛЬКО если он в ней что-то менял по сравнению с m_pC, то же и при изменении имени+параметров функции.

если я правильно все понял, то именно это и есть главный недостаток Decoratora, который ты хочешь обойти, но обойти его неполучится, ибо Decorator ОБЯЗАН реализовывать весь интерфейс (что собственно и является минусом). Можно конечно наследовать класс декоратора от class C2 , а не от базового, но тогда смысл декоратора пропадает т.к. его предназначение избавиться от большого количества подклассов (к чему приведет такое наследование), и использовать этого декоратора для добавления функциональности к ЛЮБОМУ классу иерархии.
Кстати 
Код

IC* m_pC; /* = new C1*/

если я тут правильно понимаю твою мысль, то она тоже неверна. Этот указатель не создается внутри декоратора, а должен передаваться декоратору в конструкторе и сам декоратор не обязан знать кто это на самом деле.

Это сообщение отредактировал(а) Fazil6 - 11.11.2007, 13:37
PM MAIL   Вверх
Alek86
Дата 11.11.2007, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 21
Всего: 25



Цитата(Fazil6 @  11.11.2007,  13:17 Найти цитируемый пост)
если я тут правильно понимаю твою мысль, то она тоже неверна. Этот указатель не создается внутри декоратора, а должен передаваться декоратору в конструкторе и сам декоратор не обязан знать кто это на самом деле.

да, тут я, похоже, лажанул smile



Цитата(Fazil6 @  11.11.2007,  13:17 Найти цитируемый пост)
главный недостаток Decoratora, который ты хочешь обойти, но обойти его неполучится


а вот так?
Код

#include <iostream>
#include <boost/shared_ptr.hpp>
using std::cout;
using std::endl;
// интерфейс
class IC {
public:
    virtual ~IC()                        = 0{}
    virtual int f1()                    = 0;
    virtual int f2()                    = 0;
};
// реализация декоратора для данного интерфейса
class CDecorator : public IC {
public:
    CDecorator(boost::shared_ptr<IC> vC)   {m_C = vC;}
    virtual ~CDecorator()           {}
    virtual int f1()                {return m_C->f1();}
    virtual int f2()                {return m_C->f2();}
private:
    boost::shared_ptr<IC> m_C;
};
// просто реализация интерфейса
class C1 : public IC {
public:
    virtual ~C1() {};
    virtual int f1() {return 1;}
    virtual int f2() {return 2;}
};
// 2 "декорируюшие" реализации интерфейса
class C2 : public CDecorator {
public:
    C2(boost::shared_ptr<IC> vC) : CDecorator(vC) {}
    virtual int f2() {return CDecorator::f2() + 10;}
};
class C3 : public CDecorator {
public:
    C3(boost::shared_ptr<IC> vC) : CDecorator(vC) {}
    virtual int f1() {return CDecorator::f1() - 10;}
};

int main() {
    // первый тип - не декорируемый
    boost::shared_ptr<IC> c1(new C1());
    cout << "c1->f1():" << c1->f1() << endl;
    cout << "c1->f2():" << c1->f2() << endl;
    // второй - декорируемый первый
    boost::shared_ptr<IC> c2(new C2(c1));
    cout << "c2->f1():" << c2->f1() << endl;
    cout << "c2->f2():" << c2->f2() << endl;
    // третий - декорируемый второй - для проверки
    boost::shared_ptr<IC> c3(new C3(c2));
    cout << "c3->f1():" << c3->f1() << endl;
    cout << "c3->f2():" << c3->f2() << endl;
    system("pause");
}


конечно, не фонтан решение, но, может, возможно его улучшить (с помощью каких-то возможностей метапрограммирования, я не знаю). главное, что сколько не создавай декораторов, при изменении интерфейса вносить изменений нужно не так много.


--------------------
user posted image    user posted image
PM MAIL   Вверх
Fazil6
Дата 11.11.2007, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 35
Всего: 60



Цитата(Alek86 @  11.11.2007,  13:48 Найти цитируемый пост)
а вот так?

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

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1484 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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