I was just playing around with the "state design pattern" and had a couple of questions on how exactly errors are handled in a state machine. Let us take the case below
class state_machine
{
private:
state state1;
state state2;
public:
}
class state
{
private:
state_machine* m_state_machine; /** Will pass the pointer to states **/
public:
void perform_state1_action();
void perform_state2_action();
}
class state1: public state
{
public:
void perform_state1_action()
{
/**
Functionality
**/
}
void perform_state2_action(); // Have nothing to do for this function
}
class state2: public state
{
public:
void perform_state2_action()
{
/**
Functionality
**/
}
void perform_state1_action(); // Have nothing to do for this function
}
My question is how do I gracefully handle the case where we call perform_state2_action when its in state1. Do I write a base function implementation with nothing or maybe error logging functionality?
This design pattern requires you to provide public methods that are available for every state. If you come across a situation that you feel an urge to add an action that is valid only for one of them, it could mean one of the following:
You should make it private and call it from more general, public method(s), which can be implemented for all of your states
This method should be moved outside of the state machine because it is not related to the state
This is a specific case where empty implementation is a correct behaviour (so no error log needed)
You have chosen wrong design pattern
I decided to use the state design pattern with minor changes:
Use a generic name for a function like "do_task" and use this to call the needed private functions.
This provided the benefits of the state design pattern at the same time preventing creation of surplus absolute virtual functions
Related
I have an Event system in which a Manager class contains a queue of Events. The Event class is currently an abstract base class from which all specific events are derived. The idea is to allow the Manager to process() specific events that are specialized classes constructed with their own, unique parameters elsewhere in the code where the context of creation informs which event to create and how (sometimes using an Abstract Factory pattern). These Events are consumed asynchronously by Manager in a loop that continuously empties the queue, processing each event, and then destroying it as it is popped.
I designed this system to alleviate Manager from doing all of its own data manipulation. Instead, other parts of the code can queue an Event object, and that object can perform a task via its process() member, with the Manager not needing to know about it in detail.
Without an encapsulated Event system, I would be making endless additions to Manager's members: one for each task, and calling those tasks in case statements somewhere, which is terrible. I thought it would be better to use the Event system I have in the example here. This leaves Manager unchanged while various derived, specific events are defined elsewhere. This minimal example works fine, but the problem is that all derived Events need access to Manager's private data for each one's process() to have full capability as intended. If friend inheritance was allowed, simply making Event a friend class of Manager would solve the problem. Since it's not, the only way for this to work is to make all of Manager's data public (or, technically, add every new derived Event class I make as a friend to Manager).
This works, but feels wrong, and makes me think this is not the correct design. To be clear, the Manager contains a good deal of centralized information (necessary for thread sync, etc) that is more extensive than the Example would indicate. It manages network connections that will spawn a variety of different, often arbitrary events. I'd like to elegantly react to such an environment without inflating Manager with endless additional member functions every time I want to create a new type of event.
Is there a better way to achieve this code separation pattern and still retain the freedom I want for the separated code? Should I just publicize all of Manager's data after all?
The minimal Example (includes pseudocode):
class Event;
class Manager
{
public:
Manager() {}
// Event queue insertion and processing functions omitted
// private: // Commented out on purpose to allow compilation
int dataInt;
double dataReal;
std::string dataStr;
std::queue<Event *> events;
};
// Abstract Event base class with process() member
class Event
{
public:
Event(Manager * m) : manager(m)
{
process = std::bind(&Event::processKernel, this);
}
// Process the event
std::function<void(void)> process;
protected:
// Actual processing code: derived classes must define this function
virtual void processKernel() = 0;
private:
Manager * m;
};
// One example of a specialized (derived) Event
class SpecificEvent: public Event
{
public:
SpecificEvent(Manager * m, int p) : Event(m), param(p) { }
void processKernel()
{
// Intention: modify parent manager data
manager->dataInt = param;
}
private:
int param;
};
// Another specialized (derived) Event
class OtherEvent: public Event
{
public:
OtherEvent(Manager * m, double p) : Event(m), param(p) { }
void processKernel()
{
// Intention: modify parent manager data
manager->dataReal = param;
}
private:
double param;
};
// Example usage: could be inside a Manager member, or anywhere else
int main()
{
Manager manager;
// Make a SpecificEvent, pass it the manager, and its own specific parameter(s)
SpecificEvent e(&manager, 10);
//<Not shown> Add to manager's queue
// Manager processes this event at some point later with Event::process()
}
Since
If friend inheritance was allowed, simply making Event a friend class
of Manager would solve the problem
you can just get away with
struct ManagerFields { // all Manager's fields; just for the further convenience
int dataInt;
double dataReal;
};
class Manager: private ManagerFields { // only Manager and its friends know these Fields
friend class Event;
// here Manager can use dataInt, dataReal etc. just like before
};
class Event {
public:
Event(Manager* m) : manager{m} {}
virtual void process() = 0;
protected: // "friend inheritance" setup below
ManagerFields& fields() { return *manager; } // "the further convenience"
private:
Manager* manager;
};
class SpecificEvent: public Event {
public:
SpecificEvent(Manager* m, int p) : Event{m}, param{p} {}
void process() override { fields().dataInt = param; } // "friend inheritance" usage
private:
int param;
};
See the comments in the code.
I just needed something like this:
I have got a robot class which contains a motor object and a predefined callback function (which is triggered on an interrupt).
robot.h
class robot
{
public:
motor motor1;
};
motor.h
class motor
{
public:
int incrementPosition();
int getPosition();
private:
int position;
};
callback.cpp
void callback(){
motor1.incrementPosition(); //callback function needs to reach this already created motor1
}
What I am trying to achive is:
Robot and motor objects has to be created only once (only one robot and one motor are allowable, bacause it is connected to a real physical robot and a motor),
Motor object (motor1) has to be created automatically and most importantly, it should be callable from the prefined callback function.
So the main should be like this,
main(){
robot myRobot;
robot myRobot2; //is not allowed or should be useless
printf("%d\n", myRobot.motor1.getPosition());
}
Not that I really like to recommend that1, but obviously the Singleton Pattern comes to mind:
class robot {
robot() {}
public:
motor motor1;
static robot& instance() {
static robot theRobot;
return theRobot;
}
};
The only way to access an instance of robot is to use the instance() function then.
main(){
robot myRobot; // Fails to compile since the constructor is private
printf("%d\n", robot::instance().motor1.getPosition());
// ^^^^^^^^^^^^^^^^^ Access the one and only instance
}
The same way the single motor instance can be accessed in the callback function:
void callback(){
robot::instance().motor1.incrementPosition();
}
Some more considerations:
Make your robot class implement an interface like
struct IRobot {
virtual ~IRobot() {}
virtual std::vector<std::shared_ptr<IMotor>>& motors() = 0;
};
this makes it easier to write isolated unit tests and mock the robot singleton.
Instead of the static instance() function provide a global access function for the singleton instance that returns the above mentioned interface. This also can be easier replaced with a function that returns a mock object for unit testing.
1)The Singleton Design Pattern is often blamed as a bad design, and in most cases it actually is a bad decision. Nevertheless there are valid use cases, especially when designing embedded systems. You have one single and autonomous robot, that's clear and deserves a singleton.
It's considerable though, if you should fix yourself to a single motor from the beginning, it would be hard to change if the HW engineers decide to need a second motor.
I have three types of devices (USB, COM and wireless) and one PC software to connect with them. Every device have functions like connect, read and write data from RS485 network. On PC software I must implement application layer classes to work with devices. I am looking for some design pattern to write connection between application layer and transport layer. The first idea is to write abstract class DataLink and every device will inherit from the abstract class interface (pure OOP):
class DataLink {
public:
virtual bool read() = 0;
virtual bool write() = 0;
};
class USBDevice : public DataLink {
public:
bool read() { /* some code */ }
bool write() { /* some code */ }
bool specificUSBFunction() { /* some code */ }
};
class COMDevice : public DataLink {
public:
bool read() { /* some code */ }
bool write() { /* some code */ }
bool specificCOMFunction(){ /* some code */ }
};
DataLink *dl = new COMDevice();
dl->read();
dl->write();
Now if I want to use specific USB or COM function I must use ugly cast.
The other problem is that this class must be singleton because we have only one device available so we cannot create multiple objects.
I am looking for a good way to do this using C++ (can be v11 or v14).
First, as you have an abstract class, I'd suggest you strongly to consider defining an abstract constructor.
class DataLink {
public:
virtual bool read() = 0;
virtual bool write() = 0;
virtual ~DataLink() {}
};
Now creating the devices raises some questions. Your polymorphic design would rather speak for a parameterized factory method, where a parameter (configuration data ?) would tell if a COM, USB or WIFI device is to be created:
DataLink *dl = CreateDevice("COM"); // For example. COuld use an enum as well
But you add another constraint:
This class must be singleton because we have
only one device available so we cannot create multiple objects.
In fact, the intent of a singleton is not only to ensure a single instance, but also to ensure a global point of access to it. If you don't need such a global access, I'd strongly recommend not to use a singleton here.
By the way, your constraint raises other questions: Do you have one device of each type ? Or do you have one device whatever its type is ? And most of all, won't it be possible one day, that you have to support several devices ?
So, conceptually speaking, even if you have only one device currently, the unicity is not a property of your generic device class nor its concrete implementations. It's only your current use case for creating the DataLink. I'd therefore recommend you implement a factory and derive an application specific factory to implement your creational constraints;
class DeviceFactory { // application independent
public:
enum DeviceType { COMDevice, USBDevice, ... };
DataLink *CreateDevice(std::string devicename, DeviceType t);
};
class MySpecificFactory : public DeviceFactory { // application specific constraints
std::map<std::string,DataLink*> objects;
public:
DataLink *CreateDevice(std::string devicename, DeviceType t) {
if (objects.count(devicename)!=0) {
// device already exists, either report an error, or
// return the previously created object with the same name (provided it has the same type)
...
}
else {
DataLink* dl = DeviceFactory::CreateDevice(devicename,t);
if (dl)
objects[devicename]=dl;
return dl;
}
}
};
The handling of link specific functions is orthogonal to the creation issue. The easiest and safest way is certainly the dynamic cast:
if (COMDevice* cd=dynamic_cast<COMDevice>(dl)) // nullptr if it isn't a COMDevice
cd->COMFunction();
else ...
It's difficult to advise on more specific patterns, without knowing the purpose of the link specific functions and how they relate in the context of your application.
You have a couple options, but my own personal experience is from the middle-ware approach. So that approach is what I will recommend (even if you aren't writing 'middleware' the 'ideas' can still be useful)
We had several different 'physical connections': Military Radio 1, Military Radio 2, Wifi, USB to Ethernet, etc. Each of these can be thought of as similar to your different connection types.
Make use of the Bridge Pattern which...
is meant to "decouple an abstraction from its implementation so that the two can vary independently". The bridge uses encapsulation, aggregation, and can use inheritance to separate responsibilities into different classes.
1) Define an interface that all of your connections will use.
2) Encapsulate the base atomic actions of each connection type into a 'helper' class. (open(), close(), read(), write(Byte[] data), etc.)
3) Write a bridge class that converts the universal interface to the 'helper class' implementation for each connection type.
4) Have some logic that determines which 'connection' should be 'active' at a given time, and associate the 'connection interface' with the bridge impl. of the connection type being used. (or list of connections if this is multi-cast sending, etc.)
That should do it. You have a single Interface that the 'rest' of your application can write/read from. and the "impl. details" are hidden inside your atomic action 'helper' class and/or bridge class.
Example Interface: // obviously extremely simple examle
interface IConnection{
byte[] read(int size);
void write(byte[] data);
bool open();
bool close();
}
And an implementation class:
class usb_wrapper{
// this is completely made up, but made up methods to show pattern as an example
// these methods are extreme exaggerations and not 'real' at all
int open(String connectionName, int id){
// returns connection_id of new connection
}
int close(int connection_id){...} // returns a flag if connection was closed
bool write128byte(byte[] data) {...} // you can only write 128 byte chunks
byte[] read128byte(){...} // you can only read 128 byte chunks
}
As you can see the snippets above the have 'similarities' but the actual methods have different parameters, different requirements, etc.
bridge class:
class usbConnectionBridge implements IConnection{
usb_connection conn = new usb_connection();
// Here is where you have the IConnection methods, inside these methods you
// have the logic to 'adapt' from these methods ... to the 'conn' object
byte[] read(int size){...}
void write(byte[] data){...}
bool open(){...}
bool close(){...}
// possibly additional helper methods below, etc.
}
So the 'bridge' class would wrap(encapsulate) the usb_wrapper and make it able to interact with the interface. Thereby allowing the decoupling of the interface(abstraction) from its implementation(usb_wrapper) so that the two can vary independently" which is the bridge pattern by definition.
I have a legacy piece of software that has a single manager which controls a run of the program. It calls methods of various callback classes throughout the execution of the program. These are the user hooks. The problem is that of these 1000 different hooks is that
1) they each obviously have a different interface
2) the run manager only has a slot for one of each.
I have noticed that only allowing for the user to register just one instance of each user hook-in class with the run manager results in a lot of spaghetti code from my group. I would like to write simple wrappers that contain a list of hookins, then loop over the list and call the callback of each instance. Example:
class SomeLegacyUserActionClass
{
public:
virtual void A();
virtual void B();
};
class MyWrapper : public SomeLegacyUserActionClass
{
std::vector< SomeLegacyUserActionClass* > actionList;
public:
void A()
{
// loop over each action in actionList
{
action->A();
}
}
void B()
{
// loop over each action in actionList
{
action->B();
}
}
void addAction( SomeLegacyUserActionClass* action ) { ... }
};
This is becoming very tedious and ugly to do with so many classes. Is there some way I can make a template class or something to do this in one fell blow? There is obviously a pattern here, I just don't know if I can capitalize on it somehow in c++.
I guess I could get my group to implement some kind of decorator pattern for all their actions and do away with the vectors and loops.
Thanks
This is not possible with templates, because there is no way to retrieve the list of member-functions of a type for use in a template. If you really have a lot of classes, it might be sensible to use classic code-generation.
I'm implementing a mechanism similar to the observer design pattern for a multithreaded Tetris game. There is a Game class which contains a collection of EventHandler objects. If a class wants to register itself as a listener to a Game object it must inherit the Game::EventHandler class. On state change events a corresponing method is called on the EventHandler interface of each listener. This is what the code looks like:
class Game
{
public:
class EventHandler
{
public:
EventHandler();
virtual ~EventHandler();
virtual void onGameStateChanged(Game * inGame) = 0;
virtual void onLinesCleared(Game * inGame, int inLineCount) = 0;
private:
EventHandler(const EventHandler&);
EventHandler& operator=(const EventHandler&);
};
static void RegisterEventHandler(ThreadSafe<Game> inGame, EventHandler * inEventHandler);
static void UnregisterEventHandler(ThreadSafe<Game> inGame, EventHandler * inEventHandler);
typedef std::set<EventHandler*> EventHandlers;
EventHandlers mEventHandlers;
private:
typedef std::set<Game*> Instances;
static Instances sInstances;
};
void Game::RegisterEventHandler(ThreadSafe<Game> inGame, EventHandler * inEventHandler)
{
ScopedReaderAndWriter<Game> rwgame(inGame);
Game * game(rwgame.get());
if (sInstances.find(game) == sInstances.end())
{
LogWarning("Game::RegisterEventHandler: This game object does not exist!");
return;
}
game->mEventHandlers.insert(inEventHandler);
}
void Game::UnregisterEventHandler(ThreadSafe<Game> inGame, EventHandler * inEventHandler)
{
ScopedReaderAndWriter<Game> rwgame(inGame);
Game * game(rwgame.get());
if (sInstances.find(game) == sInstances.end())
{
LogWarning("Game::UnregisterEventHandler: The game object no longer exists!");
return;
}
game->mEventHandlers.erase(inEventHandler);
}
There are two problems that I often experience with this kind of pattern:
A listener object wants to unregister itself on an already deleted object resulting in a crash.
A event is fired to a listener that no longer exists. This happens most often in multithreaded code. Here's a typical scenario:
The game state changes in a worker thread. We want the notification to occur in the main thread.
The event is wrapped in a boost::function and sent as a PostMessage to the main thread.
A short time later this function object is processed by the main thread while the Game object is already deleted. The result is a crash.
My current workaround is the one that you can see in above code sample. I made the UnregisterEventHandler a static method which checks against a list of instances. This does help, but I find it a somewhat hackish solution.
Does anyone know of a set of guidelines on how to cleanly and safely implement notifier/listener system? Any advice on how to avoid the above pitfalls?
PS: If you need more information in order to answer this question you can find the relevant code online here: Game.h, Game.cpp, SimpleGame.h, SimpleGame.cpp, MainWindow.cpp.
The rule of thumb is that delete and new for an object should be near each other. E.g. in constructor and destructor or before and after a call where you use the object. So it's a bad practice to delete an object in another object when the latter one didn't create the former one.
I don't understand how you pack the events. It seems that you have to check whether the game is still alive before processing an event. Or you can use shared_ptr in events and other places to be sure that games are deleted last.
I write a lot of C++ code and needed to create an Observer for some game components I was working on. I needed something to distribute "start of frame", "user input", etc., as events in the game to interested parties. I had the same problem to consider...the firing of an event would lead to the destruction of another observer which may also subsequently fire. I need to handle this. I did not need to handle thread safety, but the design requirement I usually shoot for is to build something simple enough (API wise) that I can put in a few mutexes in the right place and the rest should take care of itself.
I also wanted it to be straight C++, not dependent on the platform or a specific technology (such as boost, Qt, etc.) because I often build and re-use components (and the ideas behind them) across different projects.
Here is the rough sketch of what I came up with as a solution:
The Observer is a singleton with keys (enumerated values, not strings) for Subjects to register interest in. Because it is a singleton, it always exists.
Each subject is derived from a common base class. The base class has an abstract virtual function Notify(...) which must be implemented in derived classes, and a destructor that removes it from the Observer (which it can always reach) when it is deleted.
Inside the Observer itself, if Detach(...) is called while a Notify(...) is in progress, any detached Subjects end up on a list.
When Notify(...) is called on the Observer, it creates a temporary copy of the Subject list. As it iterates over it, it compare it to the recently detached. If the target is not on it, Notify(...) is called on the target. Otherwise, it is skipped.
Notify(...) in the Observer also keeps track of the depth to handle cascading calls (A notifies B, C, D, and the D.Notify(...) triggers a Notify(...) call to E, etc.)
This is what the interface ended up looking like:
/*
The Notifier is a singleton implementation of the Subject/Observer design
pattern. Any class/instance which wishes to participate as an observer
of an event can derive from the Notified base class and register itself
with the Notiifer for enumerated events.
Notifier derived classes MUST implement the notify function, which has
a prototype of:
void Notify(const NOTIFIED_EVENT_TYPE_T& event)
This is a data object passed from the Notifier class. The structure
passed has a void* in it. There is no illusion of type safety here
and it is the responsibility of the user to ensure it is cast properly.
In most cases, it will be "NULL".
Classes derived from Notified do not need to deregister (though it may
be a good idea to do so) as the base class destrctor will attempt to
remove itself from the Notifier system automatically.
The event type is an enumeration and not a string as it is in many
"generic" notification systems. In practical use, this is for a closed
application where the messages will be known at compile time. This allows
us to increase the speed of the delivery by NOT having a
dictionary keyed lookup mechanism. Some loss of generality is implied
by this.
This class/system is NOT thread safe, but could be made so with some
mutex wrappers. It is safe to call Attach/Detach as a consequence
of calling Notify(...).
*/
class Notified;
class Notifier : public SingletonDynamic<Notifier>
{
public:
typedef enum
{
NE_MIN = 0,
NE_DEBUG_BUTTON_PRESSED = NE_MIN,
NE_DEBUG_LINE_DRAW_ADD_LINE_PIXELS,
NE_DEBUG_TOGGLE_VISIBILITY,
NE_DEBUG_MESSAGE,
NE_RESET_DRAW_CYCLE,
NE_VIEWPORT_CHANGED,
NE_MAX,
} NOTIFIED_EVENT_TYPE_T;
private:
typedef vector<NOTIFIED_EVENT_TYPE_T> NOTIFIED_EVENT_TYPE_VECTOR_T;
typedef map<Notified*,NOTIFIED_EVENT_TYPE_VECTOR_T> NOTIFIED_MAP_T;
typedef map<Notified*,NOTIFIED_EVENT_TYPE_VECTOR_T>::iterator NOTIFIED_MAP_ITER_T;
typedef vector<Notified*> NOTIFIED_VECTOR_T;
typedef vector<NOTIFIED_VECTOR_T> NOTIFIED_VECTOR_VECTOR_T;
NOTIFIED_MAP_T _notifiedMap;
NOTIFIED_VECTOR_VECTOR_T _notifiedVector;
NOTIFIED_MAP_ITER_T _mapIter;
// This vector keeps a temporary list of observers that have completely
// detached since the current "Notify(...)" operation began. This is
// to handle the problem where a Notified instance has called Detach(...)
// because of a Notify(...) call. The removed instance could be a dead
// pointer, so don't try to talk to it.
vector<Notified*> _detached;
int32 _notifyDepth;
void RemoveEvent(NOTIFIED_EVENT_TYPE_VECTOR_T& orgEventTypes, NOTIFIED_EVENT_TYPE_T eventType);
void RemoveNotified(NOTIFIED_VECTOR_T& orgNotified, Notified* observer);
public:
virtual void Reset();
virtual bool Init() { Reset(); return true; }
virtual void Shutdown() { Reset(); }
void Attach(Notified* observer, NOTIFIED_EVENT_TYPE_T eventType);
// Detach for a specific event
void Detach(Notified* observer, NOTIFIED_EVENT_TYPE_T eventType);
// Detach for ALL events
void Detach(Notified* observer);
/* The design of this interface is very specific. I could
* create a class to hold all the event data and then the
* method would just have take that object. But then I would
* have to search for every place in the code that created an
* object to be used and make sure it updated the passed in
* object when a member is added to it. This way, a break
* occurs at compile time that must be addressed.
*/
void Notify(NOTIFIED_EVENT_TYPE_T, const void* eventData = NULL);
/* Used for CPPUnit. Could create a Mock...maybe...but this seems
* like it will get the job done with minimal fuss. For now.
*/
// Return all events that this object is registered for.
vector<NOTIFIED_EVENT_TYPE_T> GetEvents(Notified* observer);
// Return all objects registered for this event.
vector<Notified*> GetNotified(NOTIFIED_EVENT_TYPE_T event);
};
/* This is the base class for anything that can receive notifications.
*/
class Notified
{
public:
virtual void Notify(Notifier::NOTIFIED_EVENT_TYPE_T eventType, const void* eventData) = 0;
virtual ~Notified();
};
typedef Notifier::NOTIFIED_EVENT_TYPE_T NOTIFIED_EVENT_TYPE_T;
NOTE: The Notified class has a single function, Notify(...) here. Because the void* is not type safe, I created other versions where notify looks like:
virtual void Notify(Notifier::NOTIFIED_EVENT_TYPE_T eventType, int value);
virtual void Notify(Notifier::NOTIFIED_EVENT_TYPE_T eventType, const string& str);
Corresponding Notify(...) methods were added to the Notifier itself. All these used a single function to get the "target list" then called the appropriate function on the targets. This works well and keeps the receiver from having to do ugly casts.
This seems to work well. The solution is posted on the web here along with the source code. This is a relatively new design, so any feedback is greatly appreciated.