I'm currently refactoring a class that looks (after some refactoring and very much simplified) somewhat like this:
class Foo
{
public:
Foo(bool someFlag) : m_flag(someFlag) { };
void doThings();
void doOtherThings()
{
doPrivateThings();
if (m_flag)
doFlagThings();
else
doNoFlagThings();
}
private:
void doPrivateThings();
void doFlagThings();
void doNoFlagThings();
bool m_flag;
}
Notes:
* m_flag
being there is the result of the refactoring (which is by far not done) - initially each function individually branched (if (check_something())
) on something that for which the result was already determined/fixed during construction of the object.
* The functions doFlagThings()
and doNoFlagThings()
are rather small (~3-5 lines of code) and there are at most 3-4 functions that deviate depending of m_flag
.
So, the next step is to get rid of the someFlag
- the only question is how.
One way would be to use an abstract parent and inheritance:
class FooBase
{
public:
FooBase();
void doThings();
void doOtherThings()
{
doPrivateThings();
doSpecializedThings();
}
private:
void doPrivateThings();
virtual void doSpecializedThings() = 0;
}
class FlagFoo : public FooBase
{
public:
FlagFoo();
private:
void doSpecializedThings() override { ... };
}
class NoFlagFoo : public FooBase
{
public:
NoFlagFoo();
private:
void doSpecializedThings() override { ... };
}
The other way would be to use the Strategy pattern and composition, i.e.
class Foo
{
public:
Foo(IDoThingsStrategystrategy strategy) : m_Strategy(strategy) { };
void doThings();
void doOtherThings()
{
doPrivateThings();
m_Strategy.doSpecializedThings();
}
private:
void doPrivateThings();
IDoThingsStrategy m_Strategy;
}
class IDoThingsStrategy
{
public:
IDoThingsStrategy();
virtual void doSpecializedThings() = 0;
}
class DoThingsFlagStrategy : public IDoThingsStrategy
{
public:
DoThingsFlagStrategy();
void doSpecializedThings() override;
}
class DoThingsNoFlagStrategy : public IDoThingsStrategy
{
public:
DoThingsNoFlagStrategy();
void doSpecializedThings() override;
}
But that seems very much like overkill, and presents the problem that the creator of Foo
now needs to be aware of the different Strategies in order to create them and feed them to Foo
.
So the question is: Should I go with the Inheritance (even though one should prefer composition over inheritance) or the Strategy pattern or is there a better way I'm just not seeing right now?