The OutputPolicy of my class sometimes goes to a static/singleton object and sometime goes to a 1-to-1 object.
Not sure if I can explain in english.. so here is the desired behavior in pseudo code:
template<
class Algo,
template<class> OutputPolicy
>
class AlgoBase : Algo, OutputPolicy<Algo>
{
};
class AlgoImp
{
public:
AlgoImp(string topic) {}
void OnData(
{
cout << " AlgoImp::OnData";
if ( .... )
NewMsg(msg);
}
};
class AlgoImp2
{
public:
AlgoImp2(string topic) {}
void OnData(
{
cout << " AlgoImp2::OnData";
if ( .... )
NewMsg(msg);
}
};
AlgoImp::OnData, does some processing and calls NewMsg. I am trying to decouple the implimentation of the NewMsg() call.
template < class T>
class OutMessageQueueTcp
{
void NewMsg(string in)
{
//Should be a signgleton or static
cout << " OutMessageQueueTcp::NewMsg";
}
};
If OutputPolicy is OutMessageQueueTcp (above) then there should only be one instance of OutputPolicy. So I would either have to derive from a Singleton or use a static variable somewhere.
template <class T>
class OutMessageAsInput : AlgoBase<AlgoImp2, OutMessageQueueTcp>
{
void NewMsg(string in)
{
cout << " OutMessageAsInput::OnData";
AlgoBase<AlgoImp2, OutMessageQueueTcp>::NewMsg(in);
}
};
If OutputPolicy is OutMessageAsInput (above) then the out becomes input to a sister object and then will be sent to OutMessageQueueTcp.
Here is the main.
main
{
AlgoBase<AlgoImp, OutMessageAsInput> myalgo1;
myalgo1.OnData("hi");
}
And my desired output:
AlgoImp::OnData
OutMessageAsInput::NewMsg
AlgoImp2::OnData
OutMessageQueueTcp::NewMsg
What I really have is a collection of AlgoImp objects, each with its own topic and data. AlgoImp will generate outout by calling NewMsg. Sometimes these messages should be sent to a Socket, and sometimes they should be processed by AlgoImp2.
This decision will happen at compile time. There will be many Algo's each doing diff things. Seems like I am trying to do some kind of Aspect oriented stuff.
Question:
Is it possible to have a Base class be either a singleton or a normal object by making it a policy? Is there a design pattern for something like this? Maybe some kind of factory?
Thanks for the help.
To keep things simple - OutputPolicy
at your algo classes level should be a simple class with simple method. Of course you can implement it with singleton or static methods from the real implementation class:
template < class T>
class OutMessageQueueTcp
{
public:
void NewMsg(string in)
{
impl.NewMsg(in);
}
private:
static OutMessageQueueTcpImpl<T> impl;
};
Or:
template < class T>
class OutMessageQueueTcp
{
public:
void NewMsg(string in)
{
OutMessageQueueTcpImpl<T>::NewMsg(in);
}
};
For your Algo*
classes: if output policy is given at compile time - make all these classes template clasess, and treat OutputPolicy as a Strategy
- keeo it aggregated (as member variable) in your algo classes:
template <template <typename> class OutputPolicy>
class AlgoImp
{
public:
AlgoImp(string topic) {}
void OnData(
{
cout << " AlgoImp::OnData";
if ( .... )
outputPolicy.NewMsg(msg);
}
private:
OutputPolicy<AlgoImp> outputPolicy;
};