I am having trouble in finding simple and elegant design for the following scenario. Class Worker
uses template class Helper
to do some work. In the simple scenario it looks like this:
template<typename T>
class Helper {
public:
void Help(T data) : m_data(data) {} //NOTICE: Copy
T const& Data() const { return m_data; }
T m_data;
}
class SimpleWorker {
public:
SimpleWorker() : m_helper(SimpleData()) {} // non-temp used in reality
void DoWork()
{
m_helper.help();
}
Helper<SimpleData> m_helper;
}
Things get complicated for me when the template argument is more complex and is of the same business domain of the worker. The worker needs to use the helper but it would also need to call some methods on the data object that the helper doesn't even know about (in this design). Something like:
template<typename T>
class Helper {
public:
Helper(T data) : m_data(data) {} //NOTICE: Copy
T const& Data() const { return m_data; }
T m_data;
}
class ComplexWorker {
public:
ComplexWorker() : m_helper(ComplexData()) {} // non-temp used in reality
void DoWork()
{
m_helper.help();
m_helper.GetData().DoSomethingComplexNotConst(); // <-------------
}
Helper<ComplexData> m_helper;
}
The obvious problem is that I can't call not const function on Data()
result. Making Data()
non-const seems like a bad idea as Helper
is used in different contexts as well. My goal is to find an elegant way to alter ComplexData
using its member functions from ComplexWorker
The ComplexData
needs to be altered in the first place so that Helper
can continue working with the altered data.
EDIT: Changed Helper
construction to copy the provided data to better resemble actual flow
I think it's best to let
Helper
have only static functions, not maintaing state (as you create temporaryComplexData()
inComplexWorker
in your own code). Pass the data by reference or const-reference depending on whether you need to modify or not.Note that I made a template specialization for the
ComplexData
. There is some code duplication inhelp()
but you can easily extract this into a common non-member helper function.Why not refer to the realization of the Container part in STL. An overload of the Data() function may achieve a ballance between safty and elegance.
Seems to me that it depends on what
Helper
is actually doing. Your example just gives a constructor and an accessor but I doubt that is all it does in practice.Have you considered simply using inheritance? Your
Helper
template would then look like this:In this case you could use the
Helper<ComplexData>
object directly in an 'is-a' relationship: