本篇博客我们说的是行为型模式,其中包括以下一种模式:观察者模式、模板方法模式、命令模式、状态模式、职责链模式、解释器模式、中介者模式、访问者模式、策略模式、备忘录模式、迭代器模式。
13.管擦者模式
定义了一种一对多的依赖关系,让多个观察者对象同时监听某个主题对象。这个主题对象在状态发生变化时,会通知所有观察者,使他们能够自动更新自己。委托是一种很好的观察者模式。(举个例子:在Adidas厂商生产出来了一款新的衣服,所有的连锁店(观察者)都会得到通知)
UML图:
代码:
class="language-csharp">namespace 观察者模式
{
class Class2
{
static void Main(class="tags" href="/tags/STRING.html" title=string>string[] args)
{
Boss huhansan = new Boss();
StockObserver2 tongshi1 = new StockObserver2("为贯彻",huhansan );
NBAObserver2 tongshi2 = new NBAObserver2("以观察",huhansan );
huhansan.Attach(tongshi1 );
huhansan.Attach(tongshi2);
huhansan.Detach(tongshi1 );
huhansan.SubjectState = "老板我回来了";
huhansan.Notify();
}
}
interface Subject //通知者接口
{
void Attach(Observer2 observer);
void Detach(Observer2 observer);
void Notify();
class="tags" href="/tags/STRING.html" title=string>string SubjectState
{
get;
set;
}
}
class Boss : Subject //老板类
{
private IList<Observer2> observers = new List<Observer2>();
private class="tags" href="/tags/STRING.html" title=string>string action;
public void Attach(Observer2 observer)
{
observers.Add(observer );
}
public void Detach(Observer2 observer)
{
observers.Remove(observer);
}
public void Notify()
{
foreach (Observer2 o in observers)
o.Update();
}
public class="tags" href="/tags/STRING.html" title=string>string SubjectState
{
get
{
return action;
}
set
{
action = value;
}
}
}
class Secretary2 : Subject //老板类
{
private IList<Observer2> observers = new List<Observer2>();
private class="tags" href="/tags/STRING.html" title=string>string action;
public void Attach(Observer2 observer)
{
observers.Add(observer);
}
public void Detach(Observer2 observer)
{
observers.Remove(observer);
}
public void Notify()
{
foreach (Observer2 o in observers)
o.Update();
}
public class="tags" href="/tags/STRING.html" title=string>string SubjectState
{
get
{
return action;
}
set
{
action = value;
}
}
}
abstract class Observer2 //抽象观察者
{
protected class="tags" href="/tags/STRING.html" title=string>string name;
protected Subject sub;
public Observer2(class="tags" href="/tags/STRING.html" title=string>string name, Subject sub)
{
this.name = name;
this.sub = sub;
}
public abstract void Update();
}
class StockObserver2 : Observer2
{
public StockObserver2(class="tags" href="/tags/STRING.html" title=string>string name, Subject sub)
: base(name, sub)
{ }
public override void Update()
{
Console.WriteLine("{0}{1}关闭股票行情,继续工作!",sub.SubjectState ,name );
}
}
class NBAObserver2 : Observer2
{
public NBAObserver2(class="tags" href="/tags/STRING.html" title=string>string name, Subject sub)
: base(name, sub)
{ }
public override void Update()
{
Console.WriteLine("{0}{1}关闭NBA直播,继续工作!", sub.SubjectState, name);
}
}
}
14. 模板方法模式
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重新定义算法的某些特定步骤。将不变的行为搬到超类中,去除子类中的重复代码来体现他的优势,提供了一个很好的代码复用平台(举个例子:学生考试有考试卷作为模板,之后通过不同的学生添加不同的答案得到不同的分数形成具体的类)
UML图:
![](http://hi.csdn.net/attachment/201109/17/0_13162250956367.gif)
代码:
class="language-csharp">//10.3 把容易改变的设置为虚方法
namespace 模板方法模式
{
class Class2
{
static void Main(class="tags" href="/tags/STRING.html" title=string>string[] args)
{
TestPaper2 studentA = new TestPaperA2();
studentA.TestQuestion1();
studentA.TestQuestion2();
studentA.TestQuestion3();
}
}
class TestPaper2
{
public void TestQuestion1()
{
Console.WriteLine("杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是【】a.球墨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维");
Console.WriteLine("答案是:" + Answer1()); //使用虚方法
}
public virtual class="tags" href="/tags/STRING.html" title=string>string Answer1() //添加一个虚方法,子类来实现这个虚方法
{
return "";
}
public void TestQuestion2()
{
Console.WriteLine("杨过、程英、陆无双铲除了青花,造成【】 a.使这种植物不再伤害人 b. 使一种珍惜物种灭绝 c.破坏了生物圈的生态平衡 d.造成该地区沙漠化");
Console.WriteLine("答案是:" + Answer2()); //使用虚方法
}
public virtual class="tags" href="/tags/STRING.html" title=string>string Answer2() //添加一个虚方法,子类来实现这个虚方法
{
return "";
}
public void TestQuestion3()
{
Console.WriteLine("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药【】 a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的牛奶 e.以上全不对");
Console.WriteLine("答案是:" + Answer3()); //使用虚方法
}
public virtual class="tags" href="/tags/STRING.html" title=string>string Answer3() //添加一个虚方法,子类来实现这个虚方法
{
return "";
}
}
class TestPaperA2 : TestPaper2 //学生甲抄的试卷
{
public override class="tags" href="/tags/STRING.html" title=string>string Answer1()
{
return "b";
}
public override class="tags" href="/tags/STRING.html" title=string>string Answer2()
{
return "b";
}
public override class="tags" href="/tags/STRING.html" title=string>string Answer3()
{
return "b";
}
}
class TestPaperB2 : TestPaper2 //学生乙抄的试卷
{
public override class="tags" href="/tags/STRING.html" title=string>string Answer1()
{
return "b";
}
public override class="tags" href="/tags/STRING.html" title=string>string Answer2()
{
return "b";
}
public override class="tags" href="/tags/STRING.html" title=string>string Answer3()
{
return "b";
}
}
}
15. 命令模式
将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。它能比较容易的设计一个命令队列,可以容易的实现对请求的撤销和重做,添加命令不影响其他类
UML图:
![](http://hi.csdn.net/attachment/201109/17/0_1316225156oX8T.gif)
代码:
class="language-csharp">//23.6命令模式——通过参数达到不同的命令
namespace 命令模式
{
class Class2
{
static void Main(class="tags" href="/tags/STRING.html" title=string>string[] args)
{
Receiver r = new Receiver();
Command2 c = new ConcreteCommand(r);
Invoker i = new Invoker();
i.SetCommand(c);
i.ExecuteCommand();
Console.Read();
}
}
abstract class Command2 //抽象命令接口
{
protected Receiver receiver;
public Command2(Receiver receiver)
{
this.receiver=receiver ; //设置执行命令的对象
}
abstract public void Execute(); //执行命令
}
class ConcreteCommand : Command2
{
public ConcreteCommand(Receiver receiver)
: base(receiver)
{ }
public override void Execute()
{
receiver.Action(); //调用执行者的执行方法
}
}
class Invoker //命令的传递者——服务员
{
private Command2 command;
public void SetCommand(Command2 command)
{
this.command =command ;
}
public void ExecuteCommand()
{
command.Execute();
}
}
class Receiver //命令的接受者——执行者
{
public void Action()
{
Console.WriteLine("执行请求!");
}
}
}
16. 状态模式
当一个对象的内在状态改变时允许改变其行为,这个对象看起来是改变了其类。状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂的时候,状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。通过将各种状态转移到状态类的子类中减少相互之间的依赖。通过类中的函数将本身转换为下一个类,调用相应的方法。(举个例子:你想去办点事去找人,先是去得乡政府,乡长说这事不归我管你得去找书记,找到书记,书记又说这事不归我管你得去找县长,找到县长他说这事你得等我也没办法)
UML图:
![](http://hi.csdn.net/attachment/201109/17/0_13162252292IY6.gif)
代码:
class="language-csharp">//16.5状态模式
namespace 状态模式
{
class Class2
{
static void Main(class="tags" href="/tags/STRING.html" title=string>string[] args)
{
Context c = new Context(new ConcreteStateA());
c.Request();
c.Request();
c.Request();
c.Request();
Console.Read();
}
}
abstract class State
{
public abstract void Handle(Context context);
}
class ConcreteStateA : State
{
public override void Handle(Context context)
{
context.State = new ConcreteStateB();
}
}
class ConcreteStateB : State
{
public override void Handle(Context context)
{
context.State = new ConcreteStateA();
}
}
class Context
{
private State state;
public Context(State state)
{
this.state = state;
}
public State State
{
get { return state; }
set
{
state = value;
Console.WriteLine("当前状态:"+state.GetType().Name );
}
}
public void Request()
{
state.Handle(this );
}
}
}
17. 职责链模式
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它位置。接受者和发送者没有对方的明确信息,链中对象不知道链的结构,他们仅需要保持一个指向后继者的引用(还拿上个状态模式的例子为例,你去求乡长办事,但是这次乡长没有说让你去找书记,而是说行了这事我办吧,你回去吧,而是乡长自己去找得书记,找了书记,书记也解决不了,书记找县长,最后县长给你打电话了说这事你必须得等)
UML图:
![](http://hi.csdn.net/attachment/201109/17/0_1316225283Cl94.gif)
代码:
class="language-csharp">//24.5 加薪代码重构,在客户端让管理者形成链
namespace 职责链模式
{
class Class2
{
static void Main(class="tags" href="/tags/STRING.html" title=string>string[] args)
{
CommonManager jinli = new CommonManager("精力");
Majordomo zongjian = new Majordomo("总见");
GeneralManager zongjingli = new GeneralManager("总警力");
jinli.SetSuperior(zongjian );
zongjian.SetSuperior(zongjingli );
Request request = new Request();
request.RequestType = "请假";
request.RequestContent = "小菜请假";
request.Number = 1;
jinli.RequestApplications(request );
Request request2 = new Request();
request2.RequestType = "请假";
request2.RequestContent = "小菜请假";
request2.Number = 4;
jinli.RequestApplications(request2 );
Request request3 = new Request();
request3.RequestType = "加薪";
request3.RequestContent = "小菜请求加薪";
request3.Number = 500;
jinli.RequestApplications(request3 );
Request request4 = new Request();
request4.RequestType = "加薪";
request4.RequestContent = "小菜请求加薪";
request4.Number = 1000;
jinli.RequestApplications(request4);
Console.Read();
}
}
abstract class Manager1 //管理者接口
{
protected class="tags" href="/tags/STRING.html" title=string>string name; //管理者的姓名
protected Manager1 superior; //管理者的上级
public Manager1(class="tags" href="/tags/STRING.html" title=string>string name)
{
this.name = name;
}
//设置管理者的上级
public void SetSuperior(Manager1 superior)
{
this.superior = superior;
}
//申请请求
abstract public void RequestApplications(Request request);
}
class CommonManager : Manager1 //经理
{
public CommonManager(class="tags" href="/tags/STRING.html" title=string>string name)
: base(name)
{ }
public override void RequestApplications(Request request)
{
if (request.RequestType == "请假" && request.Number <= 2)
{
Console.WriteLine("{0}:{1}数量{2}被批准", name, request.RequestContent, request.Number);
}
else
{
if (superior != null) //其余的申请都需要转移到上级
superior.RequestApplications(request);
}
}
}
class Majordomo : Manager1 //总监
{
public Majordomo(class="tags" href="/tags/STRING.html" title=string>string name)
: base(name)
{ }
public override void RequestApplications(Request request)
{
if (request.RequestType == "请假" && request.Number <= 5)
{
Console.WriteLine("{0}:{1}数量{2}被批准", name, request.RequestContent, request.Number);
}
else
{
if (superior != null) //其余的申请都需要转移到上级
superior.RequestApplications(request);
}
}
}
class GeneralManager : Manager1 //总经理
{
public GeneralManager(class="tags" href="/tags/STRING.html" title=string>string name)
: base(name)
{ }
public override void RequestApplications(Request request)
{
if (request.RequestType == "请假" && request.Number <= 5)
{
Console.WriteLine("{0}:{1}数量{2}被批准", name, request.RequestContent, request.Number);
}
else if (request.RequestType == "加薪" && request.Number <= 500)
{
Console.WriteLine("{0}:{1}数量{2}被批准", name, request.RequestContent, request.Number);
}
else if (request.RequestType == "加薪" && request.Number > 500)
{
Console.WriteLine("{0}:{1}数量{2}再说吧", name, request.RequestContent, request.Number);
}
}
}
}
18. 解释器模式
给定一个语音,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。如果一种特定类型的问题发生的频率足够高,就值得将该问题的各个实例表述为一个简单语言中的句子,这就是解释器。其实就是咱们平时说的“行话”(例如:小偷公司中的上天窗,下平台;掏底兜,插马后都有特殊的含义,大家可以查查看,呵呵)
UML图:
![](http://hi.csdn.net/attachment/201109/17/0_13162253962V1S.gif)
代码:
class="language-csharp">namespace 解释器模式
{
class Program
{
static void Main(class="tags" href="/tags/STRING.html" title=string>string[] args)
{
Context context = new Context();
IList<AbstractExpression> list = new List<AbstractExpression>();
list.Add(new TerminalExpression());
list.Add(new NonterminalExpression ());
list.Add(new TerminalExpression ());
list.Add(new TerminalExpression());
foreach (AbstractExpression exp in list)
{
exp.Interpret(context );
}
Console.Read();
}
}
abstract class AbstractExpression
{
public abstract void Interpret(Context context );
}
class TerminalExpression : AbstractExpression
{
public override void Interpret(Context context)
{
Console.WriteLine("终端解释器");
}
}
class NonterminalExpression : AbstractExpression
{
public override void Interpret(Context context)
{
Console.WriteLine("非终端解释器");
}
}
class Context //解释器之外的信息
{
private class="tags" href="/tags/STRING.html" title=string>string input;
public class="tags" href="/tags/STRING.html" title=string>string Input
{
get { return input; }
set { input = value; }
}
private class="tags" href="/tags/STRING.html" title=string>string output;
public class="tags" href="/tags/STRING.html" title=string>string Output
{
get { return output; }
set { output = value; }
}
}
}