如果我已经写好了一个类,
但是调用端(客户端)想要干预我的执行顺序。
比如有一个Car类,客户端想要在Car超速的时候,打印出超速的信息。
而且,客户端想要怎么样打印还不确定,或者说不同的客户端想要打印不同的信息。
这个时候,Car就和客户端约定好:
定义一个接口,用来规范需要的参数;
Car维护一个该接口的列表(用户可以传入多个处理方式),并且在适当的时候,调用该接口定义的方法,给客户端象接口列表加入Sink、删除sink的方式。
客户端实现接口,加入需要执行的方式(如打印出超速的信息)。
using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace TestCS
{
class Car
{
//我接收了Sink并不是简单的加入,我需要
//1.维护一个Sink列表,以供客户端加入多个Sink
//2.我需要在适当的时机触发Sink
public int MaxSpeed =600;
public string PetName;
public int Speed;
public Car()
{
PetName = "no name";
Speed = 300;
}
public Car(string petName,int speed)
{
this.PetName = petName;
this.Speed = speed;
}
public override string ToString()
{
return PetName+" is at a speed of "+Speed.ToString();
}
ArrayList clientSinks = new ArrayList();
public void Advise(IEngineNotification sink)
{
clientSinks.Add(sink);
}
public void UnAdvise(IEngineNotification sink)
{
clientSinks.Remove(sink);
}
bool isCarDead;
public void Accelerate(int delta)
{
if (isCarDead)
{
foreach (IEngineNotification sink in clientSinks)
{
sink.Exploed("Sorry ,the car is dead!");
}
}
else
{
Speed += delta;
if (100 == (MaxSpeed - Speed))
{
foreach (IEngineNotification sink in clientSinks)
{
sink.AboutToBlow("Careful body!Gonna blow!");
}
}
if (MaxSpeed <Speed)
{
isCarDead = true;
}
else
{
Console.WriteLine("Current Speed is: {0}", Speed.ToString());
}
}
}
}
//我的存在是为了叫客户可以定制触发事件后的操作。
//我的操作是打印name:msg
public class CarEventSink : IEngineNotification
{
string name;
public CarEventSink(string name)
{
this.name = name;
}
public CarEventSink()
{
}
#region IEngineNotification 成员
public void AboutToBlow(string msg)
{
Console.WriteLine("{0} is {1}", name, msg);
}
public void Exploed(string msg)
{
Console.WriteLine("{0} is {1}", name, msg);
}
#endregion
}
//我的存在是为了叫客户端可以定制触发事件后的操作。
//客户端也可以给我加入参数
//我的操作是打印name==》msg
//Sink的意思--》接收器
public class CarEventSink2 : IEngineNotification
{
#region IEngineNotification 成员
string name;
public CarEventSink2(string name)
{
this.name = name;
}
public void AboutToBlow(string msg)
{
Console.WriteLine("{0}===>{1}", name, msg);
}
public void Exploed(string msg)
{
Console.WriteLine("{0}===>{1}", name, msg);
}
#endregion
}
//我的存在是为了制定一个客户端和Car通信的协议。
//定义car要触发哪些方法
//同时,定义了这些方法需要的参数,这样,Car就可以传参数给客户端
public interface IEngineNotification
{
void AboutToBlow(string msg);
void Exploed(string msg);
}
class Program
{
public static void Main(string[] args)
{
Car c1 = new Car();
CarEventSink sink = new CarEventSink(c1.PetName+":");
CarEventSink sink2 = new CarEventSink("2:");
c1.Advise(sink);
c1.Advise(sink2);
//我知道Car一定是可以接收sink的。
//我可以通过实现来IEngineNotification来定义Car发生了指定的事件后如何反应。
//这样就等于在Car的外部,影响了Car的执行。
//条件是Car一定要配合我,维护一个sink列表,并且在适当的实际触发
for (int i = 0; i < 10; i++)
{
c1.Accelerate(100);
}
c1.UnAdvise(sink);
c1.UnAdvise(sink2);
}
}
}