I wrote a command pattern to my class Administrator, HR and Staff.
Each of it has several MF but command only operate on single MF.
Therefore, i got this design.

I got the solution like this. CommandList composes Vector of command.

class GenericCommander;
class ComamndList : public GenericCommander {};
class Command : public GenericCommander {};
This approach works with single command and list of command.

Code:

class GenericCommand
{
public:
        GenericCommand();
        virtual ~GenericCommand();

        virtual void ExecuteSignalCallBack(int) = 0;

};

template <typename T>
class Command : public GenericCommand
{
public:
        typedef boost::shared_ptr<T> objectPtr;

private:

        objectPtr targetObjectCommandCallerPtr;

        void (T::*MemberFuncPtr)();

public:
        Command();
        explicit Command(objectPtr& );
        ~Command();

        void ExecuteSignalCallBack(int);

};

template <typename T>
Command<T>::Command() : targetObjectCommandCallerPtr(objectPtr())
{
}

// =========================================
template <typename T>
Command<T>::Command(objectPtr& user)
        : targetObjectCommandCallerPtr(objectPtr(user))
{
}

// =========================================
template <typename T>
Command<T>::~Command()
{
}

// =========================================
template <typename T>
void Command<T>::ExecuteSignalCallBack(int choice)
{
        (*targetObjectCommandCallerPtr.*MemberFuncPtr)();

}

template <typename T>
class Command;

template <typename T>
class CommandList : public GenericCommand
{
public:
        typedef boost::shared_ptr<T> objectPtr;

private:
        Command<T> cont[15];

public:
        CommandList();
        explicit CommandList(objectPtr&);

        ~CommandList();

        void ExecuteSignalCallBack(int);
        // void CallCommand(int );

};

// =========================================
template <typename T>
CommandList<T>::CommandList()
        : cont(Command<T>())
{
}

// =========================================
template <typename T>
CommandList<T>::CommandList(objectPtr& userTargetObjectPtr)
                : cont(Command<T>(userTargetObjectPtr))
{
}

// =========================================
template <typename T>
CommandList<T>::~CommandList()
{
}

// =========================================
template <typename T>
void CommandList<T>::ExecuteSignalCallBack(int choice)
{
        (cont[choice - 1].*MemberFuncPtr)();
}

// =========================================

*
        Not recommended to specialize
        Function Template
*/

// ============ General Command ============
template <typename T>
boost::shared_ptr<GenericCommander>
                                CommandFactory(boost::shared_ptr<T>& targetObject,
                                                                                                                        void (T::*MemberFuncPtr)() )
{
        // To create one command only
}

// =========== Generic Command List =========
template <typename T>
boost::shared_ptr<GenericCommander> CommandListFactory
(boost::shared_ptr<T>& targetObject)
{

}

// =========== Administrator Command ========
template <>
boost::shared_ptr<GenericCommander> CommandListFactory<Administrator>
(boost::shared_ptr<Administrator>&
targetObject)                                                                                                                                                                                                                                                                                                                                           void
(T::*MemberFuncPtr)() )
{
        // Regiter Administrator MF
        /*
                &Administrator::Add
                &Administrator::Delete
                &Administrator::Modified
        */
}

// ============= HR Command =================
template <>
boost::shared_ptr<GenericCommander> CommandListFactory<HumanResource>
(boost::shared_ptr<HumanResource>&
targetObject)                                                                                                                                                                                                                                                                                                                                           void
(T::*MemberFuncPtr)() )
{
        // Regiter HR MF
}

// ============== Staff Command ============
template <>
boost::shared_ptr<GenericCommander> CommandListFactory<Staff>
(boost::shared_ptr<Staff>&
targetObject)                                                                                                                                                                                                                                                                                                                                           void
(T::*MemberFuncPtr)() )
{
        // Register Staff MF
}

1. What approach replaces function template specialization ?
2. How to implement the CommandFactory ?

Usage Code:
share_ptr<GenericCommander> GCPtr = CommandFactory(thePtr);

GCPtr->ExecuteSignalCallBack(int);

Thanks for your help.

Recommended Answers

All 9 Replies

I do reading that but does not help any.

sorry PETER_APIIT but your design has several flaws, describe you requirement a bit, then I will tweak your design to meet your needs.

OK. Can you show me Why i my design was wrong ?

I have a class three class which are Administrator, HR and Staff. Therefore, i would like to create a command pattern that handle the request for each of this class. Each class has several MF.

My approach like this.

class GenericCommand;

// Use to handle single Command
template <typename T>
class command : public GenericCommand;


// Use to handle several command build before it called
template <typename T>
class CommandList: public GenericCommand;


Therefore, i code a three function templates to initialize the command with respective MF for each class.


My final choice wil be using single command but i will create the type on the fly. Another final choice is i have to create three class hierarchy which initialize the respective MF in each command.

I hope my explanation is clear to you.

Please let me know if you have any inquiry.

I don't think Command Design pattern best matches your need,

what you can do is simply create a Class that holds the map of Objects of type administrator, HR, Staff and value part contains the vector of member funciton pointers. now in each object administrator, HR or Staff create some integral type upon which you'll decide which member function would be executed for selected object. or either call every registered member funciton.

//something like below.
typedef void (T::*MEMFuncPtr)(int id);
map<T, vector<MEMFuncPtr> > fMap;

check for the Chain of Responsiblity Design pattern. your requirement matches that pattern.

As far as Factory Method is concern its simple man. provide the Create function in every member class and create the abstract factor which would be templatized.

Yes, i try this before because i have three classes which are Administrator, HR and Staff.

How can i create one map with hold three different type of MF ?

The fact is there are either one creation of administrator, hr or staff object at run time only. After that i want to issue command for that object instance only.

Therefore, if i uses your approach, i need to create three classes and do some polymorphism which choose what class to execute the command.

Thanks.

hmmmmmmmmmm, I've come up with some solution to you problem hope this might help you.

class ICommand {
public:
	virtual ~ICommand() = 0  { }
	virtual void ExecuteCallBack(int iCommandId) = 0;
};

// Command Base Object.
template<class T>
class Command : public ICommand {
	typedef void (T::*Delegate)(int a);
	vector<Delegate> memFunctions;
public:
	Command() { }
	void RegisterCallBack(Delegate func) {
		memFunctions.push_back(func);
	}

	Delegate GetCallBack(int idx) { 
		// add checking of constraint.
		return memFunctions[idx];
	}

	// you can add functions like 
	// void executeAllCallBacks() = 0;
	virtual void ExecuteCallBack(int iCommandId) = 0;

};


class Administrator : public Command<Administrator> {
protected:

	virtual void ExecuteCallBack(int iCommandId) {
		(this->*GetCallBack(iCommandId))(8);
	}

	Administrator() { }
public:
	
	

	void Add(int a) {
		cout << "Administrator Add"<<endl;
	}

	void Remove(int a ) {
		cout << "Administrator Remove"<<endl;
	}

	static Command<Administrator>* GetInstance() {
		return new Administrator;
	}
};


class HR : public Command<HR>  {
protected:
	virtual void ExecuteCallBack(int iCommandId) {
		(this->*GetCallBack(iCommandId))(8);
	}
HR() { }
public:
	
	void Add(int a) {
		cout << "HR Add"<<endl;
	}

	void Remove(int a ) {
		cout << "HR Remove"<<endl;
	}

	static Command<HR>* GetInstance() {
		return new HR;
	}
};




int main ()
{
	Command<Administrator>* obj = Administrator::GetInstance();
	obj->RegisterCallBack(&Administrator::Add);
	obj->ExecuteCallBack(0);

	Command<HR>* obj2 = HR::GetInstance();
	obj2->RegisterCallBack(&HR::Add);
	obj2->ExecuteCallBack(0);

	// now the interesting Part.
	vector<ICommand*> vec;
	vec.push_back(obj);
	vec.push_back(obj2);

	for(size_t i=0; i<vec.size(); ++i) {
		vec[i]->ExecuteCallBack(0);
	}

	return 0;
}

Hope this help, you can further comment on this as well.

Actually, i have the problem in my mind. By the way, thanks for your help.

Your solution is OOP approach and the approach i did before is Generic Programming approach.

I don't think chain of responsibility is suitable for this design because there are no list of handler that request pass along that handler.

By the way. Thanks. Solved.

Your solution has design flaw and it is consider as classical undoable command.

By the way, thanks for your help.

Sharing is caring.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.