寒假去西班牙的计划一再受阻,准备好了材料,成都签证中心又关了,也是醉了。明天上完设计模式就结课了,唉,理解不深啊~~~~咋才能学的好啊~~~今天的学习是利用委托对昨天的观察者模式的补充。
观察者模式的不足:
观察者模式所做的工作其实就是在解除耦合,让耦合双方都依赖于抽象,而不依赖于具体,这极大程度地体现了依赖倒转原则,但是在现实运用中,抽象通知者还是依赖于抽象观察者,万一没有了抽象观察者的接口,通知功能便无法完成;此外,观察者的方法名并不完全相同。这时就需要运用委托来解决这一问题。
委托:
委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值,如下面的示例所示:
public delegate int PerformCalculation(int x, int y);
与委托的签名(由返回类型和参数组成)匹配的任何方法都可以分配给该委托。
简单理解Delegate委托(或代理)是一种数据类型:它的变量可以引用到某一个符合要求的方法上,通过委托可以间接地调用该方法。
其实.NET的委托类似于C语言的函数指针,区别在于.NET委托是类型安全的,这说明,C中的函数指针只不过是一个指向存储单元的指针,我们无法说出这个指针实际指向什么。
在此处将昨天的代码做了修改,运用委托之后,将删去抽象观察者类,观察这类的方法也可以有不同的名称。
代码:
Subject.cs
abstract class Subject
{
void Notify()
{
}
string SubjectState
{
get;
set;
}
}
ConcreteSubject.cs
delegate void EventHandler();
class ConcreteSubject : Subject
{
public event EventHandler Update;
private string action;
public void Notify()
{
Update();
}
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
ConcreteObserver.cs
class ConcreteObserver
{
private string name;
private string observerState;
private ConcreteSubject subject;
internal ConcreteSubject Subject
{
get { return subject; }
set { subject = value; }
}
public ConcreteObserver(ConcreteSubject subject, string name)
{
this.subject=subject;
this.name=name;
}
public void Update1()
{
observerState = subject.SubjectState;
Console.WriteLine("Observer{0}的新状态是{1}", name, observerState);
}
}
ConcreteObserverA.cs
class ConcreteObserverA
{
private string name;
private string observerState;
private ConcreteSubject subject;
internal ConcreteSubject Subject
{
get { return subject; }
set { subject = value; }
}
public ConcreteObserverA(ConcreteSubject subject, string name)
{
this.subject=subject;
this.name=name;
}
public void Update2()
{
observerState = subject.SubjectState;
Console.WriteLine("观察者{0}的新状态是{1}", name, observerState);
}
}
Program.cs
class Program
{
static void Main(string[] args)
{
ConcreteSubject sb = new ConcreteSubject();
ConcreteObserver CO = new ConcreteObserver(sb, "Kobe");
ConcreteObserverA COA = new ConcreteObserverA(sb, "T-Mac");
sb.Update += new EventHandler(CO.Update1);
sb.Update += new EventHandler(COA.Update2);
sb.SubjectState = "Come Back";
sb.Notify();
Console.ReadKey();
}
}
委托可以看作是对函数的抽象,是函数的“类”,委托的实例将代表一个具体的函数。一个委托可以搭载多个方法,他可以使得委托对象所搭载的方法不需要属于同一个类。