Задать вопрос

Паттерн Стратегия

Есть небольшой вопрос по данному шаблону. Прочитал статью habrahabr.ru/blogs/programming/132929/ Вроде даже понял, что к чему. Пытаюсь реализовать, но не получается. Дело в том, что в примерах просто вызывается метод из другого класса, который выводит текстовую строку. В моем случае, требуется, чтобы вызванный метод изменял параметры объекта главного класса. То есть вот так:

class changeValue
{
public:
    changeValue();
    ~changeValue();
    virtual void Change() = 0;
};

changeValue::changeValue() {}
changeValue::~changeValue() {}

class General
{
public:
    General();
    ~General();
    float a;
    void changeit();
    changeValue *object;
};

General::General() {a=0;}
General::~General() {}
void General::changeit()
{
    object->Change();
}

class changeValueTo1 : public changeValue
{
    changeValueTo1();
    ~changeValueTo1();
    void Change();
};

changeValueTo1::changeValueTo1() {}
changeValueTo1::~changeValueTo1() {}
void changeValueTo1::Change()
{
    //должен изменить значение параметра a объекта класса MyClass на 1
}

class MyClass : public General
{
    MyClass();
    ~MyClass();
};

MyClass::MyClass() {
   object = new changeValueTo1;
}

MyClass::~MyClass() {
   delete object;
}

Как реализовать метод void changeValueTo1::Change() так, чтобы он имел доступ к параметрам класса MyClass?
  • Вопрос задан
  • 6656 просмотров
Подписаться 3 Оценить Комментировать
Решения вопроса 1
@rtorsten
Как реализовать метод void changeValueTo1::Change() так, чтобы он имел доступ к параметрам класса MyClass?

Наиболее простой способ, как уже и сказали сделать перекрестную ссылку/указатель.
class changeValueTo1 : public changeValue
{
public:
    changeValueTo1(General * p) : _parent(p) {}
    ~changeValueTo1() {}
    void Change();

private:
    General * _parent;
};

void changeValueTo1::Change()
{
    //должен изменить значение параметра a объекта класса MyClass на 1
    _parent->a = 5;
}

MyClass::MyClass() {
   object = new changeValueTo1(this);
}


В данном случае это параметр класса General, а не MyClass как ты указал в комментарии. Если нужно именно MyClass то необходимо в changeValueTo1 изменить тип указателя.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
taliban
@taliban
php программист
Перекрестная ссылка Вам нужна, хотя это не лучший вариант, часто причина утечек, а обязательна ли стратегия? Вообще лично я стараюсь придерживаться правила: «проще писать проще, потом и поддерживать будет проще и дописывать будет проще».
Ответ написан
retran
@retran
Если у вас возникла необходимость из стратегии как-то модифицировать контекст — то скорее всего вы неправильно произвели декомпозицию классов и скорее всего нарушили Single Responsibility Principle.

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

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

Войдите, чтобы написать ответ

Похожие вопросы