委托

委托

委托有两层含义:

1、对象复用过程中,一个类委托另一个类做事情。

2、C#中,表示一类方法,这类方法具备相同的形参表(输入)和返回类型(产出)相同,而不要求方法名。


 委托(对象复用)

继承是一种很好的复用方式,假设A继承B,意味着A包含B所有的字段和方法,也就是说,二者在语义上是一种IsA的关系。但很多时候并不是这种情况,而是二者之间存在关联关系,A委托B去做一件事。常见的设计模式中,有一些就是特殊的委托关系。比如:

1、状态模式:一个对象将请求委托给描述该对象状态的State对象去处理。

2、对象适配器模式:Adapter委托Adaptee去做一件事。

3、代理模式:Proxy委托RealSubject去做事,Proxy和RealSubject实现相同的接口,这样Proxy就可以代替RealSubject。

4、命令模式:Invoker委托Command去做事,Command委托Receiver去做事,从而实现命令发起者与命令执行者的解耦。


 委托(一类方法)

方法包括4个内容:方法名,形参表(输入),返回类型(输出),修饰符。这里不考虑修饰符,委托是一类方法,这一类方法的形参表和返回类型相同,而不关心方法名。

这里涉及到逆变与协变。举例来说:我要找一个厨师,要求是给你小麦,做出面食。现在有个人应聘:给我粮食,我就能做出面条。现在考虑:应聘者符合要求吗?应聘者把输入的条件放宽了,同时产出更具体了,根据里氏代换,当然符合要求。

调用委托的时候,传递的是小麦,委托会执行绑定的方法,该方法接收粮食作为输入,小麦向粮食转型,符合里氏代换。

调用委托后,期望返回的是面食,而实际返回的是面条,面条向面食转型,符合里氏代换。


为什么要使用委托呢?

以观察者为例说明,subject维护一系列Observer,subject变化,通知Observer更新。我们知道,面向对象强调面向抽象编程,也就是说Subject内部维护是抽象的Observer引用,这些引用指向具体的Observer。在Subject变化的时候,遍历Observer集合,调用Observer的方法。这就意味着,只有具备Observer接口的对象才能观察Subject。这不符合现实情况,如果有必要,任何对象都可以观察Subject,只要这个对象提供一个方法处理。这种情况下,可以使用委托,绑定到这个对象的处理方法。