I was working on implementing an adapter design pattern to utilize the existing classes. My problem is, the classes works almost same, but have different names and less functionalities on another.
For example, each Work class and Homework class has one function that does the same, which is doWork() and doHomework().
I can link these to doThis() in Task interface. But, Work class doesn't have done() function while Homework class has it. How would I take care of this? Just no implementation? Are there any better approach?
class Task {
public:
virtual int doThis() = 0;
virtual bool done() = 0;
};
class Work {
public:
Work();
int doWork();
};
class Homework {
public:
Homework();
int doHomework();
bool done();
bool isDone;
};
class WorkAdapter : public Task, private Work {
public:
WorkAdapter();
int doThis() {
return doWork();
}
virtual bool done() {
// Is this okay not to implment this?
}
};
class HomeworkAdapter : public Task, private Homework {
public:
HomeworkAdapter();
int doThis() {
return doWork();
}
virtual bool done() {
return isDone;
}
};
int main() {
Task *homework = new HomeworkAdapter();
Task *work = new WorkAdapter();
homework->doThis();
bool isHomeworkDone = homework->done();
work->doThis();
bool isWorkDone = work->done(); // This would never be called in my implementation...
}
The adapter implementation using multiple inheritance (public for the target, private for the adaptee) is a valid approach.
Just take care of the the return type of the function:
class HomeworkAdapter : public Task, private Homework {
public:
HomeworkAdapter() {}
int doThis() override { // make sure you override target member
return doWork(); // and return value as expected
}
bool done() override {
return isDone;
}
};
Hint: virtual doesn't need to be specified in the derived class. Instead it's worth to use override, just to avoid subtle issues in case of non matching parameter or return types.
When no feature is available for taking care of done() in the adaptee, you must emulate it. So its's not just about changing the name, but also ensuring similar behaviour:
class WorkAdapter : public Task, private Work {
bool isdone; // functionality to add
public:
WorkAdapter() : isdone(false) {}
int doThis() override {
auto rc = doWork();
isdone = true; // once it's done, it's done ;-)
return rc;
}
bool done() override {
return isdone; // you must add this
}
};
Related
I need some help with inheritance and coding to interfaces in C++. I'm creating a state machine from which I'll derive another state machine. Therefore I have two interacting parts, a StateMachine and a State. The problem is that with this design, I cannot derive a specialised State from either the StateMachine or a DerivedStateMachine.
class StateMachine; //fwd
class State {
public:
virtual void action(StateMachine *engine) = 0;
virtual ~State() = default;
};
class StateMachine {
public:
StateMachine() = default;
explicit StateMachine(State &state) : state_(&state) {};
virtual void setState(State &state) {
state_ = &state;
}
[[nodiscard]] virtual State *getState() const {
return state_;
}
protected:
State *state_ = nullptr;
};
class DerivedStateMachine : public StateMachine {
public:
using StateMachine::StateMachine;
int doSpecializedThings(){
return special_thing_;
}
void setSpecialState(int specialState) {
special_thing_ = specialState;
}
private:
int special_thing_;
};
The issue with DerivedStateDependsOnGeneralStateMachine is that a StateMachine* doesn't have access to the doSpecializedThings() method.
class DerivedStateDependsOnGeneralStateMachine : public State {
virtual void action(StateMachine *engine) {
int important_value = engine->doSpecializedThings();
};
};
And the problem with DerivedStateDependsOnDerivedStateMachine is that you can't override a method with different arguments to the parent.
class DerivedStateDependsOnDerivedStateMachine : public State {
void action(DerivedStateMachine *engine) override {
engine->doSpecializedThings();
};
};
Can anybody see a way out of this knot I've tied myself in? Clearly I've messed up the design somewhere. What's 'normal' (for want of a better word) in such situations?
edits
To address the comments, firstly #Ted Lyngmo I am using the state machine design that I found in this post. It is odd that the mutual dependency is built into the design but its deliberate. The StateMachine needs to hold a reference to a State at all times and the State is responsible for determining the next state. The next state might depend on variables stored in the StateMachine so its useful to have a reference to the StateMachine in the State.
To get a little more concrete, I'm writing a Poker game. The idea is to have an abstract StateMachine interface from which I can derive a PokerEngine state machine, which conforms to the interface. I also thought I should have an abstract State, from which I can derive a PokerState. This would all work without the abstract level, and might initially be easier to think about, but its important for me to practice coding to interfaces to enable dependency injection and mocking. The irony is that in trying to do these things I've violated the Liskov substitution principle. Anyway, the PokerEngine will need to do things like getPotAmount which is a specialized method that I wouldn't want to any StateMachine.
I don't fully understand your design, but you can do what you need like this:
class StateMachine; //fwd
class State {
public:
virtual void action(StateMachine *engine) = 0;
virtual ~State() = default;
};
class StateMachine {
public:
StateMachine() = default;
explicit StateMachine(State &state) : state_(&state) {};
virtual void setState(State &state) {
state_ = &state;
}
virtual void setState(int state) {};
[[nodiscard]] virtual State *getState() const {
return state_;
}
virtual int doSpecializedThings(){
std::cout << "Do StateMachine things (or nothing)" << std::endl;
return 0;
}
protected:
State *state_ = nullptr;
};
class DerivedStateDependsOnGeneralStateMachine : public State {
public:
virtual void action(StateMachine *engine) {
int important_value = engine->doSpecializedThings();
};
};
class DerivedStateDependsOnDerivedStateMachine : public State {
public:
void action(StateMachine *engine) override {
engine->doSpecializedThings();
};
};
class DerivedStateMachine : public StateMachine {
public:
using StateMachine::StateMachine;
int doSpecializedThings(){
std::cout << "Do DerivedStateMachine things " << std::endl;
return special_thing_;
}
void setState(int specialState) {
special_thing_ = specialState;
}
private:
int special_thing_;
};
class AnotherDerivedStateMachine : public StateMachine {
public:
using StateMachine::StateMachine;
int doSpecializedThings(){
std::cout << "Do AnotherDerivedStateMachine things and" << std::endl;
std::cout << "\tcalling base class: ";
StateMachine::doSpecializedThings();
return special_thing_;
}
void setState(int specialState) {
special_thing_ = specialState;
}
private:
int special_thing_;
};
int main()
{
StateMachine sm;
DerivedStateMachine dsm;
AnotherDerivedStateMachine adsm;
DerivedStateDependsOnGeneralStateMachine dsmg;
DerivedStateDependsOnDerivedStateMachine dsmd;
sm.setState (dsmg);
StateMachine * pdsm = &dsm;
pdsm->setState (dsmd);
dsm.setState (1);
dsmg.action (&dsm);
dsmd.action (&dsm);
dsmg.action (&sm);
dsmd.action (&sm);
dsmd.action (&adsm);
return 0;
}
I don't understand why do you need the State in the StateMachine though, as you are calling StateMachine from State.
In the end I was able to access the variables and methods I needed by casting down from the abstract to derived type
I once implemented a state machine like this:
class Player
{
public:
int Run();
int Jump();
int Stop();
private:
class State
{
public:
virtual int Run() = 0;
virtual int Jump() = 0;
virtual int Stop() = 0;
};
class StandingState : public State
{
virtual int Run() { /*...*/ }
virtual int Jump() { /*...*/ }
virtual int Stop() { /*...*/ }
};
class RunningState : public State
{
virtual int Run() { /*...*/ }
virtual int Jump() { /*...*/ }
virtual int Stop() { /*...*/ }
};
// More states go here!
std::list<State*> states;
State* currentState;
};
int Player::Run()
{
int result = m_currentState->Run();
// do something with result
}
int Player::Jump()
{
int result = m_currentState->Jump();
// do something with result
}
int Player::Stop()
{
int result = m_currentState->Stop();
// do something with result
}
Fairly textbook I should think: Player delegates the calls from outside to its current State object, and does something with the result (possibly transitioning to another state). Essentially, each state knows how a given action affects it, but it's up to the state machine to wire the various states together. I found this to be a good separation of concerns.
But I'm seeing a possibility for abstraction here. The entire system is defined by the interface of the State class:
Both the state machine and the substates implement State
The state machine keeps a pointer to all possible States and the current State
Whatever method of State is called on the state machine, it is undiscerningly forwarded to the current state.
So, we can totally make this a class template, right? Look:
template< class StateInterface >
class StateMachine : public StateInterface
{
// public methods already declared in StateInterface
protected:
std::list<StateInterface*> states;
void AddState(StateInterface* state);
StateInterface* currentState;
};
class PlayerStateInterface
{
public:
virtual int Run() = 0;
virtual int Jump() = 0;
virtual int Stop() = 0;
};
class Player : public StateMachine< PlayerStateInterface >
{
public:
virtual int Run() { currentState->Run(); /* do stuff */ }
virtual int Jump() { currentState->Jump(); /* do stuff */ }
virtual int Stop() { currentState->Stop(); /* do stuff */ }
};
Of the above points, this has 1 and 2 covered, but what about 3? I still have to manually delegate the calls to the current state in the concrete state machine implementation. Is there a way to move that functionality to the StateMachine template? Can I somehow express that whenever a method of StateInterface is called on StateMachine it should call the same method on currentState, when I don't know the names or signatures of StateInterface's methods?
If you're looking for a general answer to the case where Run, Jump, and Stop have different signatures, I don't know if there's a good solution. However, in your example they all have the same signature, which suggests to me that the following approach might work:
#include <iostream>
class AbstractState
{
public:
virtual void write1() = 0;
virtual void write2() = 0;
};
class State1: public AbstractState
{
public:
virtual void write1() { std::cout << "1-1" << std::endl; }
virtual void write2() { std::cout << "1-2" << std::endl; }
};
class State2: public AbstractState
{
public:
virtual void write1() { std::cout << "2-1" << std::endl; }
virtual void write2() { std::cout << "2-2" << std::endl; }
};
template <typename StateInterface>
class Player
{
public:
Player(StateInterface *s_):
s(s_)
{
}
void setState(StateInterface *s_)
{
s = s_;
}
void execute(void (StateInterface::*method)())
{
(s->*method)();
}
private:
StateInterface *s;
};
int main()
{
State1 s1;
State2 s2;
Player<AbstractState> p(&s1);
p.execute(&AbstractState::write1);
p.execute(&AbstractState::write2);
p.setState(&s2);
p.execute(&AbstractState::write1);
p.execute(&AbstractState::write2);
return 0;
}
I was able to compile and run this with GCC 4.5.2 and got the expected result, namely:
1-1
1-2
2-1
2-2
As I said, I'm not sure that there's a good way to extend this to the case where the different member functions of AbstractState take different parameters or return different values, and there may be other drawbacks that I haven't considered yet. It isn't quite as nice as what I think you were hoping to find, but hopefully this will at least serve as a good starting point.
I like the idea of using interfaces to hide my implementation details. I also really enjoying using inheritance as a way to build upon my previously created classes. How can I get both of these benefits to coexist together? Here is an example of my problem:
object.h
class object {
protected:
//stuff that should be available to derived classes
virtual void derivedHelper () = 0;
public:
//stuff that should be available to the client
virtual object* create () = 0;
virtual void mainTask () = 0;
}
object.cpp
class objectPriv : public object {
private:
//implementation specific details and members
protected:
void derivedHelper () {
//some stuff
}
public:
objectPriv() { }
object* create () {
return(new objectPriv());
}
void mainTask () {
//more stuff
}
}
superObject.h
class superObject : public object { //problem #1
public:
//stuff that should be available to the client
virtual superObject* create () = 0;
}
superObject.cpp
class superObjectPriv : public superObject { //problem #2
private:
//the magic behind super object
public:
superObjectPriv() { }
superObject* create () {
return(new superObjectPriv());
}
void mainTask () {
object::mainTask(); //problem #3
object::derivedHelper(); //problem #4
//super extra stuff
}
}
So you can see here that this won't compile.
I could implement the pure virtuals of object for superObject, but that defeat the purpose of deriving from object. I don't want to duplicate the implementation, I want to build on it.
I could change superObject to derive from objectPriv, but then I would be exposing my implementation details. I want to hide everything specific about objectPriv from everybody.
I can't think of any way to achieve this. I have a bad feeling that it might not be possible, but I have my fingers crossed that you folks will have some clever trick for me :)
Thanks
Les
Have you considered the mixin pattern? It is a way to add shared implementation to multiple classes. One defines a template class which derives from it's argument. You could do that with the the common behavior of ObjectPriv and SuperObjectPriv:
template <typename ParentT>
class CommonFunctionalityMixin
: public ParentT // this is the magic line that makes it a mixin
{
public:
typedef ParentT parent_type;
virtual void mainTask() { /* implementation */ }
virtual void derivedHelper() { /* implementation */ }
};
class ObjectPriv
: public CommonFunctionalityMixin<object> // which derives from object
{
public:
typedef CommonFunctionalityMixin<object> parent_type;
virtual object* create() { return new ObjectPriv; }
// virtual void mainTask() defined in CommonFunctionalityMixin
// virtual void derivedHelper() defined in CommonFunctionalityMixin
};
class SuperObjectPriv
: public CommonFunctionalityMixin<superObject> // which derives from superObject
{
public:
typedef CommonFunctionalityMixin<object> parent_type;
virtual object* create() { return new SuperObjectPriv; }
// now we override CommonFunctionalityMixin's mainTask() with super's
virtual void mainTask()
{
parent_type::mainTask();
parent_type::derivedHelper();
}
};
I have a class which needs more callbacks..
I am trying to implement them with an interface:
class CallbacksInterface
{
public:
virtual bool mycallback1() = 0;
virtual bool mycallback2() = 0;
virtual bool mycallback3() = 0;
};
Class BusImplementation{
public:
addRequest(bool (CallbacksInterface::*callback)());
}
Callback is parameter for addRequest() method and is defined as pointer to interface method.
So I want to add request..
//class with callbacks
class Main:CallbacksInterface{
public:
bool mycallback1(){..};
bool mycallback2(){..};
bool mycallback3(){..};
//..
}
BusImplemantation bus;
Main main;
bus.addRequest(main.mycallback1);
bus.addRequest(main.mycallback2);
bus.addRequest(main.mycallback3);
But I cant pass a callback into my BusImplemantation class
error: argument of type 'bool (Main::)()' does not match 'bool (CallbacksInterface::*)()'
I think there is a solution with templates, but I am programming embedded devices and my compiler is limited.
A simpler approach would be to define a single interface type representing a function:
struct ICallback
{
virtual bool operator()() const = 0;
};
and implement it as many times as necessary:
struct Foo : ICallback
{
virtual bool operator()() const { return true;}
};
struct Bar : ICallback
{
virtual bool operator()() const { return false;}
};
then your bus implementation can take callback interfaces:
class BusImplemantation{
public:
void addRequest(const ICallback* callback) { .... }
};
then
BusImplemantation bus;
Foo foo; // can be called: bool b = foo();
Bar bar; // can be called: bool b = bar();
bus.addRequest(&foo);
bus.addRequest(&bar);
You could also investigate using std::function and avoiding the common interface altogether.
I also strongly suggest going with an abstract interface. However, if you really want the original approach for some reason, you need something like this:
void addRequest(bool (CallbacksInterface::*callback)(), CallbacksInterface* pTarget) {...}
...
bus.addRequest(&CallbacksInterface::mycallback1, &main);
// ! Not &Main::mycallback1 - that wouldn't compile
...
// calling a callback
(pTarget->*callback)();
I'm working on a plugin framework, which supports multiple variants of a base plugin class CPlugin : IPlugin. I am using a boost::shared_ptr<IPlugin> for all reference to the plugins, except when a subsystem needs the plugin type's specific interface. I also need the ability to clone a plugin into another seprate object. This must return a PluginPtr. This is why CPlugin is a template rather than a straight class. CPlugin::Clone() is where the template paramter is used. The following are the class definitions I am using:
IPlugin.h
#include "PluginMgr.h"
class IPlugin;
typedef boost::shared_ptr<IPlugin> PluginPtr;
class IPlugin
{
public:
virtual PluginPtr Clone() =0;
virtual TYPE Type() const =0;
virtual CStdString Uuid() const =0;
virtual CStdString Parent() const =0;
virtual CStdString Name() const =0;
virtual bool Disabled() const =0;
private:
friend class CPluginMgr;
virtual void Enable() =0;
virtual void Disable() =0;
};
CPlugin.h
#include "IPlugin.h"
template<typename Derived>
class CPlugin : public IPlugin
{
public:
CPlugin(const PluginProps &props);
CPlugin(const CPlugin&);
virtual ~CPlugin();
PluginPtr Clone();
TYPE Type() const { return m_type; }
CStdString Uuid() const { return m_uuid; }
CStdString Parent() const { return m_guid_parent; }
CStdString Name() const { return m_strName; }
bool Disabled() const { return m_disabled; }
private:
void Enable() { m_disabled = false; }
void Disable() { m_disabled = true; }
TYPE m_type;
CStdString m_uuid;
CStdString m_uuid_parent;
bool m_disabled;
};
template<typename Derived>
PluginPtr CPlugin<Derived>::Clone()
{
PluginPtr plugin(new Derived(dynamic_cast<Derived&>(*this)));
return plugin;
}
An example concrete class CAudioDSP.h
#include "Plugin.h"
class CAudioDSP : CPlugin<CAudioDSP>
{
CAudioDSP(const PluginProps &props);
bool DoSomethingTypeSpecific();
<..snip..>
};
My problem (finally) is that CPluginMgr needs to update m_disabled of the concrete class, however as it is passed a PluginPtr it has no way to determine the type and behave differently according to the template paramater. I can't see how to avoid declaring ::Enable() and ::Disable() as private members of IPlugin instead but this instantly means that every section of the application now needs to know about the CPluginMgr class, as it is declared as a friend in the header. Circular dependancy hell ensues. I see another option, declare the Enable/Disable functions as private members of CPlugin and use boost::dynamic_pointer_cast<CVariantName> instead.
void CPluginMgr::EnablePlugin(PluginPtr plugin)
{
if(plugin->Type == PLUGIN_DSPAUDIO)
{
boost::shared_ptr<CAudioDSP> dsp = boost::dynamic_pointer_cast<CAudioDSP>(plugin);
dsp->Enable();
}
}
This however leads to lots of duplicate code with many multiple variants of the base CPlugin template. If anyone has a better suggestion please share it!
You can easily write :
class CPluginMgr;
class IPlugIn ..
{
friend CPluginMgr;
...
};
Only a predefinition is needed for friend.
I think your get in trouble trying to return a shared_ptr in clone method. Why don't you make use of covariant return types? What you are doing is a common idiom called Virtual Constructor.
class IPlugin
{
public:
virtual IPlugin* clone() = 0;
// ...
}
class CPluginMgr;
class CPlugin : public IPlugin
{
public:
virtual CPlugin* clone() = 0;
friend CPluginMgr; // as #Christopher pointed out
void Enable(bool enable) { m_disabled = !enable; }
// ...
}
class CAudioDSP : public CPlugin
{
public:
virtual CAudioDSP* clone();
// ...
}
CAudioDSP* CAudioDSP::clone()
{
return new CAudioDSP(*this); // assume copy constructors are properly implemented
}
Returning a shared_ptr may lead you to make errors (as early destruction of temparary objects) and I think is not usually a good idea.