I've used the command pattern quite extensively, and it works well. However, what's usually not discussed is where the instances of the Commands are created.
The following examples illustrate this issue: A Document has a function setText() that sets the text:
class Document {
public:
void setText(const std::string text) {
if (commandManager()->isActive()) {
// called by SetTextCommand
m_text = text;
} else {
// called somewhere in the application
commandManager()->addAndExecute(new SetTextCommand(this, text));
}
}
std::string text() const { return m_text; }
CommandManager * commandManager() const { return m_commandManager; }
private:
std::string m_text;
CommandManager * m_commandManager;
}
Here, the SetTextCommand would execute document->setText(text) like this:
class SetTextCommand : public Command {
public:
SetTextCommand(Document * doc, const std::string & text)
: Command(), m_doc(doc), m_oldText(doc->text()), m_text(text)
{}
void redo() override {
m_doc->setText(m_text);
}
void undo() override {
m_doc->setText(m_oldText, false);
}
}
The SetTextCommand is processed by the CommandManager like this:
CommandManager::addAndExecute(Command * command) {
m_doc->commandManager()->setActive(true); // THIS IS THE TRICK
command->redo();
m_doc->commandManager()->setActive(false); // THIS IS THE TRICK
m_stack->push_back(command);
}
The trick here is, that when running redo(), CommandManager::isActive() is set to true. Hence, Document::setText() will set m_text.
Obviously, all Document setter functions must follow the if (commandManager()->isActive()) { ... } else { ... } paradigm. This is, because the Commands themselves are created in the setter functions.
Question is now: Is this a good way to implement the command pattern? Or are there far cleaner solutions for creating the Commands while at the same time having a nice API?
Please be verbose with your answers.
I think it'd be pretty ugly to have to replicate the if (commandManager()->isActive()) everywhere... probably nicer to have setText always do the SetTextCommand path, and create a new setTextImmediate method which SetTextCommand can use.
Related
I need my mutator to call a different function in my constructor and another function anytime after that, so I was thinking of putting a bool as a second parameter to differentiate as follows:
void SetName(const char* name, bool init)
{
init ? this(name) : that(name);
}
Is this against convention or anything? Should I use two separate mutators instead?
It allows you to make a mistake which can instead be prevented at compile-time. For example:
Example example;
example.SetName("abc", true); // called outside the constructor, `init == true` anyway
To prevent such situations, just replace your
struct Example {
Example() { SetName("abc", true); }
void SetName(const char* name, bool init) { init ? foo(name) : bar(name); }
};
with
struct Example {
Example() { foo("abc"); }
void SetName(const char* name) { bar(name); }
};
Testing:
Example example; // calls the for-the-constructor version
example.SetName("abc"); // calls the not-for-the-constructor version
example.SetName("abc", true); // obviously, doesn't compile any more
I am working with a project that compiles with C++98 and I am trying to refactor my code in order to make it more maintainable.
My starting code is like this:
void ClassA::parseIncomingData(char * buffer) {
switch(buffer[0]) {
case 0x0F:
sendMessage("Reply to 0x0F");
}
}
void ClassA::sendMessage(char * text) {
...
}
I want to move the parser code to a dedicated class to isolate the parsing logic from the rest of the code. So I did this change:
Created class MessageParser:
MessageParser::MessageParser(IMessageSender * messageSender) {
this->messageSender = messageSender;
}
void MessageParser::parseBuffer(char * buffer) {
...
messageSender->sendMessage("Reply");
}
Changed the original ClassA:
(ClassA implements IMessageSender interface)
void ClassA::parseIncomingData(char * buffer) {
MessageParser * parser = new MessageParser((IMessageSender *)this);
parser->parseBuffer(buffer);
delete parser;
}
void ClassA::sendMessage(char * text) {
...
}
Is there a better option to call MessageParser with some kind of reference to the non-static callback function that is defined into ClassA?
I have a codebase with many command line options. Currently, each command line option lives in a table along with a function pointer to run if the command is passed in on the command line.
e.g.
static CommandFunction s_Commands[] =
{
{ "command1", Func1 },
{ "command2", Func2 },
{ "command3", Func3 },
etc...
};
My problem with this is, the table is huge, and the functions live elsewhere. I would prefer the string for the command to live right beside each function.
So for example:
COMMAND_ARG("command1")
void Func1()
{
dostuff
...
}
COMMAND_ARG("command2")
void Func2()
{
dostuff
...
}
COMMAND_ARG("command3")
void Func3()
{
dostuff
...
}
Is this possible?
You can do that with a template specialized by an address of a function:
#include <stdio.h>
// In a header file.
template<void(*Fn)()>
struct FnMeta
{
static char const* const meta;
};
// no definition of meta
// some.cc
void some() {}
template<> char const* const FnMeta<some>::meta = "some";
// another.cc
void another() {}
template<> char const* const FnMeta<another>::meta = "another";
// main.cc
int main() {
printf("%s\n", FnMeta<some>::meta);
printf("%s\n", FnMeta<another>::meta);
}
The idea above is that FnMeta<>::meta is not defined. However, different translation units (.cc files) can provide a definition of a specialization of FnMeta<>::meta. This way when FnMeta<X>::meta is used the linker finds the appropriate definition of it in another translation unit.
There are different approaches to this particular problem. You can use inheritance, by which you create a base Command and then implement some execute function (you can also implement help, validate....). Then create a dispatcher function that associates the names with the actual implementations of the commands (in a lookup table of sorts, possibly a map).
While this does not solve your issue with locality, that issue might or not be real. That is, the implementation of the commands might be all over the place, but there is a single place that determines what commands are available in the CLI.
If locality is such an important thing for you (at the cost of not having a single place in your source code where all commands in use are listed), you can provide a registration mechanism that is globally accessible, then provide a helper type that during construction will register the function into the mechanism. You can then create one such object with each function definition.
CommandRegistry& getCommandRegistry(); // Access the registry
struct CommandRegister {
CommandRegister(const char* name, Function f) {
getCommandRegistry().registerCmd(name,f);
}
// Optionally add deregistration
};
// ...
void Func2() {...}
static CommandRegister Func2Registration("function2",&Func2);
I personally prefer to go the other way... having a single place in the code where all commands are listed, as it allows for a single location in which to find the command (text) to code that executes it. That is, when you have a few commands and someone else needs to maintain one of them, it makes it easier to go from the command line to the actual code that executes it.
I agree with Maxim Yegorushkin's answer that it is best to try to use static mechanisms, but here's a couple of runtime approaches that meet the requirement of keeping the behavior and the function name together.
Approach #1, Command Object:
class AbstractCommand{
public:
virtual ~AbstractCommand() {}
virtual void exec() = 0;
virtual const char *commandName() const = 0;
};
class Command1 : public AbstractCommand{
public:
virtual void exec() { /* do stuff */ }
virtual const char *commandName() const { return "command name 1"; }
};
class Command2 : public AbstractCommand{
public:
virtual void exec() { /* do stuff */ }
virtual const char *commandName() const { return "command name 2"; }
};
static AbstractCommand *s_commands[] {
new Command1(),
new Command2(),
...,
0
};
Approach #2, function with selector:
enum CommandExecOption { GET_NAME, EXEC };
typedef void* (*command_func_t)( CommandExecOption opt );
void *Command1Func( CommandExecOption opt )
{
switch(opt){
case GET_NAME: return "command 1"; break;
case EXEC:
/* do stuff */
break;
}
return 0;
}
void *Command2Func( CommandExecOption opt )
{
switch(opt){
case GET_NAME: return "command 2"; break;
case EXEC:
/* do stuff */
break;
}
return 0;
}
command_func_t s_commands[] = {
Command1Func,
Command2Func,
...,
0
};
So you want to use preprocessor macros, huh? There are seams to be bad, but I use them frequently. This answer will be based on command registry:
class Command
{
public:
Command(std::string const& _name):name(_name){ registry[_name]=this; }
virtual ~Command() { registry.erase(name); }
static void execute( std::string const& name ) {
RegistryType::iterator i = registry.find(name);
if(i!=registry.end()) i->second->_execute();
//some exeption code here
}
protected:
virtual void _execute() = 0;
private:
const std::string name;
typedef std::map< std::string, Command* > RegistryType;
static RegistryType registry;
};
There are static registry that should be somewhere else than header:
Command::RegistryType Command::registry;
Lets look what we need (changed a bit to be simpler):
COMMAND_ARG( doSomething )
{
cout << "Something to do!" << std::endl;
}
So we need to create some object of a class that inherit from Command and have implemented _execute method. Since method can be defined outside of class this macro will enclose all needed code, and use the code in braced:
class CommanddoSomething : public Command {
public:
CommanddoSomething () : Command( "doSomething" ) {}
private:
virtual void _execute();
} commanddoSomething;
void CommanddoSomething :: _execute()
{
cout << "Something to do!" << std::endl;
}
So this is perfect place for a macro:
#define COMMAND_ARG( NAME ) \
class Command ## NAME : public Command { \
public: Command ## NAME () : Command( #NAME ) {} \
private: virtual void _execute(); \
} command ## NAME; \
void Command ## NAME :: _execute()
I hope you like it.
I am new to C++ and came to a point, where I generate an overhead with classes. I have a QTcpSocket and read messages from it and create objects, for example MessageJoin, MessagePart, MessageUserData etc. I send these objects to my client and display them (+ do some UI updating).
Now here comes my problem. I tested a few design techniques but all of them are not that nice:
Pass each parameter of a message object in a signal/slot connection to the client - small overhead but not that good-looking
Create a method for each Message-Type (messageJoinReceived, messageNoticeReceived etc.)
Create one method and use dynamic_cast to cast für each class and test it
For a better understanding, I added my dynamic_cast version. As a said, the code looks ugly and unusable. My questions are:
Is there a better way to do it with (a) dynamic_cast
Is there another way (For example a design pattern) to solve such a problem ? maybe add a method in the classes and return the type or something like this
I read about the visitor pattern. This pattern is just for dynamic object types in Getter/Setter methods ?
A few side notes
I can use RTTI
Speed isn't a big deal. Clean and understandable code is more important
I use Qt and have the possiblity to use qobject_cast and signal/slots
Here is my code (Pastebin-Link):
// Default class - contains the complete message (untouched)
class Message
{
public:
QString virtual getRawMessage() { return dataRawMessage; }
protected:
QString dataRawMessage;
};
// Join class - cointains the name of the joined user and the channel
class MessageJoin : public Message
{
public:
MessageJoin(const QString &rawmessage, const QString &channel, const QString &user)
{
dataRawMessage = rawmessage;
dataChannel = channel;
dataUser = user;
}
QString getChannel() { return dataChannel; }
QString getUser(){ return dataUser; }
private:
QString dataChannel;
QString dataUser;
};
// Notice class - contains a notification message
class MessageNotice : public Message
{
public:
MessageNotice(const QString &rawmessage, const QString &text)
{
dataRawMessage = rawmessage;
dataText = text;
}
QString getText() { return dataText;}
private:
QString dataText;
};
// Client code - print message and update UI
void Client::messageReceived(Message *message)
{
if(message)
{
MessageJoin *messagejoin;
MessagePart *messagepart;
MessageNotice *messagenotice;
if((messagejoin = dynamic_cast<MessageJoin *>(message)) != 0)
{
qDebug() << messagejoin->getUser() << " joined " << messagejoin->getChannel();
// Update UI: Add user
}
else if((messagenotice = dynamic_cast<MessageNotice *>(message)) != 0)
{
qDebug() << messagenotice->getText();
// Update UI: Display message
}
else
{
qDebug() << "Cannot cast message object";
}
delete message; // Message was allocated in the library and is not used anymore
}
}
This looks quite similar to the expression problem and AFAIK there is no way to avoid casts if you are going to add new messages and new ways to handle them. However it's not that hard to make more eye pleasing wrap for necessary run-time stuff. Just create a map from message type to corresponding handler using typeid.
#include <functional>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
typedef std::function<void(Message *)> handler_t;
typedef std::unordered_map<
std::type_index,
handler_t> handlers_map_t;
template <class T, class HandlerType>
handler_t make_handler(HandlerType handler)
{
return [=] (Message *message) { handler(static_cast<T *>(message)); };
}
template <class T, class HandlerType>
void register_handler(
handlers_map_t &handlers_map,
HandlerType handler)
{
handlers_map[typeid(T)] = make_handler<T>(handler);
}
void handle(handlers_map_t const &handlers_map, Base *message)
{
handlers_map_t::const_iterator i = handlers_map.find(typeid(*message));
if (i != handlers_map.end())
{
(i->second)(message);
}
else
{
qDebug() << "Cannot handle message object";
}
}
Then register handlers for specific message types:
handlers_map_t handlers_map;
register_handler<MessageJoin>(
handlers_map,
[] (MessageJoin *message)
{
qDebug() << message->getUser() << " joined " << message->getChannel();
// Update UI: Add user
});
register_handler<MessageNotice>(
handlers_map,
[] (MessageNotice *message)
{
qDebug() << message->getText();
// Update UI: Display message
});
And now you can handle messages:
// simple test
Message* messages[] =
{
new MessageJoin(...),
new MessageNotice(...),
new MessageNotice(...),
new MessagePart(...),
};
for (auto m: messages)
{
handle(handlers_map, m);
delete m;
}
Surely you might want to make some improvements like wrapping handlers stuff into reusable class, using QT or boost signals/slots so you can have multiple handlers for a single message, but the core idea is the same.
The visitor pattern could be a good fit i.e.
class Message
{
public:
QString virtual getRawMessage() { return dataRawMessage; }
virtual void accept(Client& visitor) = 0;
protected:
QString dataRawMessage;
};
// Join class - cointains the name of the joined user and the channel
class MessageJoin : public Message
{
public:
MessageJoin(const QString &rawmessage, const QString &channel, const QString &user)
{
dataRawMessage = rawmessage;
dataChannel = channel;
dataUser = user;
}
QString getChannel() { return dataChannel; }
QString getUser(){ return dataUser; }
void accept(Client& visitor) override
{
visitor.visit(*this);
}
private:
QString dataChannel;
QString dataUser;
};
// Notice class - contains a notification message
class MessageNotice : public Message
{
public:
MessageNotice(const QString &rawmessage, const QString &text)
{
dataRawMessage = rawmessage;
dataText = text;
}
QString getText() { return dataText;}
void accept(Client& visitor) override
{
visitor.visit(*this);
}
private:
QString dataText;
};
void Client::visit(MessageJoin& msg)
{
qDebug() << msg.getUser() << " joined " << msg.getChannel();
// Update UI: Add user
}
void Client::visit(MessageNotice& msg)
{
qDebug() << msg.getText();
// Update UI: Display message
}
// Client code - print message and update UI
void Client::messageReceived(Message *message)
{
if(message)
{
message->visit(this);
delete message; // Message was allocated in the library and is not used anymore
}
}
A better design might be to have an abstract virtual function in the Message class, called process or onReceive or similar, the sub-classes implements this function. Then in Client::messageReceived just call this function:
message->onReceive(...);
No need to for the dynamic_cast.
I would also recommend you to look into smart pointers, such as std::unique_ptr.
If you have private data in the Client class that is needed for the message processing functions, then there are many methods of solving that:
The simplest is to use a plain "getter" function in the client:
class Client
{
public:
const QList<QString>& getList() const { return listContainingUiRelatedStuff; }
// Add non-const version if you need to modify the list
};
If you just want add items to the list in your example, then add a function for that:
void addStringToList(const QString& str)
{ listContainingUiRelatedStuff.push_back(str); }
Or the non-recommended variant, make Client a friend in all message classes.
The second variant is what I recommend. For example, if you have a list of all connected clients and want to send a message to all of them, then create a function sendAll that does it.
The big idea here is to try and minimize the coupling and dependencies between your classes. The less coupling there is, the easier it will be to modify one or the other, or add new message classes, or even completely rewrite one or the other of the involved classes without it affecting the other classes. This is why we split code into interface and implementation and data hiding.
Is it possible to get a list of functions in a certain namespace or all functions in a program at runtime?
I have a function pointer map and I need to add commands on my own to it, but I thought: why not create a namespace and let the program do the work at runtime?
something like(pseudocode):
typedef bool (*command)(void);
namespace Commands
{
bool Start(void)
{
return true;
}
bool End(void)
{
return true;
}
};
std::map<std::string,command> CommandMap;
main()
{
for(each function in namespace Commands)
{
CommandMap[std::string(function_name)] = function;
}
CommandMap["Start"]();
CommandMap["End"]();
return 0;
}
instead of
std::map<std::string,command> CommandMap;
main()
{
CommandMap["Start"] = Commands::Start;
CommandMap["End"] = Commands::End;
//list of thousands of other commands......
CommandMap["Start"]();
CommandMap["End"]();
return 0;
}
Is this possible to achieve in C++ or C++11? Or any alternatives to my goal?
No (it has to be 30 characters).
EDIT: This goes along with my comment about how much control you have. You could redefine all of your functions as functors, and have the constructor register itself with some array. Your base class would look like this:
EDIT2: read the comment about all functions having same arguments and return types, makes it a little cleaner.
class myFunctorBaseClass
{
public:
myFunctorClass () : {//register myself, no duplicates}
virtual int operator () (int);//Whatever types you want
};
class myFunctor: public myFunctorBaseClass //Define as many of these as you need
{
public:
int operator() (int y) { return y; } // Define this as whatever you want
}
This obviously would depend on the objects being constucted, but assuming they all were as an initialization step, this would get you what you want.
NOTE: This may be incomplete/not compile. I just kinda wrote this off the top of my head, but it should be close. The reference you want is "functors" if you have questions about how this works.
Consider something like:
class CommandCollection
{
...
void register_command(Command*, string);
map<string, Command*> m_command_map;
}
class Command
{
...
virtual do_command(...) = 0;
}
class EachCommand : public Command
{
EachCommand() { CommandCollection::instance().register_command(this, my_name); }
...
virtual do_command(...);
}
EachCommand each_command_inst;
The Command base class has a virtual to do a command. Each derived type implements the command (you could try overloading the () operator to make them look more like functions).
Each derived Command registers itself with the CommandCollection, so it can be known in a central location. If you want to associate the commands by string (seems good if a user is typing them in), then that would be the key in the map.
As mentioned elsewhere, names (in C and C++, other languages may/do differ on this point) only really exist as part of the source-code. Once compiled, the names cease to have any meaning in C and C++.
One could, however, consider some sort of structure like this:
class CommandBase
{
virtual bool doCommand() = 0;
virtual std::string name() = 0;
virtual ~CommandBase() {}
};
class StartCommand : public CommandBase
{
bool doCommand() { ...; return true }
std::string name() { return "Start"; }
};
void RegisterCommand(CommandBase *cmd)
{
CommandMap[cmd->name] = cmd;
}
...
StartCommand start;
...
void someFunction()
{
RegisterCommand(&start);
}
I'll probably get a downvote for mentioning macros, because these are evil - don't use this if you are a purist that don't like macros.
#define CMD(x) CommandMap[#x] = Command::x
CMD(start);
CMD(end);
There are certainly other variants, and someone who knows templates may well come up with something that does this using templates.