I have two interfaces: INetwork
and IController
. Class App
would store implementations of both interfaces as it's fields. Both interfaces should be able to access public methods of each other. It would look something like:
class INetwork
{
public:
virtual ~INetwork() {}
virtual void do_something() = 0;
virtual void setController(IController*);
}
class IController
{
public:
virtual ~IController() {}
virtual void do_something() = 0;
virtual void setNetwork(INetwork*);
}
class Controller : public IController
{
void do_something() override;
}
class Network : public INetwork
{
void do_something() override;
}
class App
{
private:
IController *controller;
INetwork *network;
void initialize()
{
controller = new Controller(); //todo: factory
network = new Network(); //todo: factory
controller.setNetwork(network);
network.setController(controller);
}
}
The idea:
Network
and Controller
are two separate entities that would evolve over time ( ControllerV1
, ControllerV2
, ControllerMultithreaded
, NetworkHttp
, NetworkModbus
, etc.), but I still need to maintain backward compatibility and concrete implementations would depend on the configuration. This is why I use interfaces. Network
and Controller
would be able to control each other depending on the various events, state changes and so on. This is why I pass them to each other via setController(IController*)
and setNetwork(INetwork*)
. I would also like to implement Observer patter for both Network
and Controller
. Now by main problem is that I am not sure how to correctly implement all my ideas using the modern C++11/14 approaches. Should I store INetwork
and IController
an simple pointer within the App
or should I use std::shared_ptr
here? How to store and pass references to INetwork
within IController
and vice-versa? Are there any issues in inheritance?
C++ provides several instruments and I am a bit lost here.
There is no one-and-only correct answer to the questions you're asking.
There are different ways of storing/passing variables that are interfaces and you've mentioned some of those ways. Some other ways of dealing with this depend on what you're ultimately trying to achieve.
For instance, if you're ultimately concerned about having polymorphic behavior and you're not tied to that being a design/type detail, you can also consider using type erasure and storing/passing these entities by value (semantically speaking). As to the how and why you might want to do it this way — which also addresses your question regarding issues with using inheritance — I'd suggest watching Sean Parent's talk: Inheritance Is The Base Class of Evil .
As to which way you should go, that's a matter of opinion which is better suited for a site like Code Review or Software Engineering .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.