最近的学习中开始接触到了委托,为了深化自己对委托的认识,下面从几个例子入手,逐步强化进行学习。
相信大家小时候都看过迪猫和老鼠。Tom大战jerry的精彩演出让我们乐在其中,难以自拔。为了向这部经典致敬,我用代码将其中的一个场景表现出来。
目标:打印”老鼠出动吵醒猫,猫抓老鼠吵醒主人”
普通版
public class Mouse
{
public string MouseMove()
{
return "老鼠出动";
}
}
public class Cat
{
private Mouse mouse;
public string CatMove(Mouse mouse)
{
return mouse.MouseMove() + "吵醒猫,猫抓老鼠";
}
}
public class People
{
private Cat cat;
public Cat Cat {
set { this.cat = value; }
get { return cat; }
}
private Mouse mouse;
public Mouse Mouse {
set { this.mouse = value; }
get { return mouse; }
}
public string PeopleMove(Cat cat)
{
return cat.CatMove(mouse) + "吵醒主人";
}
}
static void Main(string[] args)
{
People hh = new People();
hh.Mouse= new Mouse();
hh.Cat = new Cat();
Cat cat = new Cat();
String cry= hh.PeopleMove(cat);
Console.WriteLine(cry);
分析:
这段代码最大的问题在于类与类之间的耦合太强。主要原因是在people类中出现了mouse类和cat类的名字以及方法。为了消除类与类之间的强耦合,下面使用委托来解耦。
委托版
class Program
{
public delegate string WakeUp();
public class Mouse
{
public string MouseMove()
{
return "老鼠出动";
}
}
public class Cat
{
private WakeUp wakeup;
public WakeUp WakeUp {
set { this.wakeup = value; }
get { return wakeup; }
}
public string CatMove()
{
return wakeup() + "吵醒猫,猫抓老鼠";
}
}
public class People
{
private WakeUp wakeup;
public WakeUp WakeUp {
set { this.wakeup = value; }
get { return wakeup; }
}
public string PeopleMove()
{
return wakeup() + "吵醒主人";
}
}
static void Main(string[] args)
{
People master = new People();
Cat tom = new Cat();
Mouse jerry = new Mouse();
tom.WakeUp = new WakeUp(jerry.MouseMove);
master.WakeUp = new WakeUp(tom.CatMove);
String cry= master.PeopleMove();
Console.WriteLine(cry);
}
分析:这段代码中我们可以看到,cat,people,mouse三个类之间没有直接通信,它们甚至不知道彼此之间的存在。解决了强耦合的问题。
但是现实生活中,如果在家里出现了一只老鼠,在接下来的2周内,你就要准备好对付一窝的老鼠。为了描述这个问题,我们使用委托链也就是多播委托。
多播委托版
public delegate void animalMove();
public class Cat {
private animalMove mouseM;
public animalMove MouseM {
set { this.mouseM = value; }
get { return mouseM; }
}
public void catMove()
{
Console.WriteLine("喵,猫来了。");
mouseM();
}
}
public class Mouse
{
private string name;
public Mouse(string name)
{
this.name = name;
}
public void mouseMove()
{
Console.WriteLine( name+"快跑");
}
}
class Program
{
static void Main(string[] ars)
{
Cat cat = new Cat();
Mouse tom = new Mouse("tom");
Mouse jerry = new Mouse("jerry");
cat.MouseM += new animalMove(tom.mouseMove);
cat.MouseM += new animalMove(jerry.mouseMove);
cat.MouseM += new animalMove(tom.mouseMove);
cat.catMove();
}
分析:所谓的委托链表就是委托和链表的结合体,在程序中的表现就是将老鼠tom,jerry,tom三个老鼠的方法统一注册到猫的方法中,通过猫的方法来触发三个老鼠的行为。非常类似与设计模式中的观察者模式以及数据结构中的链表。
总结
在写这篇博客的过程中参考了很多博客,发现了自己底子的薄弱,不能像很多博主一样从性能分析和方法指针等等的高度上来看待委托。于是决定采用渐变的方式和对委托所带来的语言现象的描述入手,论述我对委托的认识。总而言之,委托可以减少类与类之间的耦合,避免了一个类直接调用另外一个类的方法的同时让一个类成为另一个类的成员这种语言现象消失。更加强大的特性则是多播委托的存在,通过注册多个方法,多用于事件模型。