3

I'd like to configure the behaviour of objects at runtime by choosing a method to call out of a given set. Consider this simple example:

class Parameter;

class Conf;

class Obj {
public:
    Obj( const Conf &t ): t_( t ) {}
    void f( Parameter *d );
    void f1( Parameter *d );
    void f2( Parameter *d );
    typedef void ( Obj::*Fn )( Parameter *d );
private:
    const Conf &t_;
};

class Conf {
public:
    Obj::Fn f;
};

void Obj::f( Parameter *d ) {
    ( this->*t_.f )( d );
}

By changing Conf::f for a given Conf object, the behaviour of all Obj objects configured with this is changed.

First question: Does this resemble some design pattern (ok, it's kind of a method-pointer-strategy-thing...)? If so, should I consider a redesign?

Second question: I'd like to make this more flexible by using different parameter classes. I've already done this by making Parameter a base class and doing type casting in the fN methods, but that does not look like a final solution. Any suggestions?

mkluwe
  • 3,823
  • 2
  • 28
  • 45

1 Answers1

0

This reminds me of the State pattern, considering when the state changes, a method will be called on a different object. If you look at the Java example of the wikipedia link, the StateContext object has the myState attribute which will be changed to a different State object for state changes.

You could do something similar, whereby your Obj class would have a pointer/reference to an object that implements a method specified in the interface that it implements. Then the internal pointer/reference could be changed to point to a different object, either by internal logic or by setting it externally, and then the method being called will be different.

Here is a brief example:

class Action
{
    virtual void action() = 0;
}

class Action1 : public Action
{
    virtual void action() { /* do something useful here */ }
};

class Action2 : public Action
{
    virtual void action() { /* do something different here */ }
}

class Obj
{
public:
    setAction(Action *a) {a_ = a;}
    void action() {if(a_) a_->action();}
private:
    Action *a_;
};

{
    Action1 a1;
    Action2 a2;
    Obj o;
    o.setAction(&a1);
    o.action();

    o.setAction(&a2);
    o.action();
}

As mentioned in the comments, this is also very similar to the Strategy pattern.

Brady
  • 10,207
  • 2
  • 20
  • 59
  • Does this have any advantage over passing a function object (with overloaded operator() ) as a template parameter? – nurettin May 17 '13 at 12:46
  • @nurettin, good question, I guess it boils down to the difference/preference between templates and inheritance, which is beyond the scope of this question. – Brady May 17 '13 at 13:29
  • As I said in a comment to the question, the actions should be able to modify the internal state of the object (as methods can do). You can't really do that in `/* do something useful here */`. – mkluwe May 17 '13 at 14:23