LINUX.ORG.RU

Proxy шаблон проектирования

 


0

4

Пример прокси объекта с википедии

class MathProxy : public IMath
{
public:
    MathProxy()
    {
        math = new Math();
    }
    virtual ~MathProxy()
    {
        delete math;
    }
    virtual double add(double x, double y) 
    {
        return math->add(x, y);
    }
    
    virtual double sub(double x, double y) 
    {
        return math->sub(x, y);
    }
    
    virtual double mul(double x, double y) 
    {
        return math->mul(x, y);
    }
    
    virtual double div(double x, double y) 
    {
        return math->div(x, y);
    }
    
private:
    IMath *math;
};


Есть возможность не делать реализации add, mul, div, sub функций, а сразу их перенаправлять в Math class?
для этих целей подошла бы перегрузка operator->, но требуется перед каждым вызовом функции вставить код. Код один и тот же для всех функций.


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

Deleted
()
Ответ на: комментарий от fluorite

Данный код можно реализовать просто Math* operator->() {return &math}

вопрос: можно ли вставить свой кастомный код(один и тот же) для проксирующего вызова всех функций math

kasha
() автор топика
Ответ на: комментарий от kasha

если исключение в методе мне нужно его перехватить и вызвать метод заново. и вернуть результат метода. +учесть что некоторые методы возвращают войд

kasha
() автор топика
Ответ на: комментарий от kasha
class IMath
{
    virtual double add(double x, double y) = 0; 
    virtual double sub(double x, double y) = 0; 
    virtual double mul(double x, double y) = 0;
    virtual double div(double x, double y) = 0;
};

class Math : public IMath
{
    virtual ~Math() {};
    virtual double add(double x, double y) { return x+y; } 
    virtual double sub(double x, double y) { return x-y; } 
    virtual double mul(double x, double y) { return x*y; }
    virtual double div(double x, double y) { return x/y; }
};

class MathProxy : public Math
{
    // Here you can override add,sub,mul,div, but have not.
};
fluorite ★★★★★
()
Ответ на: комментарий от fluorite

Но это уже не прокся, а наследование 8)

Deleted
()
Ответ на: комментарий от fluorite

мне нужно добавить один и тот же код для этих 4 методов. представь себе что таких методов 5 десятков. мне в MatchProxy все эти 50 методов переопределять?

kasha
() автор топика

пофиг это прокси или нет, нужно любым способом добиться нужного поведения

kasha
() автор топика
Ответ на: комментарий от kasha

В дочернем классе при вызове извне доступны все public методы родителя.

fluorite ★★★★★
()
Ответ на: комментарий от kasha

вопрос: можно ли вставить свой кастомный код(один и тот же) для проксирующего вызова всех функций math

Да вы бы хоть пример того кода, что вам нужно, показали бы. А то все может свестись к банальщине вроде:

template<typename T, typename A>
class proxy {
  T obj_;
  A action_;
public :
  T & operator->() {
    action_();
    return obj_;
  }
};

class some_action {
public :
  void operator() { kill_a_cat(); }
};

proxy<Math, some_action> p;
p->add(x, y);
p->sub(x, y);

eao197 ★★★★★
()

Суть примера на википедии абсолютно неправильная и не описывает шаблон прокси. Правильно так:

class MathProxy : public IMath
{
public:
    MathProxy()
    {
        math = otherlib::CreateMath();
    }
    virtual ~MathProxy()
    {
        delete math;
    }
    virtual double add(double x, double y) 
    {
        return math->add(x, y);
    }
    
    virtual double sub(double x, double y) 
    {
        return math->sub(x, y);
    }
    
    virtual double mul(double x, double y) 
    {
        return math->mul(x, y);
    }
    
    virtual double div(double x, double y) 
    {
        return math->div(x, y);
    }
    
private:
    otherlib::OtherIMath *math;
};
vzzo ★★★
()
Ответ на: комментарий от eao197

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

kasha
() автор топика
Ответ на: комментарий от kasha

Тогда, боюсь, без макросов не обойтись. Если есть возможность использовать C++11 (а лучше С++14), то дело упрощается за счет variadic templates. Что-то вроде:

#define PROXY_METHOD(method) \
template<typename... Args> \
auto method(Args && ...args) { \
  try { return obj_.method(std::forward<Args>(args)...); } \
  catch(const your_exception &) { \
    return obj_.method(std::forward<Args>(args)...); \
  } \
}

class math_proxy {
  Math obj_;
public :
  PROXY_METHOD(add)
  PROXY_METHOD(sub)
  PROXY_METHOD(mul)
  ...
};

Ну и да, если в вашем классе 50 методов, то придется делать proxy с 50-ю методами.

eao197 ★★★★★
()
Ответ на: комментарий от rumgot

Прокси объект может скрывать за собой, скажем, rpc. Или обеспечивать какие-то дополнительные, но необязательные, функции, скажем кеширование, журналирование, и т.п.

iliyap ★★★★★
()
Ответ на: комментарий от iliyap

мля, вот я лошара. я всегда из обёртками называл. Как раз с rpc и кешированием

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.