您的位置:首页 > 其它

“设计模式”学习之七:解释器与中介者(行为型)

2011-08-29 00:05 567 查看
一、解释器(Interpreter)
1、引言
该模式一般用于为某种简单的特定类型的问题(如简单语言)提供一种文法,使用类来解释当中的每一条规则。

给出几种典型应用场合:正则表达式的解释与匹配、布尔表达式的操作、计算24的实例(/article/7021463.html)、XML格式数据解析、从大写汉字“一千零五万六千零七十二”到数字“10056072”的转换实例(/article/7027337.html)等等。

可见,解释器模式应用于:较简单的文法(若复杂,则需要语法分析程序生成器);各文法规则明确独立、易于扩展;效率不是最关键因素的情况。

2、一般思路
下图,上下文Context会包含解释器之外的全局信息。非终结符类NonterminalExpression会递归调用终结符类TerminalExpression。客户需自行构建抽象语法树——表示某表达式,并调用解释操作Interpreter()。



3、典型代码
基本程序代码参见《设计模式精解-GoF 23种设计模式解析附C++实现源码》即可,暂时空缺其它应用实例,待补…

4、应用提示
(1)Interpreter模式提供了一种很好的组织和设计简单语言文法解析器的架构
(2)Interpreter模式的缺点在于,不适于构建复杂文法的解释器。
(3)抽象语法树是一个Composite模式的实例。
(4)终结符类TerminalExpression的实例可应用Flyweight模式在抽象语法树中共享。
(5)不一定要在结点类中定义解释操作Interpreter(),可应用Visitor模式将解释放入一个独立的“访问者”类,以避免在每个结点类都定义需要的几种独立的解释操作。

二、中介者(Mediator)
1、引言
面向对象设计鼓励将行为分布到各个对象中。中介者模式通过将各个对象间的交互封装到一个中介者对象中,从而将多对多的通信转变为一对多,降低系统复杂性,这符合OO设计中的职责单一集中的原则。

2、一般思路
下图,中介者Mediator/ConcreteMediator负责与同事类的对象进行通信,而具体同事ConcreteColleagueA/B无需彼此引用,只需知道中介者即可,其接口函数易于扩展。
定义抽象类Mediator是为了使各个ConcreteColleague能够与不同的中介者共同工作,当仅有唯一一个中介者时,无需定义Mediator。



3、典型代码
参考:/article/4754255.html,实现一个简易聊天功能,聊城室就是一个中介者,参与聊天的人就是同事对象。
// "Mediator_Chatroom.h":头文件//////////////////////////

#ifndef _MEDIATOR_CHATROOM_H_
#define _MEDIATOR_CHATROOM_H_

#include <vector>
#include <iostream>
#include <conio.h>
#include <string>
using namespace std;

class AbstractColleague;

class MediatorChatroom
{
private:
vector <AbstractColleague *> vecColleague;

public:
MediatorChatroom(){}
~MediatorChatroom(){}

void Register(AbstractColleague *talker);
void Send(string from, string to, string message);
};

class AbstractColleague
{
public:
AbstractColleague(MediatorChatroom * chatroom, string strColleagueValue)
{
this->_chatroom = chatroom;
this->_strColleagueValue = strColleagueValue;
}
virtual ~AbstractColleague(){}

virtual void Receive(string from,string message)
{
cout<<"<"<<from<<"> to <"<<_strColleagueValue<<">:  "<<message<<endl;
}

public:
MediatorChatroom *  _chatroom;
string _strColleagueValue;

void Send(string to, string message)
{
_chatroom->Send(_strColleagueValue, to, message);
}
};

class ColleagueINer : public AbstractColleague
{
public:
ColleagueINer(MediatorChatroom * chatroom, string strColleagueValue)
:AbstractColleague(chatroom, strColleagueValue){}
~ColleagueINer(){}

void Receive(string from,string message)
{
cout<<"To one INer:";
AbstractColleague::Receive(from, message);
}
};

class ColleagueOUTer : public AbstractColleague
{
public:
ColleagueOUTer(MediatorChatroom * chatroom, string strColleagueValue)
:AbstractColleague(chatroom, strColleagueValue){}
~ColleagueOUTer(){}

void Receive(string from,string message)
{
cout<<"To one OUTer:";
AbstractColleague::Receive(from, message);
}
};

#endif //~_MEDIATOR_CHATROOM_H_

// Mediator_Chatroom.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "Mediator_Chatroom.h"

void MediatorChatroom::Register(AbstractColleague *talker)
{
//引入迭代器实现按顺序访问池中的各参与者对象
vector <AbstractColleague *>:: iterator it = vecColleague.begin();
//	AbstractColleague * talkerTemp;
if (vecColleague.size() == 0)//当容器内无任何对象时,先push一个对象
{
//		flyTemp = new ConcreteFlyweight(key);
vecColleague.push_back(talker);
return;
}
for (; it != vecColleague.end(); it++)//遍历对象
{
string tem = talker->_strColleagueValue;
if ((*it)->_strColleagueValue == talker->_strColleagueValue)//若存在,则返回。
{
cout<<"Check <"<<talker->_strColleagueValue<<">:Ensure it used only once..."<<endl;
return;
}
//	flyTemp = new ConcreteFlyweight(key);
vecColleague.push_back(talker);
return;
//	return flyTemp;
}
}//

void MediatorChatroom::Send(string from, string to, string message)
{
vector <AbstractColleague *>:: iterator it = vecColleague.begin();
for (; it != vecColleague.end(); it++)//遍历对象
{
if ((*it)->_strColleagueValue == to)//若接收存在,则让其接收信息。
{
(*it)-> Receive(from, message);
return;
//	cout<<"Check <"<<talker->_strColleagueValue<<">:Ensure it used only once..."<<endl;
}
else
{
//			cout<<"<"<<to<<">:doesn't existed!"<<endl;
//			return;
}
//	flyTemp = new ConcreteFlyweight(key);
//	vecColleague.push_back(talker);
//	return flyTemp;
}
}

int _tmain(int argc, _TCHAR* argv[])
{
MediatorChatroom *chatroom = new MediatorChatroom;

AbstractColleague *LiLei = new ColleagueINer(chatroom, "LiLei");
AbstractColleague *HanMeimei = new ColleagueINer(chatroom, "HanMeimei");
AbstractColleague *Poly = new ColleagueINer(chatroom, "Poly");

AbstractColleague *SongJiang = new ColleagueOUTer(chatroom, "SongJiang");

chatroom->Register(LiLei);
chatroom->Register(HanMeimei);
chatroom->Register(Poly);

chatroom->Register(SongJiang);

LiLei->Send("HanMeimei", "Long time no see!");
HanMeimei->Send("LiLei", "Yepp!");
LiLei->Send("HanMeimei", "What is up? I miss U...");
HanMeimei->Send("LiLei", "Not so bad, Me2");
Poly->Send("HanMeimei", "Don't forget me!");
HanMeimei->Send("Poly", "Sorry,Bird");

LiLei->Send("SongJiang", "《Water Margin》,nice! ");

_getch();/*等待按键继续*/
return 0;
}


运行情况截图如下:



4、应用提示
Mediator模式Colleague—Mediator之间的通信有两种方式:
一是,Colleague将自身(或其标志性成员变量)作为一个参数传递给Mediator,使其可以识别发送者;
二是,使用观察者Observer模式,将Mediator实现为一个Observer,各个Colleague作为Subject,一旦其状态改变就通知Mediator,再由Mediator将状态通知其它colleague。
本节实例采用第一种方式。第二种方式待学…


















                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐