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

一、解释器(Interpreter)

1、引言

该模式一般用于为某种简单的特定类型的问题(如简单语言)提供一种文法,使用类来解释当中的每一条规则。

给出几种典型应用场合:正则表达式的解释与匹配、布尔表达式的操作、计算24的实例(http://www.cnblogs.com/mahope/archive/2005/05/04/149246.html)、XML格式数据解析、从大写汉字“一千零五万六千零七十二”到数字“10056072”的转换实例(http://www.cnblogs.com/MaoBisheng/archive/2008/09/08/1287014.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、典型代码

参考:http://www.cnblogs.com/ywqu/archive/2010/02/09/1666196.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。

本节实例采用第一种方式。第二种方式待学…



















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值