前の二つの記事は、スキーマとスキーマ構造を作成するためのデザインパターンの三つのカテゴリーにまとめました。
今日は、私たちは最後の部分、行動パターンを整理しましょう。
まず、行動パターンは何ですか?
行動パターン(行動パターン)は異なるアルゴリズム間の責任の分割を意味し、それは、クラスとオブジェクトの構造を懸念だけでなく、それらの間の相互作用に焦点を当てるだけでなく、抽象的なデザインパターンオブジェクト。
システムの場合、オブジェクトは単独運転ではない、いくつかの複雑な機能は、オブジェクト、オブジェクト間の相互の影響との間の相互通信および連携を介して達成することができます。
行動パターンは、カテゴリの行動パターンとオブジェクトの行動パターンに分けられています。クラスの行動パターンはいくつかのクラス、マルチステートクラスを通じて責任の父と息子の主分布、などの間で分配行動に継承を使用します.. オブジェクトの行動パターンは、重合関連オブジェクトによって割り当て責任にあります。ほとんどの行動デザインパターンは、すべてのオブジェクトの行動のデザインパターンです。
デューティチェーン(Chain of Responsibilityパターン)、コマンドモード(コマンドパターン)、インタプリタモード(インタープリタパターン)、イテレータ(イテレータパターン)、仲介モデル:すなわち、特定の設計パターン、11種類を含む行動パターン(Mediatorパターン)、メモモード(Mementoパターン)、観察モード(観察パターン)、状態モード(状態パターン)、戦略モード(ストラテジパターン)、テンプレートメソッドパターン(テンプレートメソッドパターン)、ビジターパターン(Visitorパターン) 。
私たちは、紹介する5種類のいずれかを選択しました。
1.モードコマンド(Commandパターン)
また、コマンドモード動作モード(行動パターン)またはトランザクション・モード(トランザクションパターン)として知られています。このモードでは、要求は、クライアントの要求は、異なるパラメータを使用してその結果、オブジェクトにカプセル化された、または要求ログをキュー、およびサポート操作を取り消すことができるされています。
完全にデカップル送信者と受信者は、送信者と受信者の間の関係には直接の言及はありません可能なコマンドモードは、オブジェクトは要求を完了する方法を知らなくてもリクエストを送信する方法を知っておく必要があり、要求を送信します。
コマンドモードを含む5つの文字:
(1)抽象クラスコマンドコマンド
(2)ConcreteCommand基づいて、特定のコマンド
(3)起動側発信者
(4)受信機の受信機
(5)クライアントクラスクライアント
サンプルコード:
#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();
}
コマンドモードは、抽象クラス宣言コマンドは、これらの方法によって要求された受信者関連の操作を呼び出すことができ、処理の実行要求()等を実行するために、特定のコマンドのクラスは抽象クラスコマンドのサブクラスであり、実装する抽象クラスコマンド実行(受信者、また、要求コマンド・オブジェクトによって実行され、リクエスタと呼ばれる、すなわち送信者、発信者要求、特定の受信者オブジェクト、受信者オブジェクトの前記結合動作に対応する宣言されたメソッド、要求に関連する)動作を行うには、ビジネス・プロセスの特定の実装を要求します。
コマンドモードコマンドの性質がカプセル化され、責任と義務の問題は、コマンド実行コマンドを分離しました。コマンドモードは、格納されて送信されてもよい。このオブジェクトと他のオブジェクトとして、オブジェクトとしての地位を要求します。このモードでは、新しいコマンドの追加がより簡単にコマンドキューとマクロを実装することができ容易にするためのカップリングシステムを減らすことができ、そしてアンドゥやリドゥの要求を達成するために。
最初のパスモードでは、それを2回以上のマルチ読み、あなたがそれをよく理解することができると思い、抽象より難しいだろう理解しています。テレビとリモコンを想像してみて、テレビ受像機は、受信者(出演者)であるコマンドは、このコマンドのリモコン送信機、特定のコマンドは、プログラムを選択し、オフ、にすることができ、これらのコマンドは、に抽象化することができます統一されたコマンド・インタフェース。
2.仲介モデル(Mediatorパターン)
パッケージ相互作用仲介オブジェクトに異なるオブジェクトと仲介モデル、疎結合の目的を達成するために互いにそうに言及明示的にオブジェクトを維持します。
メディエーター4つのロールを含むパターン:
(1)抽象メディエーターメディエーター
(2)特定のメディエーターConcreteMediator
抽象クラスの同僚同僚(3)
特定のクラスの同僚ConcreteColleague(4)。
サンプルコード:
#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;
}
仲介モデルは、抽象オブジェクトと同僚との間の通信のために使用されるブローカインタフェースを定義するために使用され、メディエータは、特にある抽象メディエーターのサブクラスに維持しながら、協調動作は、オブジェクトの様々な同僚を調整することによって達成されます。それは、各オブジェクトの同僚を参照し、各クラスのメソッドを共有同僚は抽象同僚を定義し、特に同僚の同僚抽象クラスクラスのサブクラスであり、各オブジェクトは、同僚仲介オブジェクトを指します。各同僚オブジェクト対象通信要件及び他の同僚は、間接的に仲介通信完全なクラスおよび他の同僚を介して、第一の中間と通信します。同僚抽象クラスは、クラスの特定の同僚で定義されたメソッドを実装します。
ピアネットワーク構造へのピアの仲介オブジェクト元のシステムを導入することにより、交通機関と調整の役割を担うように、星型構造の中心として媒体に変更されます。オブジェクト間の相互作用を簡素化し、さらに、そのような同僚の異なるレベルの間で著作権管理などのオブジェクト間の相互作用を制御することができ、システム全体のコア、制御及び調整としてメディエータ。
前記オブザーバーパターン(Observerパターン)
たびに、オブジェクトの状態が変化するが、それに関連付けられた従属オブジェクトが通知され、自動的に更新されるようにオブジェクトを定義する多くの依存関係のうちの1種類のオブザーバーパターン。Observerパターンは、モデル(パターンパブリッシュ/サブスクライブ)、モデル/ビューモード(モデル/ビューパターン)、ソース/リスナーモード(ソース/リスナーパターン)や部下モード(扶養パターン)をパブリッシュ/サブスクライブと呼ばれています。
4つの文字を含むオブザーバーパターンである:
(1)テーマターゲット
(2)目標ConcreteSubject
(3)観察者の観察者を
(4)ConcreteObserverビューア特定
サンプルコード:
#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;
}
結果:
オブジェクトの一種は、オブザーバモデルの多くの依存関係の間で定義されるので、オブジェクトの状態を変更するたびに、それに関連する依存オブジェクトが通知され、更新されていること。オブザーバ分離モードでは、論理層とデータ層を表し、観察者と観察対象物との間に結合された要約を作成し、ブロードキャスト通信をサポートすることができます。
4.ステータスモード(状態パターン)
その内部状態が変更されたときの状態パターンは、オブジェクトがその動作を変更することができ、オブジェクトは、そのクラスを変更することが表示されます。
3つの役割を含む、状態パターン:
(1)環境のコンテキスト
(2)状態抽象クラスの状態
、具体的状態クラスConcreteState(3)。
サンプルコード:
#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());
}
結果:
また、環境コンテキストクラスとして知られている3文字のステータスモードで、オブジェクトは、環境内のクラスのインスタンスの状態クラスと、この例では、現在の状態は、特定の実装では、それが定義され、状態を有しますオブジェクト状態サブクラスは、初期状態を定義することができます。抽象クラスは、環境クラスの挙動をカプセル化するために特定の状態と関連するインターフェースの状態を定義します。抽象クラスの特定のサブクラス挙動の環境の状態に関連付けられたクラス、環境の特定の状態に特定のクラス対応の各状態、異なる具象クラス状態の異なる挙動各サブクラスが実装、ステータスカテゴリの状態です。
5.戦略モード(Strategyパターン)
戦略モードは、ポリシーモード(ポリシー・パターン)と呼ばれる、一連のアルゴリズムの定義は、各アルゴリズムは、一緒に包装し、それらを交換可能にすることになります。戦略モードでは、独立して自分のアルゴリズムの変更のユーザーをすることができます。
戦略モードの役割:
(1)環境的文脈
(2)抽象戦略クラス戦略
(3)特定のポリシークラスConcreteStrategy
サンプルコード:
#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;
}
結果:
数文字以上では、クラス内の環境は、政策環境のクラスで抽象クラスのインスタンスへの参照を維持するために様々な戦略を使用して問題を解決することができ、抽象戦略クラスは、サポートされているアルゴリズムのための抽象メソッドを宣言し、すべての基底クラスの戦略。具体的な戦略のクラスが実装抽象戦略クラスで定義されたアルゴリズム。
戦略モードはよく交換したり、新しいアルゴリズムを追加することができ、アルゴリズムを変更することなく、既存のシステムに基づいて、「開閉、の原則」をサポートすることができます。
参考:https://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html