Strategy Design Pattern for handling requests - c++

I need to refactor class, which handles requests. I don't need chain of responsibility, because in compile time I have specified which request is connected to which handler.
My idea is to create one singleton class which is responsible for all logic.
For example it will have pointer to database object and it will handle requests.
There will be interface for HandlerMessage and many class derived from them.
Suppose we have:
class Singleton {
Database db;
int handleMessage(const Request& in, Response& out);
};
int Singleton::handleMessage(const Request& in, Response& out) {
int result = 0;
HandlerMessage* handler;
if(in.type == RequestType::A)
handler = new HandlerA();
else if(in.type == RequestType::B)
handler = new HandlerB();
else
return -1;
result = handler->handle(in, out);
delete handler;
return result;
}
However HandlerMessage needs to use Database and I wonder how to get use them.
I can pass pointer to database as an argument of handle function in HandlerMessage class.
However it seems to me strange, because all time I will pass the same argument. Moreover not all handlers needs to use database.
My question is:
class MessageHandler {
static Database* db;
}
this a good solutions, where I initialized db from MessageHandler class with db from SingeltonClass in Singleton constructor?
Or it is better to use more sophisticated solutions?
Thank You for any reply!

You can pass the reference to the database in the constructor of the handler like this:
handler = new HandlerA(db); //HandlerA needs to deal with database
handler = new HanlderB(); //HandlerB doesn't need to deal with database
HandlerA can look like this:
class HandlerA : public MessageHandler
{
HandlerA(Database& db) { /* ... */ }
int handle(const Request& in, Response& out) { /* ... */ }
};

Related

Cap'n'proto premature destruction of interface?

Let's say I have a streaming API like this:
interface MyInterface {
addListener #0 (listener: Listener) -> (registration: RegisteredListener);
interface Listener {
update #0 () -> stream;
}
interface RegisteredListener {
}
}
I'm having a challenge where the destructor for the server implementation of MyInterface is running before the last registered interface has been released. How can I properly communicate the relationship to cap'n'proto RPC so that even if the client releases it's MyInterface::Client before the RegisteredListener::Client, that either MyInterface::Server lifetime is extended or the RegisteredListener::Server is smart enough to recognize that the original server instance its tracking the registration for is dead. Alternatively, am I misusing the API in some basic way?
Roughly the C++ code looks like this. Server:
class MyInterfaceImpl : public MyInterface {
class Registered final : public MyInterface::RegisteredListener::Server {
public:
Registered(MyInterfaceImpl* parent, uint64_t registrationId) : parent_(parent), id_(registrationId) {}
~Registered() {
parent->unregister(id_);
}
private:
MyInterfaceImpl *parent_;
uint64_t id_;
};
public:
kj::Promise<void> addListener(MyInterface::AddListenerContext context) {
auto registrationId = ++registrationId_;
clients_.emplace_back(context.getParams().getListener());
registrations_.emplace_back(registrationId);
context.getResult().setRegistration(kj::heap<Registered>(this, registrationId));
return kj::READY_NOW;
}
void unregister(uint64_t registrationId) {
auto found = std::find(registrations_.begin(), registrations_.end(), registrationId);
clients_.erase(clients_.begin() + (found - registrations_.begin()));
}
private:
std::vector<MyInterface::Listener::Client> clients_;
std::vector<uint64_t> registrations_;
uint64_t registrationId_ = 0;
};
The client code looks something like this:
capnp::EzRpcClient client("localhost:5923");
MyInterface::Client intf = client.getMain<MyInterface>();
auto& waitScope = client.getWaitScope();
auto listenerRequest = intf.addListenerRequest();
auto listenerPromise = listenerRequest.send();
listenerPromise.wait(waitScope);
{
auto listenerRequest2 = intf.addListenerRequest();
auto listenerPromise2 = listenerRequest2.send();
listenerPromise2.wait(waitScope);
}
Since this is all single-threaded it's pretty easy to spot the use-after-free. I put debug statements in ~MyInterfaceImpl and ~RegisteredListener and the second listener is getting unregistered after ~MyInterfaceImpl. I know that my add listener requests don't have the actual client object but I'm hoping that's not actually an important detail for this.
I recommend having Registered class hold a MyInterface::Client pointing to the parent, in addition to the plain pointer it currently holds.
MyInterfaceImpl *parent_;
MyInterface::Client ownParent_;
uint64_t id_;
This ensures that as long as a Registered still exists, the MyInterfaceImpl won't be destroyed.
Inside the implementation of addListener(), you can obtain a MyInterface::Client pointing to this by calling thisCap().
context.getResult().setRegistration(kj::heap<Registered>(
this, thisCap(), registrationId));

Using GoogleMock to mock an instance created by code under test

I have create an interface (here's an example):
class DataStream
{
virtual std::string read(std::string terminator) = 0;
virtual size_t write(std::string data) = 0;
};
For which there exists a concrete implementation, such as:
class SerialDataStream : public DataStream
{
public:
// NOTE: This constructor will throw an exception if the
// serial port cannot be opened.
SerialDataStream(string port, int baudrate);
std::string read(std::string terminator);
size_t write(std::string data);
}
And the interface is used, for example:
class SomeThing
{
public:
SomeThing(std::shared_ptr<DataStream> stream);
}
Using GoogleMock, testing the SomeThing class is fairly straight forward, all you need to do is create a mock implementation for the interface, for example:
class MockDataStream : public DataStream
{
public:
MOCK_METHOD1(read, size_t(std::vector<uint8_t>&));
MOCK_METHOD1(write, size_t(std::vector<uint8_t>&));
}
Where the test would look something like this:
std::shared_ptr<MockDataStream> mock_stream(nullptr);
mock_stream = std::make_shared<MockDataStream>();
EXPECT_CALL(*mock_stream, write("START")).Times(AtLeast(1));
EXPECT_CALL(*mock_stream, read("\n")).Times(AtLeast(1));
SomeThing some_thing = SomeThing(mock_stream);
Which is pretty cool as it easily allows me to unittest how the SomeThing class uses the DataStream interface.
However, there also exists some code whose job it is to create new (concrete) DataStream objects and I'm finding using GoogleMock to test this a little more tricky. For example, here is a snippet of some code that needs to be tested:
std::shared_ptr<DataStream> datastream(nullptr);
// Try and open the serial port:
try
{
std::shared_ptr<SerialDataStream> serialstream =
std::make_shared<SerialDataStream>("/dev/tty99", 115200);
}
catch (...)
{
// Returns a nullptr
return datastream;
}
// Check if there is a known device on the other end:
datastream = std::static_pointer_cast<DataStream>(serialstream);
if (!device_is_connected(datastream))
{
datastream = nullptr;
}
return datastream;
I'm struggling to find an effective method to test this code with GoogleMock:
I would like to mock the constructor (of SerialDataStream) so it throws an exception and the failure path is executed as expected.
I would like to test the successful path where the private API "device_is_connected" uses the newly created datastream object.
Is it the case that I have no option other than to create a fake SerialDataStream implementation and use dependency injection to test the code which creates concrete DataStream objects?
If this is the case, I'll just have to make the API "device_is_connected" public so I can simply test it with a mock implementation of the interface (as above) to test, for example:
datastream.write("DISCOVER");
string response = datastream.read("\n");
if (discovery_ok(response))
{
// do stuff
}
I'm fairly certain I've answered my own question and will have no option but to fake the SerialDataStream class and use dependency injection, and make private APIs public and simply test them via GoogleMock, but I'm open to suggestions if there's a better way I could/should be doing things here.
Looking at the code snipped you provided, I found myself asking:
What exactly should the function do? It seems like it
(1) creates a SerialDataStream and
(2) checks if a device is connected.
You may could break the function into two (individually testable) parts.
Still there is the question on how to handle the std::shared_ptr<SerialDataStream> serialstream = std::make_shared<SerialDataStream>("/dev/tty99", 115200); - at some point you will need to tackle the (hidden) new there.
And I agree with you - dependency injection might be the solution there. Turning whatever class or function ends up responsible for creating into a template class/function would allow to write you (e.g.)
template<typename T>
std::shared_ptr<DataStream> createDatastream()
{
std::shared_ptr<DataStream> datastream(nullptr);
std::shared_ptr<T> datastream = std::make_shared<T>("/dev/tty99", 115200);
return datastream;
}
And then instantiate the class/function with SerialDataStream in your application, while using a MockDataStream to test the function(s).

C++ how to have seperate versions of the same method?

I'm sorry if I don't know the right word for what I'm trying to accomplish.
Basically I have an event handler object which only has a single member. The member is a Stage object.
When the event handler receives an event, I want it to simply use the stage object to call the relevant method. For example:
Event event; //this event is not part of my code, but rather the library I'm using.
Stage s; // my custom class object
EventHandler event_handler; //also my custom class object
event_handler.stage = &s;
if(event == SHUTDOWN) {
event_handler.stage->handle_shutdown();
}
So what I'm trying to accomplish is that, there will be seperate scopes that my program goes into over time, and I want each scope to have access to the event_handler such that they can do something like:
void some_other_scope(EventHandler* eh) {
Stage* some_new_stage = new Stage(...);
eh->stage = some_new_stage;
}
This way, the original event code stays the same, and the event handler will be calling handle_shutdown on a different object than it was originally going to.
So what I want to do is to overload the handle_shutdown method so that there can be different implementations of it. I know how basic overloading works, it can be done by specifying different parameters, but is there any way to have different definitions of the same class method based on the file that the object was created in?
I was hoping to have several files, each with their own some_other_scope() function, and each file can redefine the handle_shutdown method to do different things based on what that file needs.
I'm sure there's a way to do what I want, I just don't know the right words to use.
It seems you want to use polymorphism:
class IStage
{
public:
virtual ~IStage() = default;
virtual void handle_shutdown() = 0;
// ...
};
class Stage1 : public IStage
{
public:
void handle_shutdown() override { /*Implementation1*/ }
// ...
};
class Stage2 : public IStage
{
public:
void handle_shutdown() override { /*Implementation1*/ }
// ...
};
And then
struct EventHandler
{
std::unique_ptr<IStage> stage;
// ...
};
EventHandler event_handler;
event_handler.stage = std::make_unique<Stage1>();
if (event == SHUTDOWN) {
event_handler.stage->handle_shutdown();
}
// Later
event_handler.stage = std::make_unique<Stage2>();
if (event == SHUTDOWN) {
event_handler.stage->handle_shutdown();
}

Best approach to extend this C++ factory implementation?

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.

How to enforce coupling polymorphic type and enum value?

I have a state machine with one state which dispatches some message (e.g. text) to an external receiver. Before transiting to this state (let's call it Dispatching) previous state needs somewhere to store that message so Dispatching can fetch it later. As message is created in one context and consumed in another, it will be created on the heap and State Manager object (which manages states, transitions and event loop) keeps a reference/pointer to it. State objects are created and destroyed as state machine transits through states. Each state inherits abstract base class State:
enum StateID
{
STATE_A,
STATE_B,
...
};
class State
{
public:
State(StateID stateID, StateManager& sm) :
stateID_(stateID), sm(sm_){}
virtual ~State(){};
virtual StateID HandleEvent(const Event& e) = 0;
StateID id() const {return stateID_;}
protected:
StateID stateID_;
StateManager& sm_;
};
In order to make passing data to the next state generic, I came up with the idea of StateData - a piece of information passed from one state to the next one. It is stored in dynamic memory, State Manager keeps a reference to it so each state can access it. As it is possible that different types of data will be passed to different states, StateData can be made abstract base class, specialized for each particular state:
struct StateData
{
virtual ~StateData() = 0;
};
struct StateAData : public StateData
{
int n_;
StateAData(int n) : n_(n){}
};
struct StateBData : public StateData
{
std::string str_;
StateBData(const std::string& str) : str_(str){}
};
...
class StateManager
{
boost::scoped_ptr<State> pCurrState_;
boost::scoped_ptr<StateData> pStateData_;
...
public:
void runEventLoop()
{
while(true)
{
...
//get event from a queue
...
StateID nextStateID = pCurrState_->HandleEvent(e);
if(nextStateID == pCurrState_->id())
continue;
pCurrState_.reset(0);
switch(nextStateID)
{
case STATE_A:
pCurrState_.reset(new StateA(*this));
break;
case STATE_B:
pCurrState_.reset(new StateB(*this));
break;
case STATE_C:
pCurrState_.reset(new StateC(*this));
break;
...
}
}
}
...
};
class StateA
{
public:
StateA(StateManager& sm) : State(STATE_A, sm){}
StateID HandleEvent(const Event& e)
{
switch(e.ID)
{
case EVENT_1:
{
StateAData* pData = reinterpret_cast<StateAData*>(stateMachine_.pStateData_.get());
// do something with data, e.g. use it for transition logic
if(pData->n_ % 2)
{
stateMachine_.pStateData_.reset(new StateBData("Hello from StateA"));
return STATE_B;
}
else
{
...
}
break;
}
...
}
}
...
}
There is a pitfall in following lines:
stateMachine_.pStateData_.reset(new StateBData("Hello from StateA"));
return STATE_B;
If transition logic changes so from here we need to go to STATE_C, developer can forget to change the type of StateBData to StateCData:
stateMachine_.pStateData_.reset(new StateBData("Hello from StateA"));
return STATE_C;
...which would lead to undesired behaviour when StateC tries to cast down StateData to StateCData.
How to avoid this? How to enforce matching the type of created object and returned enum value?
Yeah, this code stinks and this is the consequence of using two piece information and using enum to distinguish state types instead of types themselves. HandleEvent could return StateXData and depending on this returned type (as it carries the information about the next state) State Manager would determine (by using RTTI) the next state to transit to (X) but I don't like this solution.
Another idea is to create an instance of the next state and pass its data into its constructor but this approach would pollute state machine design as one state would be created before previous state is destroyed.
Make the enum part of the base class or provide a pure virtual function in the base class to return this enum. This way, the state itself will advertise its type.