Using the strategy pattern if the concrete strategy depends on the concrete parameter type - c++

I'm currently working with a System/Data hierarchy implemented like this:
class SystemData
{
}
class SystemDataA : public SystemData
{
int x;
}
class SystemDataB : public SystemData
{
float y;
}
class System
{
virtual SystemData* getData() = 0;
virtual Result computeData(SystemData*) = 0;
}
class SystemA : public System
{
// really returns SystemDataA
SystemData* getData() override;
Result computeData(SystemData*) override;
}
class SystemB : public System
{
// really returns SystemDataB
SystemData* getData() override;
Result computeData(SystemData*) override;
}
In the end there is a controller class which does sth similar to this:
void foo()
{
for(auto& s : systemVec)
{
SystemData* data = s->getData();
FinalResult final = s->computeData(data);
}
}
Whereas now each specific system dynamic_casts back to the concrete type it is able to process. This seems like pretty bad design and I'd like to refactor this into sth more reasonable. My first idea was to just implement the computation algorithm inside the SystemData classes and then just do:
SystemData* data = s->getData();
FinalResult final = data->compute();
but does it really belong there?
It appears more intuitive to have a separate algorithm hierarchy, probably implemented with the strategy pattern. However then I again have the problem of losing runtime type info of the data because all algorithms get passed the abstract data type and in the end will have to dynamic cast and do nullptr and error checks again. So is it still better to implement the algorithm inside the data classes itself? Can I maybe still implement the hierarchy in a separate module and just add function pointers or a similar construct to the data class? Is there a completely different solution I'm not aware of?

Related

Clever way to clean dirty flag in c++

I have this case where I am trying to expose a standard API for spatial search structures, where the input data for the various method of building the structure is the same, but the way the search structure is built is different.
I have setters for the data on the base class and a pure virtual Build() method that the derived classes need to implement to construct the search structure.
Below is sort of how my base class looks like
class SpatialSearch
{
public:
void SetData(Data data_)
{
this->data = data_;
this->dirty = true;
}
virtual void Build() = 0;
int search(Vec3 point)
{
if(dirty)
Build();
// Code to perform a search. I won't get into the
// nitty gritty of this, but this exists as a commom
// implementation on the base class for all the spatial
// search structures.
}
private :
Data data;
bool dirty;
}
So if you notice, every call to search has a check for the dirty flag.
And if the data has been changed after the last time, I rebuild the structure.
However, the Build method is implemented on the derived class, and I need a way to enforce a means of setting this flag to false after the Build method has been execute, and not just leave a guideline for the person writing the derived class to have dirty = false in their 'Build' method.
In short, I need a way to make sure the user has set dirty = false after every execution of the Build method.
A common way to do this is to have a vertical interface and a horizontal one (protected & public).
The "horizontal interface" is the one the users of the class see and the "vertical" one is the one that the derived class implementers override to add functionality.
class SpatialSearch
{
public:
void SetData(Data data_)
{
this->data = data_;
this->dirty = true;
}
void Build() // no longer virtual
{
internal_build();
dirty = false;
}
int search(Vec3 point)
{
if(dirty)
internal_build();
// Code to perform a search. I won't get into the
// nitty gritty of this, but this exists as a commom
// implementation on the base class for all the spatial
// search structures.
}
protected:
virtual void internal_build() = 0; // implementers override this
private :
Data data;
bool dirty;
}
class SpecialSpatialSearch
: public SpatialSearch
{
protected:
void internal_build() override
{
// do the build without caring or knowing of the
// existence of the dirty flag
}
};

Modifying class behavior depending on property using if() is code smell or not?

I have a class representing some parameter. The parameter can be number, array, enum or bitfield - this is the param type. The behavior is slightly different between these types, so they are subclasses of paramBase class. The parameter can be stored in RAM or be static (i.e. hardcoded in some way, currently saved in a file).
void read() implemented in paramBase and uses template method pattern to implement reading for any param type, but this works only for RAM storage. If parameter is static then read() must be completely different (i.e. read from file).
A straightforward solution can be further subclassing like paramArrayStatic, paramNumberStatic, etc. (it will be 8 subclasses).
The difference between paramArray and paramArrayStatic is basically only in the read() method, so a straightforward solution will lead to code duplication.
Also I can add if( m_storage==static ) to read() method and modify behavior, but this is also code smell(AFIK).
class paramBase
{
public:
virtual paramType_t type() = 0;
paramStorage_t storage();
virtual someDefaultImplementedMethod()
{
//default implementation
}
void read()
{
//template method pattern
m_prop1 = blablabla;
someDefaultImplementedMethod();
}
protected:
paramStorage_t m_storage;
int m_prop1;
int m_prop2;
};
class paramArray: public paramBase
{
public:
virtual paramType_t type()
{
return PT_ARRAY;
}
virtual someDefaultImplementedMethod()
{
//overriding default implementation of base
//i.e. modify templated read() method behavior
}
protected:
int m_additional_prop1;
int m_additional_prop2;
};
In the end, I have 4 subclasses of base and I need to modify behavior of read() by static/non_static modificator.
How do I solve this without code duplication and code smell? Is the condition if( m_storage==static ) in read() is code smell or not?
You never have to duplicate code: just only re-implement that single method read. If you need to use it from pointers to the base class, virtual does just that. If you have common code between that 8 read method (or just between some of them), put it in a common middle layer.
If you want to make it clear that the class might not use the method at the base level, you can make it abstract, the add a ninth subclass for the RAM case.
Having a huge switch calling 9 different read methods in the same class seems far worse to me.
Straightforward solution can be furhter subclassing like paramArrayStatic, paramNumberStatic..etc. i.e. totally it will be 8 subclasses. Difference between paramArray and paramArrayStatic is basically only in read() method, so straightforward solution will lead to code duplication.
I agree. Creating a class that overrides the behaviour in such a significant way would be in violation of the SOLID principles (specifically the LSP part).
Also i can add if( m_storage==static ) to read() method and modify behavior, but this is also code smell(AFIK).
Who decides that this is code smell? It seems most expressive, and sensible to me.
Stop worrying so much about code smells, and start questioning the expressiveness of your options...
SigmaN,
For your simple example I would not worry about the control coupling in the read method. It is often better to have clear and maintainable code versus code that is strictly decoupled.
The general idea of your questions seems to be about decoupling the source of a value from the business logic for that value. Oftentimes, a good strategy is creating an interface as an ABC and then taking an instance on the the ctor. Here is a very simple example.
class ReadValue
{
public:
virtual int32_t readValue(std::string & value) = 0;
};
class DatabaseReadValue::public ReadValue
{
public:
virtual int32_t readValue(std:string & value) override; // read from the database
}
class XMLReadValue::public ReadValue
{
public:
virtual int32_t readValue(std::string & value) override; // read from XML file
}
class Parameter
{
public:
Parameter(ReadValue & readValueObj): readValueObj_(readValueObj) {}
int32_t read() { return(readValueObj_.readValue(value_)); }
ReadValue & readValueObj_;
std::string value_;
}
Oftentimes, the idea will be used in a template class rather than using inheritance. The gist is the same however.
The idea is related several Design Patterns depending on the details. Bridge, Adapter, Factory, Abstract Factory, PIMPL.
https://en.wikipedia.org/wiki/Software_design_pattern
--Matt
My problem is solved in this way:
//public interface and basic functionality
class base
{
public:
virtual void arraySize() //part of interface
{
printf("base arraySize()\n");
}
//template method read
int read()
{
readImpl();
}
protected:
virtual void readImpl() = 0;
};
//only base functionality of array is here. no read implementation!
class array : public base
{
public:
virtual void arraySize()
{
printf("array arraySize()\n");
}
};
//implement static read for array
class stat_array : public array
{
public:
void readImpl()
{
printf("stat_array read() \n");
}
};
//implement non static read for array
class nostat_array : public array
{
public:
void readImpl()
{
printf("nostat_array read() \n");
}
};
//test
stat_array statAr;
nostat_array nonstatAr;
base *statArPtr = &statAr;
base *nonstatArPtr = &nonstatAr;
void main()
{
statArPtr->read();
nonstatArPtr->read();
}

How to use polymorphic method on a container of different classes

I have two classes like below :
class Plot
{
protected:
virtual void plot() = 0;
}
class DynamicPlot : public Plot
{
public:
virtual void update_real_time();
virtual void plot();
}
class StaticPlot : public Plot
{
public:
virtual void plot();
}
And a container like this:
std::vector<Plot*> plot_vector;
plot_vector.append(new DynamicPlot());
plot_vector.append(new DynamicPlot());
plot_vector.append(new StaticPlot());
plot_vector.append(new StaticPlot());
And i want to call update_real_time() if the type of the instance is DynamicPlot.
foreach(Plot *plot, plot_vector)
{
if(/* plot type == DynamicPlot */)
{
plot->update_real_time();
}
plot->plot();
}
Which pattern should i use here ? Adding an empty update_real_time() method into the StaticPlot class doesn't seem like a good solution.
EDIT : The code above is not real. I just wrote it in order to tell my problem, think that as a psuedo code. I didn't bother to write access qualifiers. In my real code, i do not have a private inheritance or slicing issue. I keep pointers of instances in vector. Sorry for misunderstanding. I am fixing it anyway.
You would need to use dynamic_cast:
foreach(Plot *plot, plot_vector)
{
DynamicPlot* p = dynamic_cast<DynamicPlot*>(plot);
if(p)
{
p->update_real_time();
}
plot->plot();
}
Except that foreach is not C++, so you would have to use real code for that too.

Tightly coupled parallel class hierarchies in C++

For context, I'm working on a C++ artificial-life system involving agents controlled by recurrent neural networks, but the details aren't important.
I'm facing a need to keep two object hierarchies for the "brain" and "body" of my agents separate. I want a variety of different brain and body types that can be coupled to each other at run-time. I need to do this to avoid a combinatorial explosion caused by the multiplicative enumeration of the separate concerns of how a body works and how a brain works.
For example, there are many topologies and styles of recurrent neural network with a variety of different transfer functions and input/output conventions. These details don't depend on how the body of the agent works, however, as long as sensory inputs can be encoded into neural activity and then decoded into actions.
Here is a simple class hierarchy that illustrates the problem and one potential solution:
// Classes we are going to declare
class Image2D; // fake
class Angle2D; // fake
class Brain;
class Body;
class BodyWithEyes;
class BrainWithVisualCortex;
// Brain and Body base classes know about their parallels
class Brain
{
public:
Body* base_body;
Body* body() { return base_body; }
virtual Brain* copy() { return 0; } // fake
// ...etc
};
class Body
{
public:
Brain* base_brain;
Brain* brain() { return base_brain; }
virtual Body* reproduce() { return 0; } // fake
// ...etc
};
// Now introduce two strongly coupled derived classes, with overloaded access
// methods to each-other that return the parallel derived type
class BrainWithVisualCortex : public Brain
{
public:
BodyWithEyes* body();
virtual void look_for_snakes();
virtual Angle2D* where_to_look_next() { return 0; } // fake
};
class BodyWithEyes : public Body
{
public:
BrainWithVisualCortex* brain();
virtual void swivel_eyeballs();
virtual Image2D* get_image() { return 0; } // fake
};
// Member functions of these derived classes
void BrainWithVisualCortex::look_for_snakes()
{
Image2D* image = body()->get_image();
// ... find snakes and respond
}
void BodyWithEyes::swivel_eyeballs()
{
Angle2D* next = brain()->where_to_look_next();
// ... move muscles to achieve the brain's desired gaze
}
// Sugar to allow derived parallel classes to refer to each-other
BodyWithEyes* BrainWithVisualCortex::body()
{ return dynamic_cast<BodyWithEyes*>(base_body); }
BrainWithVisualCortex* BodyWithEyes::brain()
{ return dynamic_cast<BrainWithVisualCortex*>(base_brain); }
// pretty vacuous test
int main()
{
BodyWithEyes* body = new BodyWithEyes;
BrainWithVisualCortex* brain = new BrainWithVisualCortex;
body->base_brain = brain;
brain->base_body = body;
brain->look_for_snakes();
body->swivel_eyeballs();
}
The trouble with this approach is that it's clunky and not particularly type-safe. It does have the benefit that the body() and brain() member functions provide a bit of sugar for derived classes to refer to their partners.
Does anyone know of a better way of accomplishing this tight coupling between 'parallel' hierarchies of classes? Does this pattern come up often enough to have warranted a well-known general solution? A perusal of the usual sources didn't reveal any established patterns that match this problem.
Any help appreciated!
I think what you are doing is approximately correct. You would want the members such as reproduce to be pure virtual, though, so the base classes cannot be created. What is your issue with type-safety? You don't want the Brain subclass and the Body subclass to depend on each others' types.

calling a function from a set of overloads depending on the dynamic type of an object

I feel like the answer to this question is really simple, but I really am having trouble finding it. So here goes:
Suppose you have the following classes:
class Base;
class Child : public Base;
class Displayer
{
public:
Displayer(Base* element);
Displayer(Child* element);
}
Additionally, I have a Base* object which might point to either an instance of the class Base or an instance of the class Child.
Now I want to create a Displayer based on the element pointed to by object, however, I want to pick the right version of the constructor. As I currently have it, this would accomplish just that (I am being a bit fuzzy with my C++ here, but I think this the clearest way)
object->createDisplayer();
virtual void Base::createDisplayer()
{
new Displayer(this);
}
virtual void Child::createDisplayer()
{
new Displayer(this);
}
This works, however, there is a problem with this:
Base and Child are part of the application system, while Displayer is part of the GUI system. I want to build the GUI system independently of the Application system, so that it is easy to replace the GUI. This means that Base and Child should not know about Displayer. However, I do not know how I can achieve this without letting the Application classes know about the GUI.
Am I missing something very obvious or am I trying something that is not possible?
Edit: I missed a part of the problem in my original question. This is all happening quite deep in the GUI code, providing functionality that is unique to this one GUI. This means that I want the Base and Child classes not to know about the call at all - not just hide from them to what the call is
It seems a classic scenario for double dispatch. The only way to avoid the double dispatch is switching over types (if( typeid(*object) == typeid(base) ) ...) which you should avoid.
What you can do is to make the callback mechanism generic, so that the application doesn't have to know of the GUI:
class app_callback {
public:
// sprinkle const where appropriate...
virtual void call(base&) = 0;
virtual void call(derived&) = 0;
};
class Base {
public:
virtual void call_me_back(app_callback& cb) {cb.call(*this);}
};
class Child : public Base {
public:
virtual void call_me_back(app_callback& cb) {cb.call(*this);}
};
You could then use this machinery like this:
class display_callback : public app_callback {
public:
// sprinkle const where appropriate...
virtual void call(base& obj) { displayer = new Displayer(obj); }
virtual void call(derived& obj) { displayer = new Displayer(obj); }
Displayer* displayer;
};
Displayer* create_displayer(Base& obj)
{
display_callback dcb;
obj.call_me_back(dcb);
return dcb.displayer;
}
You will have to have one app_callback::call() function for each class in the hierarchy and you will have to add one to each callback every time you add a class to the hierarchy.
Since in your case calling with just a base& is possible, too, the compiler won't throw an error when you forget to overload one of these functions in a callback class. It will simply call the one taking a base&. That's bad.
If you want, you could move the identical code of call_me_back() for each class into a privately inherited class template using the CRTP. But if you just have half a dozen classes it doesn't really add all that much clarity and it requires readers to understand the CRTP.
Have the application set a factory interface on the system code. Here's a hacked up way to do this. Obviously, apply this changes to your own preferences and coding standards. In some places, I'm inlining the functions in the class declaration - only for brevity.
// PLATFORM CODE
// platformcode.h - BEGIN
class IDisplayer;
class IDisplayFactory
{
virtual IDisplayer* CreateDisplayer(Base* pBase) = 0;
virtual IDisplayer* CreateDisplayer(Child* pBase) = 0;
};
namespace SystemDisplayerFactory
{
static IDisplayFactory* s_pFactory;
SetFactory(IDisplayFactory* pFactory)
{
s_pFactory = pFactory;
}
IDisplayFactory* GetFactory()
{
return s_pFactory;
}
};
// platformcode.h - end
// Base.cpp and Child.cpp implement the "CreateDisplayer" methods as follows
void Base::CreateDisplayer()
{
IDisplayer* pDisplayer = SystemDisplayerFactory::GetFactory()->CreateDisplayer(this);
}
void Child::CreateDisplayer()
{
IDisplayer* pDisplayer = SystemDisplayerFactory::GetFactory()->CreateDisplayer(this);
}
// In your application code, do this:
#include "platformcode.h"
class CDiplayerFactory : public IDisplayerFactory
{
IDisplayer* CreateDisplayer(Base* pBase)
{
return new Displayer(pBase);
}
IDisplayer* CreateDisplayer(Child* pChild)
{
return new Displayer(pChild);
}
}
Then somewhere early in app initialization (main or WinMain), say the following:
CDisplayerFactory* pFactory = new CDisplayerFactory();
SystemDisplayFactory::SetFactory(pFactory);
This will keep your platform code from having to know the messy details of what a "displayer" is, and you can implement mock versions of IDisplayer later to test Base and Child independently of the rendering system.
Also, IDisplayer (methods not shown) becomes an interface declaration exposed by the platform code. Your implementation of "Displayer" is a class (in your app code) that inherits from IDisplayer.