I am in a situation where I'm going to do a multiple inheritance (and the diamond of dread kind of). I'd like to avoid that, so hopefully someone has an idea to do it another way.
I want to make a library that handle network connections. I have an abstract factory with method to create a tcpServer, tcpClient, udp, and a last method that create an entry from a directory (config file is given to the init method of the factory). So I've created classes (actually interfaces) to this kind of connections. Entry is the base interface. To simplify, let's just say that it has methods to set data and status callback. All other classes (tcpClient ...) inherits from this one.
I want to do an implementation of this factory using boost, so I have to implement all the classes (tcpServer, …). The problem is that all class implementations require a common base. Here is what I'm going to do, but I'm not sure that's the right way to do it:
Here is the abstract part:
// The abstract factory:
class Factory
{
virtual IO::TcpServer* createTcpServer() = 0;
virtual IO::TcpClient* createTcpClient() = 0;
virtual IO::Entry* createFromConf() = 0;
};
// The Entry interface:
class Entry {
virtual bool isChild() const = 0;
// ...
virtual void setDataCbk() = 0;
virtual void setStateCbk() = 0;
};
// TcpClient interface
class TcpClient : public IO::Entry {
/* Nothing yet but stuff will come */
};
Here is the boost implementation (Class names are same but in different namespaces; I don't show the factory implementation):
// Entry first step of implementation (still abstract)
class Entry : public IO::Entry
{
virtual void setDataCbk();
virtual void setStateCbk();
};
// Flat entry : entry that can't have child (like tcp client, udp ...)
class FlatEntry : public IO::Boost::Entry
{
virtual bool isChild() const; // Will always return false
// ...
};
// The final TcpClient implementation
class TcpClient : public IO::TcpClient
, public IO::Boost::FlatEntry
{
// ...
};
So I'm worried about this multiple inheritance thing. On the other hand, super classe is a pure interface (no data, only pure virtual methods). Any ideas?
Related
My goal here was, instead of placing all methods in ServerInterface(superclass), i wanted to place the methods in child classes to organize the code better.
class ServerInterface
{
public:
Router* router = new Router();
Client* client = new Client();
ServerInterface() {
} //Creates new Router and Client instance
};
class Router : public ServerInterface
{
public:
Router() {}
void randomRouterFunction() {}
};
class Client : public ServerInterface
{
public:
Client() {}
virtual void randomClientFunction() {};
};
class ProductionServer : public ServerInterface
{
public:
ProductionServer() {}
};
int main() {
ProductionServer* productionServer = new ProductionServer();
productionServer->router->randomRouterFunction(); //causes it to not debug
return 0;
}
In my situation I am only allowed to access to ProductionServer which has to inherit from ServerInterface in my code.
So instead of calling productionServer->randomRouterFunction() or productionServer->randomClientFunction(), i wanted to be able to call productionServer->Router->randomRouterFunction() etc
Even though intellisense tells me that it's all working fine, trying to run my code i recieve
main:289:20: error: 'class ProductionServer' has no member named
'router'
productionServer->router->randomRouterFunction();
Is this even feasible to accomplish? The reason for thinking it may not work is cause the superclass creates a member of Router which is the child class, and then the router child class creates another superclass since it inherits it, which then creats another router child class in the superclass.... and it would be an infinite loop? XD
ps. The randomFunction() could be any method, just used as an example.
The problem is with the design. You can compile this but when you create a ProductionServer it will instantiate a ServerInterface which will create a Router and a Client and those will both also instantiate a ServerInterface that will create a Router and a Client and so on - until you get a stack overflow.
In order to get this in some working condition, you need to add something that breaks that cycle so that it doesn't instantiate Routers and Clients endlessly.
I have a code similar to the following:
template<class ObjType>
class jsonable
{
private:
static map<string, jsonElem> config;
protected:
virtual void setConfig() = 0;
//other fields and methods in public/private
}
class user : public jsonable<user>
{
protected:
virtual void setConfig();
//other fields and methods in public/private
}
class client : user
{
protected:
virtual void setConfig() {user::setConfig(); /* more config */}
//other fields and methods in public/private
}
The main idea of this code is to save in static variables data related to the class referenced in the template. The problem comes when I want to inherit from the user class: the static variable is shared between user and client classes, instead of one static variable for each class.
I've tried to do something like:
class client : user, jsonable<client>
But a bunch of problems appeared (many methods with same name, and some other related to inherit 2 times the same class). I don't know if there is an elegant way of do this, or even if there is a way at all. (I'm a bit newbie in c++)
Any idea would be welcome! :). And of course, I can "copy" all the contents of user into client but... I would like to do not do that until there are no more options.
Edit:
In order to add context and details to the question, I'm going to explain a bit what I'm doing (or want to do).
Jsonable is a class that provides the ability to serialize into Json another class (helped by https://github.com/nlohmann/json).
To achive this, it uses a static map to store each jsonable-field name and its info (type and position relative to the start of the class in memory, so it can be serialized and deserialized).
The problem comes if a class inherits from another class that inherits from jsonable. Both shares that map, so only the baseclass data is consider when serializing/deserializing. Hope this explanation helps to understand...
Edit2: Giving a full code in a question seems very overkilling to me. If someone wants something to compile, I've uploaded a git repo: https://github.com/HandBe/jsontests
Really thanks to all the people who have put interest on this question!.
A possible solution can be derive client from both user (because it is a user) and jsonable<client> as (private/public apart)
class user : public jsonable<user>
{
protected:
virtual void setConfig();
//other fields and methods in public/private
};
class client: public user, public jsonable<client>
{
virtual void setConfig()
{
user::setConfig();
// more config, referred to jsonable<client>::map
}
}
because it has to implement jsonable for itself (regardless of user).
This is the so-called "stacked parallelogram" inhertiance pattern very common in multiple interface implementations as modular behavior.
Now user and client have each their own configuration
If I understand your problem correctly: you want client to be a user, but also have all the per-class statics defined in jsonable?
Have you considered composition over inheritance? This could work either way:
1) make user a component of client
class client : public jsonable<client>
{
user parent; // could also be a pointer
void setConfig() {parent.setConfig(); /* more config */}
/* ... */
}
2) make jsonable a component:
class user
{
jsonable<user> userjson; // public, private, whatever is appropriate for your design
/* ... */
}
class client : public user
{
jsonable<client> clientjson;
/* ... */
}
I would like to extend an existing piece of code, and I'm not sure about the cleanest design approach to do so. I'm wondering if the existing design really supports the kind of extension that I'm thinking of.
There is a factory which looks like this:
class XYZFactory
{
public:
static XYZFactory& getDefaultInstance() // so this is a singleton!
// ... some create methods
// std::unique_ptr<ABC> createABC();
private:
std::unique_ptr<XYZFactoryImpl> m_impl;
}
---
XYZFactory::XYZFactory() : m_impl(std::make_unique<XYZImpl>;
Now the problem is that I would like to extend the functionality of XYZImpl by deriving from it. I would like to avoid to expose that implementation detail however in the factory class, like adding a separate XYZFactory constructor with a ExtendedXYZImpl as an argument to inject that extension.
ADDED/EDITED for clarifaction: I should have called XYZImpl XYZFactoryImpl. It does the actual object creation. XYZFactory passes the createWhatever() calls to it. There is only one instance of XYZImpl which is held in m_Impl.
The thing that I actually want to be able to dynamically change is a member of XYZImpl m_ABC (instance of ABC) which is used for the object creation. I would like to derive from ABC.
Would killing the singleton design and subclassing from XYZFactory help?
Any ideas?
Thank you!
Mark
XYZFactory currently has a dependency on XYZFactoryImpl so clearly there is no way of injecting a dependency on ExtendedXYZImpl without exposing that functionality on XYZFactory. If that is unacceptable, the only alternative is to abandon the current design of XYZFactory.
There are not a great deal of constraints left in your question for us to use to form an answer but I suggest you start by making XYZFactory an abstract factory:
class XYZFactory {
public:
virtual ~XYZFactory(){}
virtual std::unique_ptr<ABC> createABC() const = 0;
}
With two implementations:
class XYZFactoryImpl : public XYZFactory {
public:
std::unique_ptr<ABC> createABC() const override {
return std::make_unique<ABC>();
}
};
class ExtendedXYZFactoryImpl : public XYZFactory {
public:
std::unique_ptr<ABC> createABC() const override {
return std::make_unique<DerivedABC>();
}
};
You can then provide a function to get a singleton instance and a way of reseating with a different singleton instance. e.g:
namespace details {
// Or this could be hidden in an anonymous namespace in a .cpp file
std::unique_ptr<XYZFactory>& getXYZFactoryInstanceMutable() {
static std::unique_ptr<XYZFactory> singleton = std::make_unique<XYZFactoryImpl>();
return singleton;
}
}
const XYZFactory& getXYZFactoryInstance() {
auto& singleton = details::getXYZFactoryInstanceMutable();
if (!singleton)
throw std::runtime_error("No XYZFactory registered");
return *singleton;
}
void setXYZFactoryInstance(std::unique_ptr<XYZFactory> new_factory) {
details::getXYZFactoryInstanceMutable() = std::move(new_factory);
}
Then to inject in your ExtendedXYZFactoryImpl you could do:
setXYZFactoryInstance(std::make_unique<ExtendedXYZFactoryImpl>());
auto abc = getXYZFactoryInstance().createABC();
Live demo.
Say i have an hierarchy of Shape objects, each has its own data (polyline has list of vertices, circle has a center and radius, etc).
I want to be able to perform operations on each shape, such as Draw, Snap to some point, split to two shapes at a specific point, etc.
One way to do it is to add a method to Shape interface for each operation. However, in that case i will have to modify my model interface every time a new operation is added. It does not sound correct to me. I thought of the following solution and would like to here your opinion or other solutions.
I will add an interface of ShapeOperationsFactory and the following method to Shape interface:
class Shape
{
public:
virtual ShapeOperationFactory* createShapeOperationsFactory() = 0;
};
class Circle : public Shape
{
public:
virtual ShapeOperationsFactory* createShapeOperationsFactor();
};
ShapeOperationsFactory* Circle::createShapeOperationsFactory()
{
return new CircleShapeOperationsFactory();
}
ShapeOperationsFactory will be able to create a set of operations classes that are specific for the shape:
class ShapeOperationsFactory
{
public:
virtual ShapeDrawer* createDrawer() = 0;
virtual ShapeSnapper* createSnapper() = 0;
virtual ShapeSplitter* createSplitter() = 0;
};
class CircleShapeOperationsFactory : public ShapeOperationsFactory
{
public:
virtual ShapeDrawer* createDrawer();
virtual ShapeSnapper* createSnapper();
virtual ShapeSplitter* createSplitter();
}
ShapeDrawer* CircleShapeOperationsFactory::createDrawer()
{
return new CircleShapeDrawer();
}
ShapeSnapper* CircleShapeOperationsFactory::createSnapper()
{
return new CircleShapeSnapper();
}
ShapeSplitter* CircleShapeOperationsFactory::createSplitter()
{
return new CircleShapeSplitter();
}
In this implementation the Shape interface will not change when new operations are added. For new shape i will need to implement a new operations factory and a class per operation. For new operations i will need to add a method to the operations factory class and a class implementing the operation for each shape.
Making your classes more modular by creating an Operator class I think is great, but this is not really a factory. Factory usually involved creating an object base on some message, for example on a unserialization process.
For your case you could have an Operator member in your base class and in the constructor of your derived class you assign that member to the appropriate Operator derived class.
A solution could be to use the visitor design pattern. The purpose of this design pattern :
the visitor design pattern is a way of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying those structures. It is one way to follow the open/closed principle.
The principle is simple:
You create a visitor class:
class Visitor
{
public:
virtual void visit(Circle*) = 0;
virtual void visit(Polyline*) = 0;
...
};
You add this method to Shape:
virtual void accept(class Visitor*) = 0;
Then you implements this method in each Shape sub class.
void Circle::accept(Visitor *v)
{
v->visit(this);
}
And then you have to create one visitor per operation:
class Drawer: public Visitor
{
public:
Drawer()
{
}
void visit(Circle* c)
{
drawCircle(c);
}
void visit(Polyline*p)
{
drawPolyline(p);
}
...
};
You could also delegate each visit method to a service: (visit(Circle* c) to a CircleDrawer).
void visit(Circle* c)
{
circleDrawer->draw(c);
}
void visit(Polyline*p)
{
polylineDrawer->draw(p);
}
If you want to add an operation, you will have to create a new visitor sub class.
If you want to add a shape, you will have to add a new method on each visitor.
The visitor collaborare really well with the composite design pattern (heavily use in gui programming). The visitor pattern can be used in addition with the composite pattern. The object structure can be a composite structure. In this case in the implementation of the accept method of the composite object the accept methods of the component object has to be invoked.
Note:
I am not a c++ programmer, feel free to edit and make the code syntactically correct.
I want to define plugin like objects for my program. They should look like this:
class ModuleBase
{
public :
void baseFunction1();
void baseFunction2();
...
virtual void init() = 0;
virtual void finalize() = 0;
};
class SpecificModule : public ModuleBase
{
public :
virtual void doSpecificTask() = 0;
};
Thus I will have SpecificModule implementations:
class ConcreteSpecificModule1 : public SpecificModule
{
public :
void init();
void finalize();
void doSpecificTask();
};
In order to mask implementation and complexity, I want my modules to see the underlying system through a facade Interface :
class SystemViewForSpecificModule
{
public :
virtual SystemData& getData(//some parameters) = 0;
virtual void doSystemAction1() = 0;
virtual void doSystemAction2() = 0;
...
};
Finally I want to be able to make several programs that can deal with Module and / or SpecificModule instances.
Considering I have prog1, prog2, and prog3, I will have to implement
Prog1View, Prog2View and Prog3View as concrete implementations of SystemViewForSpecificModule interface.
Additionally, I have to consider the following case :
Prog2 will embed Prog1 and I want to be able to do this :
instantiate the SpecificModule instances
run the prog1 part that make calls to SpecificModule::doSpecificTask();
run the prog2 part that also call SpecificModule::doSpecificTask();
My question is: How to pass / store the reference (or pointer) to the system in the SpecificModule instances ?
1 - Storing the reference at construction time :
thus the SpecificModule interface should like
class SpecificModule : public ModuleBase
{
SystemViewForSpecificModule& m_sys;
public :
SpecificModule(SystemViewForSpecificModule& sys):m_sys(sys){}
virtual void doSpecificTask() = 0;
};
This is a pleasant way to achieve my problem, but don't forget that in prog2 I have first to
run my modules with prog1, thus I have to switch from SystemViewForSpecificModule implementation dynamically in this case.
(+) Modules can access to system during their whole life and all method can get access to it.
(-) Once the reference set, it can not be changed
We can consider that using a reference is not a good solution, or use something like this:
class SystemView : public SystemViewForSpecificModule
{
SystemViewForSpecificModule* concreteSystem;
public
SystemView(SystemViewForSpecificModule& sys)
{concreteSystem = &sys;}
void setSystem(SystemViewForSpecificModule& sys)
{concreteSystem = &sys;}
void doSystemAction1()
{concreteSystem->doSystemAction1();}
...
}
This way, the module doesn't even know that the implementation has changed
However, I'm afraid it will reduce performance due to extra vtable access.
2 - Using a setter to specify the system view
The SpecificModule interface should like:
class SpecificModule : public ModuleBase
{
SystemViewForSpecificModule* m_sys;
public :
setSystem(SystemViewForSpecificModule& sys){m_sys = &sys;}
virtual void doSpecificTask() = 0;
};
That seems to be a convenient solution but I don't like the fact that the module has:
the knowing of this change
to handle this change
to check the validity of the pointer before using it
3 - Passing references to SpecificModule methods
At least the SpecificModule interface will look like that:
class SpecificModule : public ModuleBase
{
virtual void doSpecificTask(SystemViewForSpecificModule& sys) = 0;
};
I don't like to pass the same reference 10000 times to the same function (both prog1 and prog2 part will call it lot of times).
Another bad point for this solution is: I don't have access to the system view in the ModuleBase methods (such as init() and finalize()). And obviously, moving them to the subclasses would reduce the inheritance interest.
What solution would you use in this example case (I hope to see other solutions than the 3 presented)?