Design Mode Overview - behavioral patterns

The previous two articles were put together in three categories of design patterns to create a schema and schema structure:

Design Overview Mode - Create schema 

Design Patterns Overview - structural model

Today let us sort out the last part, behavioral patterns.

First, what is the behavioral patterns?

Behavioral patterns (Behavioral Pattern) refers to the division of responsibilities between different algorithms and objects abstract design pattern, it is not only concerned about the structure of classes and objects, but also focus on the interaction between them.

For a system, the object is not the isolated operation, some complex functions can be accomplished through mutual communication and collaboration between objects, mutual influence between objects.

Behavioral patterns are divided into categories behavioral patterns and object behavioral patterns. Class behavioral patterns use inheritance in the distribution behavior between several classes, mainly the distribution of responsibilities father and son through a multi-state class, etc.. Object behavioral pattern is to assign responsibility by polymerization association objects. Most behavioral design patterns are all object behavioral design patterns.

Behavioral pattern comprising 11 kinds of specific design patterns, namely: duty chain (Chain of Responsibility Pattern), command mode (Command Pattern), the interpreter mode (Interpreter Pattern), Iterator (Iterator Pattern), intermediary model (Mediator pattern), the memo mode (Memento pattern), observer mode (observer pattern), state mode (state pattern), strategy mode (strategy pattern), the template method pattern (template method pattern), the Visitor pattern (Visitor pattern) .

We chose one of the five kinds to introduce.

1. Mode Command (Command Pattern)

Also known as command mode operation mode (Action Pattern) or transaction mode (Transaction Pattern). In this mode, a request is encapsulated into an object, so that a request for the client using different parameterization, or queue the request log, and support operations can be revoked.

Command mode can completely decouple senders and receivers, there is no direct reference to the relationship between the sender and the receiver, the object sends the request only need to know how to send requests without the need to know how to complete the request.

Command Mode 5 characters comprising:
(1) abstract class command the Command
(2) the specific command based ConcreteCommand
(. 3) caller Invoker
(. 4) receiver Receiver
(. 5) client class Client

Sample code:

#include <iostream>
#include "ConcreteCommand.h"
#include "Invoker.h"
#include "Receiver.h"

using namespace std;

int main(int argc, char *argv[])
{
	Receiver * pReceiver = new Receiver();   // 定义一个接收者
	ConcreteCommand * pCommand = new ConcreteCommand(pReceiver);  // 定义一个具体命令
	Invoker * pInvoker = new Invoker(pCommand);    //定义命令的调用者
	pInvoker->call();
	
	delete pReceiver;
	delete pCommand;
	delete pInvoker;
	return 0;
}
///////////////////////////////////////////////////////////
//  Receiver.h
//  Definition of the Class Receiver
///////////////////////////////////////////////////////////

#ifndef __RECEIVER_H__
#define __RECEIVER_H__

class Receiver
{

public:
	Receiver();
	virtual ~Receiver();

	void action();

};

#endif
///////////////////////////////////////////////////////////
//  Receiver.cpp
//  Implementation of the Class Receiver
///////////////////////////////////////////////////////////

#include "Receiver.h"
#include <iostream>
using namespace std;

Receiver::Receiver()
{

}

Receiver::~Receiver()
{

}

void Receiver::action()
{
	cout << "Receiver action." << endl;
}

///////////////////////////////////////////////////////////
//  ConcreteCommand.h
//  Definition of the Class ConcreteCommand
///////////////////////////////////////////////////////////

#ifndef __CONCRETE_COMMAND_H__
#define __CONCRETE_COMMAND_H__

#include "Command.h"
#include "Receiver.h"

class ConcreteCommand : public Command
{

public:
	ConcreteCommand(Receiver * pReceiver);
	virtual ~ConcreteCommand();
	virtual void execute();

private:
	Receiver *m_pReceiver;

};

#endif 
///////////////////////////////////////////////////////////
//  ConcreteCommand.cpp
//  Implementation of the Class ConcreteCommand
///////////////////////////////////////////////////////////

#include "ConcreteCommand.h"
#include <iostream>
using namespace std;

ConcreteCommand::ConcreteCommand(Receiver *pReceiver)
{
	m_pReceiver = pReceiver;
}

ConcreteCommand::~ConcreteCommand()
{

}

void ConcreteCommand::execute()
{
	cout << "ConcreteCommand::execute"  << endl;
	m_pReceiver->action();
}
///////////////////////////////////////////////////////////
//  Invoker.h
//  Definition of the Class Invoker
///////////////////////////////////////////////////////////

#ifndef __INVOKER_H__
#define __INVOKER_H__

#include "Command.h"

class Invoker
{

public:
	Invoker(Command * pCommand);
	virtual ~Invoker();
	void call();

private:
	Command *m_pCommand;


};

#endif 
///////////////////////////////////////////////////////////
//  Invoker.cpp
//  Implementation of the Class Invoker
///////////////////////////////////////////////////////////

#include "Invoker.h"
#include <iostream>
using namespace std;

Invoker::Invoker(Command * pCommand)
{
	m_pCommand = pCommand;
}

Invoker::~Invoker()
{

}

void Invoker::call()
{
	cout << "Invoker calling" << endl;
	m_pCommand->execute();
}

Command mode, the abstract class declaration command to execute a process execution request () and the like, can call recipient related operations requested by these methods; specific command class is a subclass of abstract class command, implements the abstract class Command declared method, which corresponds to a specific recipient object, wherein the binding operation of the recipient object; i.e. sender caller request, also called a requestor, which is performed by the request command object; performing (recipient ) performs operations associated with the request, it requests specific implementation of the business process.

The nature of the command mode command is encapsulated, responsibility and liability issues the command execution command separated. The command mode request itself as an object, this object and other objects as may be stored and transmitted. This mode can reduce the coupling system to facilitate the addition of new commands can be more easily implemented command queue and macros, and to achieve the request of undo and redo.

The first pass mode understand it would be more difficult abstract, multi-read it over twice and think you can be a good understanding of it. Imagine a TV and a remote control, the TV Receiver is the recipient (and performers) command, a remote control sender of this command, the specific command can be on, off, selecting a program, these commands can be abstracted to a unified command interface.

2. The intermediary model (Mediator Pattern)

Intermediary model with a different object to intermediary objects interact package, keeping objects explicitly referring to each other so as to achieve the purpose of loosely coupled.

Mediator pattern comprising four roles:
(1) abstract mediator Mediator
(2) the specific mediator ConcreteMediator
(. 3) abstract class colleagues the Colleague
(. 4) the specific class colleagues ConcreteColleague

Sample code:

#include <iostream>
#include "ConcreteColleagueA.h"
#include "ConcreteMediator.h"
#include "ConcreteColleagueB.h"

using namespace std;

int main(int argc, char *argv[])
{
	ConcreteColleagueA * pa = new ConcreteColleagueA();
	ConcreteColleagueB * pb = new ConcreteColleagueB();
	ConcreteMediator * pm = new ConcreteMediator();
	pm->registered(1,pa);
	pm->registered(2,pb);
	
	// sendmsg from a to b
	pa->sendmsg(2,"Hello, This is a.");
	// sendmsg from b to a
	pb->sendmsg(1,"Hello, This is b.");
	
	delete pa, pb, pm;
	
	return 0;
}
///////////////////////////////////////////////////////////
//  ConcreteMediator.h
//  Definition of the Class ConcreteMediator
///////////////////////////////////////////////////////////

#ifndef __CONCRETE_MEDIATOR_H__
#define __CONCRETE_MEDIATOR_H__

#include "ConcreteColleagueB.h"
#include "Mediator.h"
#include "ConcreteColleagueA.h"
#include <map>

using namespace std;

class ConcreteMediator : public Mediator
{

public:
	ConcreteMediator();
	virtual ~ConcreteMediator();

	virtual void operation(int nWho, string str);
	virtual void registered(int nWho, Colleague * aColleague);
	
private:
	map<int,Colleague*> m_mpColleague;
};

#endif 
///////////////////////////////////////////////////////////
//  ConcreteMediator.cpp
//  Implementation of the Class ConcreteMediator
///////////////////////////////////////////////////////////

#include "ConcreteMediator.h"
#include <map>
#include <iostream>
using namespace std;

ConcreteMediator::ConcreteMediator()
{

}

ConcreteMediator::~ConcreteMediator()
{

}

void ConcreteMediator::operation(int nWho, string str)
{
	map<int,Colleague*>::const_iterator itr = m_mpColleague.find(nWho);
	if(itr == m_mpColleague.end())
	{
		cout << "not found this colleague!" << endl;
		return;
	}
	
	Colleague* pc = itr->second;
	pc->receivemsg(str);
}


void ConcreteMediator::registered(int nWho, Colleague * aColleague)
{
	map<int,Colleague*>::const_iterator itr = m_mpColleague.find(nWho);
	if(itr == m_mpColleague.end())
	{
		//插入新的对象
		m_mpColleague.insert(make_pair(nWho, aColleague));
		
		//同时将中介类暴露给colleague 
		aColleague->setMediator(this);
	}
}
///////////////////////////////////////////////////////////
//  ConcreteColleagueA.h
//  Definition of the Class ConcreteColleagueA
///////////////////////////////////////////////////////////

#ifndef __CONCRETE_COLLEAGUE_A_H__
#define __CONCRETE_COLLEAGUE_A_H__

#include "Colleague.h"

class ConcreteColleagueA : public Colleague
{
public:
	ConcreteColleagueA();
	virtual ~ConcreteColleagueA();

	virtual void sendmsg(int toWho, string str);
	virtual void receivemsg(string str);

};

#endif 
///////////////////////////////////////////////////////////
//  ConcreteColleagueA.cpp
//  Implementation of the Class ConcreteColleagueA
///////////////////////////////////////////////////////////

#include "ConcreteColleagueA.h"
#include <iostream>

using namespace std;

ConcreteColleagueA::ConcreteColleagueA()
{
}

ConcreteColleagueA::~ConcreteColleagueA()
{
}

void ConcreteColleagueA::sendmsg(int toWho, string str)
{
	cout << "send msg from colleagueA,to:" << toWho << endl;
	
	m_pMediator->operation(toWho, str);
}

void ConcreteColleagueA::receivemsg(string str)
{
	cout << "ConcreteColleagueA reveivemsg:" << str <<endl;
}

Intermediary model, the abstraction is used to define a broker interface that is used for communication between the object and colleagues; Mediator is particularly subclasses of the abstract Mediator, cooperative behavior is achieved by coordinating various colleagues in the object, while maintaining it references the respective object co-workers; colleagues sharing method of each class defines the abstract colleagues; particularly colleagues colleagues abstract class is a subclass of the class, each object refers to a colleague intermediary object. Each colleague object-object communication requirements and other colleagues, to communicate with the first intermediary, indirectly through the intermediary communications complete class and other colleagues. Colleagues abstract class implements a method defined in the class specific colleague.

By introducing an intermediary object original system of peer to peer network structure is changed to intermediaries as the center of a star structure, to bear the transit agency and coordinating role. Mediator as the core, control and coordination of the entire system, which simplifies the interaction between objects, and can further control over the interaction between objects, such as rights management between the different levels of colleagues.

3. The observer pattern (Observer Pattern)

Observer pattern for one kind among many dependencies defining the object, such that whenever a state of the object changes, its associated dependent objects are notified and updated automatically. The observer pattern is also called publish / subscribe model (Publish / Subscribe Pattern), model / view mode (Model / View Pattern), source / listener mode (Source / Listener Pattern) or subordinates mode (Dependents Pattern).

Observer pattern comprising four characters, are:
(1) target the Subject
(2) Target ConcreteSubject
(. 3) the observer the Observer
(. 4) specific viewer ConcreteObserver

Sample code:

#include <iostream>
#include "Subject.h"
#include "Observer.h"
#include "ConcreteObserver.h"
#include "ConcreteSubject.h"

using namespace std;

int main(int argc, char *argv[])
{
	Subject * subject = new ConcreteSubject();
	Observer * objA = new ConcreteObserver("A");
	Observer * objB = new ConcreteObserver("B");
	subject->attach(objA);
	subject->attach(objB);
	
	subject->setState(1);
	subject->notify();
	
	subject->detach(objB);
	subject->setState(2);
	subject->notify();
	
	delete subject;
	delete objA;
	delete objB;
		
	return 0;
}

///////////////////////////////////////////////////////////
//  Subject.h
//  Definition of the Class Subject
///////////////////////////////////////////////////////////

#ifndef __SUBJECT_H__
#define __SUBJECT_H__

#include "Observer.h"
#include <vector>
using namespace std;

class Subject
{

public:
	Subject();
	virtual ~Subject();
	Observer *m_Obeserver;

	void attach(Observer * pObserver);
	void detach(Observer * pObserver);
	void notify();
		
	virtual int getState() = 0;
	virtual void setState(int i)= 0;
	
private:
	vector<Observer*> m_vtObj;

};

#endif 

///////////////////////////////////////////////////////////
//  Subject.cpp
//  Implementation of the Class Subject
///////////////////////////////////////////////////////////

#include "Subject.h"

Subject::Subject()
{

}

Subject::~Subject()
{

}

void Subject::attach(Observer * pObserver)
{
	m_vtObj.push_back(pObserver);
}

void Subject::detach(Observer * pObserver)
{
	vector<Observer*>::iterator itr;
	for(itr = m_vtObj.begin(); itr != m_vtObj.end(); itr++)
	{
		if(*itr == pObserver)
		{
			m_vtObj.erase(itr);
			return;
		}			
	}
}

void Subject::notify(){
	for(vector<Observer*>::iterator itr = m_vtObj.begin();
		itr != m_vtObj.end();
	 	itr++)
	{	
		(*itr)->update(this);		
	}
}
///////////////////////////////////////////////////////////
//  Observer.h
//  Definition of the Class Observer
///////////////////////////////////////////////////////////

#ifndef __OBSERVER_H__
#define __OBSERVER_H__

class Subject;

class Observer
{

public:
	Observer();
	virtual ~Observer();
	virtual void update(Subject * sub) = 0;
};

#endif 
///////////////////////////////////////////////////////////
//  ConcreteObserver.h
//  Definition of the Class ConcreteObserver
///////////////////////////////////////////////////////////

#ifndef __CONCRETE_OBSERVER_H__
#define __CONCRETE_OBSERVER_H__

#include "Obeserver.h"
#include <string>

using namespace std;

class ConcreteObserver : public Obeserver
{

public:
	ConcreteObserver(string name);
	virtual ~ConcreteObserver();
	virtual void update(Subject * sub);

private:
	string m_objName;
	int m_obeserverState;
};

#endif 

///////////////////////////////////////////////////////////
//  ConcreteObserver.cpp
//  Implementation of the Class ConcreteObserver
///////////////////////////////////////////////////////////

#include "ConcreteObserver.h"
#include <iostream>
#include <vector>
#include "Subject.h"
using namespace std;

ConcreteObserver::ConcreteObserver(string name)
{
	m_objName = name;
}

ConcreteObserver::~ConcreteObserver()
{

}

void ConcreteObserver::update(Subject * sub)
{
	m_obeserverState = sub->getState();
	cout << "update oberserver[" << m_objName << "] state:" << m_obeserverState << endl;
}

Results of the:

One kind of an object is defined between the observer model many dependencies, so that every time an object state changes, its associated dependent objects are notified and updated. Observer separation mode may represent a logical layer and data layer, and create an abstract coupled between the observer and the observation target, to support broadcast communication.

4. Status Mode (State Pattern)

State pattern allows an object to change its behavior when its internal state is changed, the object will appear to change its class.

State pattern comprising three roles:
(1) Environmental the Context
(2) state abstract class State
(. 3) specifically state classes ConcreteState

Sample code:

#include <iostream>
#include "Context.h"
#include "ConcreteStateA.h"
#include "ConcreteStateB.h"

using namespace std;

int main(int argc, char *argv[])
{
	Context * c = new Context();
	c->request();
	c->request();
	c->request();

	delete c;
	return 0;
}
///////////////////////////////////////////////////////////
//  Context.h
//  Definition of the Class Context
///////////////////////////////////////////////////////////

#ifndef __CONTEXT_H__
#define __CONTEXT_H__

#include "State.h"

class Context
{

public:
	Context();
	virtual ~Context();

	void changeState(State * st);
	void request();

private:
	State *m_pState;
};

#endif 

///////////////////////////////////////////////////////////
//  Context.cpp
//  Implementation of the Class Context
///////////////////////////////////////////////////////////

#include "Context.h"
#include "ConcreteStateA.h"

Context::Context()
{
	//default is A
	m_pState = ConcreteStateA::Instance();
}

Context::~Context()
{
}

void Context::changeState(State * st)
{
	m_pState = st;
}

void Context::request()
{
	m_pState->handle(this);
}
///////////////////////////////////////////////////////////
//  ConcreteStateA.h
//  Definition of the Class ConcreteStateA
///////////////////////////////////////////////////////////

#ifndef __CONCRETE_STATEA_H__
#define __CONCRETE_STATEA_H__

#include "State.h"

class ConcreteStateA : public State
{

public:
	virtual ~ConcreteStateA();
	
	static State * Instance();
	
	void handle(Context * c);

private:
	ConcreteStateA();
	static State * m_pState;
};

#endif 
///////////////////////////////////////////////////////////
//  ConcreteStateA.cpp
//  Implementation of the Class ConcreteStateA
///////////////////////////////////////////////////////////

#include "ConcreteStateA.h"
#include "ConcreteStateB.h"
#include "Context.h"
#include <iostream>

using namespace std;

State * ConcreteStateA::m_pState = NULL;

ConcreteStateA::ConcreteStateA()
{
}

ConcreteStateA::~ConcreteStateA()
{
}

State * ConcreteStateA::Instance()
{
	if(NULL == m_pState)
	{
		m_pState = new ConcreteStateA();
	}
	
	return m_pState;
}

void ConcreteStateA::handle(Context * c)
{
	cout << "Doing something in State A.\n Done, change state to B" << endl;
	c->changeState(ConcreteStateB::Instance());
}

Results of the:

In the three character status mode, also known as Environmental context class, the object has a state, with the state class in the instance of a class in the environment, this example defines the current state, In specific implementation, it is a Object state subclass can be defined initial state. Abstract class defines an interface state, associated with a particular state to encapsulate the behavior of the environment class. Specific subclasses of the abstract class is the state of the status category, each sub-class implements a class associated with a state of the environment of the behavior, each state of a particular class corresponds to a particular state of the environment, the different behavior of different concrete classes state.

5. Strategy Mode (Strategy Pattern)

Strategy mode is also called the policy mode (Policy Pattern), the definition of a series of algorithms, each algorithm will be packaged together, and make them interchangeable. Strategy mode lets users independently of their algorithm changes.

Strategy Mode roles:

(1) Environmental Context

(2) an abstract strategy class Strategy

(3) specific policy class ConcreteStrategy

Sample code:

#include <iostream>
#include "Context.h"
#include "ConcreteStrategyA.h"
#include "ConcreteStrategyB.h"
#include "Strategy.h"
#include <vector>

using namespace std;

int main(int argc, char *argv[])
{
	Strategy * s1 = new ConcreteStrategyA();
	Context * cxt = new Context();
	cxt->setStrategy(s1);
	cxt->algorithm();

	Strategy *s2 = new ConcreteStrategyB();
	cxt->setStrategy(s2);
	cxt->algorithm();
	
	delete s1;
	delete s2;
		
	return 0;
}

///////////////////////////////////////////////////////////
//  Context.h
//  definition of the Class Context
///////////////////////////////////////////////////////////

#ifndef __CONTEXT_H__
#define __CONTEXT_H__

#include "Strategy.h"

class Context
{

public:
	Context();
	virtual ~Context();
	

	void algorithm();
	void setStrategy(Strategy* st);
	
private:
	Strategy *m_pStrategy;

};

#endif 
///////////////////////////////////////////////////////////
//  Context.cpp
//  Implementation of the Class Context
///////////////////////////////////////////////////////////

#include "Context.h"

Context::Context()
{
}

Context::~Context()
{
}

void Context::algorithm()
{
	m_pStrategy->algorithm();
}

void Context::setStrategy(Strategy* st)
{
	m_pStrategy = st;
}
///////////////////////////////////////////////////////////
//  ConcreteStrategyA.h
//  Definition of the Class ConcreteStrategyA
///////////////////////////////////////////////////////////

#ifndef __CONCRETE_STRATEGY_H__
#define __CONCRETE_STRATEGY_H__

#include "Strategy.h"

class ConcreteStrategyA : public Strategy
{

public:
	ConcreteStrategyA();
	virtual ~ConcreteStrategyA();

	void algorithm();

};

#endif

///////////////////////////////////////////////////////////
//  ConcreteStrategyA.cpp
//  Implementation of the Class ConcreteStrategyA
///////////////////////////////////////////////////////////

#include "ConcreteStrategyA.h"
#include <iostream>

using namespace std;

ConcreteStrategyA::ConcreteStrategyA()
{

}

ConcreteStrategyA::~ConcreteStrategyA()
{

}

void ConcreteStrategyA::algorithm()
{
	cout << "use algorithm A" << endl;
}

Results of the:

In more than a few characters, the environment in the class can solve a problem using a variety of strategies to maintain a reference to an instance of an abstract class in the policy environment classes; abstract strategy class declares an abstract method for the algorithm supported, all strategy of the base class. Specific strategy class implements the algorithm defined in the abstract strategy class.

Strategy Mode can well support "the principle of opening and closing," on the basis of the existing system without modifying the algorithm can replace or add new algorithms.

 

Reference: https://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html

Published 58 original articles · won praise 61 · views 130 000 +

Guess you like

Origin blog.csdn.net/DeliaPu/article/details/104718487