23种设计模式汇总行为型模式职责链模式.docx
《23种设计模式汇总行为型模式职责链模式.docx》由会员分享,可在线阅读,更多相关《23种设计模式汇总行为型模式职责链模式.docx(17页珍藏版)》请在冰豆网上搜索。
![23种设计模式汇总行为型模式职责链模式.docx](https://file1.bdocx.com/fileroot1/2022-10/29/b56d35fb-12a7-465c-9b96-928af2b6bd72/b56d35fb-12a7-465c-9b96-928af2b6bd721.gif)
23种设计模式汇总行为型模式职责链模式
职责链模式
意图
是对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。
将这些对象连成一条链,并沿着这条链传递请求,直道一个对象处理它为止。
使用场合
1.有多个对象可以处理一个请求,那个对象处理该请求在运行的时候自动确定。
2.希望在不明确制定接收者的情况下,向多个对象中的一个提交一个请求。
3.可处理一个请求的对象集合应被动态的指定。
例如:
1.过滤器:
处理或拦截信息,不同的过滤器可以过滤不同的类型的信息,过滤器可以组成职责链模式。
2.时间处理器:
不同事件可以有不同的事件处理器,时间处理器组成职责链。
然后用户可以不关心事件的类型,交给职责链处理即可。
3.异常处理器:
不同的异常处理器对应不同的异常。
4.文法分析器:
对给定的Tekon进行文法分析,通过扩充职责链扩充文法分析器的功能。
5.分段计算:
职责链上的对象在符合条件时进行计算,这样可以去掉switch语句。
结构
1.Handler:
定一个处理请求的接口并实现后续链。
2.ConcreteHandler:
处理负责的请求并可访问后继者。
如果可以处理该请求,则处理之;否则将该请求转发给后继者。
3.向链上的具体处理对象提交请求。
职责链模式构成与执行效率
有些情况下,职责链中各对象完成的任务没有包含性,如在文法分析其中各种Tekon是平行关系。
这时,职责链中对象的顺序对执行结果没有影响。
然而由于职责链是串行的德,链中的前一个对象无法完成任务i就交给后一个对象完成。
因此职责链中对象的顺序组织方式不同,会大大影响程序的执行效率。
在组织职责链对象的顺序时,应将较常用的对象放置在链的前端。
结果
使用职责链降低了请求与响应的耦合性,职责链的顺序可以有用户来决定。
采用职责链的不足如果没有适合处理请求的对象,请求将对不到处理。
文法分析器——四则运算式解析
这里我们的目的是将普通中则表达式转化为后则表达式。
方案:
四则运算式涉及到4种Tekon,即参与运算的数字、运算符(+-*/以及将来肯能扩充的运算符)、左括号 ( 和右括号 ) 。
为了方便字符串分割,这里将字符串的格式规定为数值和运算符、运算符与运算符之间都用空格隔开。
例如"(_2_+_3_)_/_3"
采用ArrayList模拟堆栈
Stack.cs
usingSystem;
usingSystem.Collections;
usingSystem.Text;
namespaceChainofResposibility.EX24_3
{
/**////
///Stact采用ArrayList模拟堆栈
///
classAStack
{
privateArrayListmyStact;
publicintCount
{
get{returnmyStact.Count;}
}
publicAStack()
{
myStact=newArrayList();
}
publicvoidPush(Objecto)
{
myStact.Add(o);
}
publicObjectPop()
{
intidx=myStact.Count-1;
if(idx<0)
{
thrownewException("堆栈已空");
}
objecto=myStact[idx];
myStact.RemoveAt(idx);
returno;
}
publicObjectPop2()
{
if(myStact.Count==0)
{
thrownewException("堆栈已空");
}
objecto=myStact[0];
myStact.RemoveAt(0);
returno;
}
publicboolIsEmpty()
{
return(myStact.Count==0);
}
publicobjectTopItem()
{
intidx=myStact.Count-1;
if(idx<0)
{
thrownewException("堆栈已空");
}
objecto=myStact[idx];
returno;
}
}
}
处理四则表达式中token的基础类
TreatToken.cs
usingSystem;
usingSystem.Collections;
usingSystem.Text;
namespaceChainofResposibility.EX24_3
{
/**////
///TreatToken处理四则表达式中token的基础类
///
abstractclassTreatToken
{
//用来处理token的临时堆栈
protectedAStackst;
//用来保存结果的堆栈
protectedAStackstOutput;
//Next构成职责链
protectedTreatToken_next;
publicTreatTokenNext
{
get{return_next;}
set{_next=value;}
}
publicTreatToken(AStackst,AStackstout)
{
this.st=st;
this.stOutput=stout;
}
publicabstractvoidTreat(strings);
}
}
在这个抽象类中定义了职责链的关系、处理过程中需要用到的堆栈和处理接口。
本例有两个Tekon需要处理,即数字和运算符,因为分别对应处理这两种类型的子类:
NumberToken.cs
usingSystem;
usingSystem.Collections;
usingSystem.Text;
usingCommonFrameworkWBs.ValidateTool;
namespaceChainofResposibility.EX24_3
{
/**////
///NumberToken处理数字
///
classNumberToken:
TreatToken
{
publicNumberToken(AStackst,AStackstout)
:
base(st,stout)
{
}
publicoverridevoidTreat(strings)
{
ValidateNumbervn=newValidateNumber();
if(vn.IsNumber(s))
{
this.stOutput.Push(s);
}
else
{
this.Next.Treat(s);
}
}
}
}
处理数字的部分很简单,只要将数字如栈即可。
应为后则表达式通过运算符的顺序控制计算,所以参与运算的数字顺序不变。
处理运算符的代码:
OperatorToken.cs
usingSystem;
usingSystem.Collections;
usingSystem.Text;
namespaceChainofResposibility.EX24_3
{
/**////
///OperatorToken处理操作符+-*/()等
///
classOperatorToken:
TreatToken
{
privateMyOperatoerope;
publicOperatorToken(AStackst,AStackstout,MyOperatoerop)
:
base(st,stout)
{
this.ope=op;
}
publicoverridevoidTreat(strings)
{
if(s==ope.OP)
{
if(st.IsEmpty()||s=="(")
{
st.Push(ope);
}
else
{
MyOperatoero=(MyOperatoer)st.TopItem();
while(o.Level>=ope.Level||ope.OP==")")
{
MyOperatoero1=(MyOperatoer)st.Pop();
if(o1.OP=="(")
{
break;
}
this.stOutput.Push(o1);
if(st.IsEmpty())
{
break;
}
o=(MyOperatoer)st.TopItem();
}
if(ope.OP!
=")")
{
st.Push(ope);
}
}
}
else
{
this.Next.Treat(s);
}
}
}
}
处理未知的运算符的类:
OtherToken.cs
usingSystem;
usingSystem.Collections;
usingSystem.Text;
namespaceChainofResposibility.EX24_3
{
classOtherToken:
TreatToken
{
publicOtherToken()
:
base(null,null)
{
}
publicoverridevoidTreat(strings)
{
if(s!
="")
{
thrownewException("无法识别的操作符"+s);
}
}
}
}
负责将组装职责链并完成计算:
Parser.cs
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceChainofResposibility.EX24_3
{
/**////
///Parser采用职责链将四则元算转化为后表达式
///
classParser
{
AStacksttemp=newAStack();
AStackstoutput=newAStack();
TreatTokentk;
publicParser()
{
NumberTokennt=newNumberToken(sttemp,stoutput);
OperatorTokenop1=newOperatorToken(sttemp,stoutput,newMyOperatoer("+",11));
OperatorTokenop2=newOperatorToken(sttemp,stoutput,newMyOperatoer("-",11));
OperatorTokenop3=newOperatorToken(