委托模式 - Delegation
定义
有两个对象参与(两个对象协同)处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。
委托模式属于行为型模式。许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式。
设计的原则和思想
- 解耦委托者与被委托者。
- 不变部分是委托者和被委托者,变化部分是委托者与被委托者之间的协同方式。
- 核心思想是委托者与被委托者协同完成某个事情。
一句话概括设计模式
委托者对象提供原本的功能,被委托者对象提供附加功能。
结构中包含的角色
- Delegate 抽象委托行为接口
- AnotherRequest 另外的请求对象 - 被委托者
- Request 请求对象 - 委托者
最小可表达代码 - 事件监听
// 抽象委托行为接口 | |
interface Delegate | |
{ | |
public function buyAirTicket(); | |
} | |
// 另外的请求对象 - 被委托者 | |
class AnotherRequest implements Delegate | |
{ | |
public function buyAirTicket() | |
{ | |
echo '购买机票'; | |
} | |
} | |
// 请求对象 - 委托者 | |
class Request | |
{ | |
private $delegate; | |
public function __construct(Delegate $eelegate) | |
{ | |
$this->delegate = $eelegate; | |
} | |
public function TakePlane() | |
{ | |
$this->delegate->buyAirTicket(); | |
echo ' 坐飞机 '; | |
} | |
} | |
$request = new Request(new AnotherRequest); | |
$request->TakePlane(); |
最小可表达代码 - 被委托协助委托者
// 抽象委托行为接口 | |
interface Delegate | |
{ | |
public function buy($phone); | |
} | |
// 另外的请求对象 - 被委托者 | |
class AnotherRequest implements Delegate | |
{ | |
public function buy($phone) | |
{ | |
echo '买手机:' . $phone; | |
} | |
} | |
// 请求对象 - 委托者 | |
class Request implements Delegate | |
{ | |
private $delegate; | |
public function __construct(Delegate $eelegate) | |
{ | |
$this->delegate = $eelegate; | |
} | |
public function buy($phone) | |
{ | |
$this->delegate->buy($phone); | |
} | |
} | |
$request = new Request(new AnotherRequest); | |
$request->buy("诺基亚"); |
优点
- 通过任务委派能够将一个大型的任务细化。
- 将应用相关的内容与框架完全分离开。
- 避免过多的子类以及子类与父类的耦合。
- 通过委托传递消息机制实现分层解耦.
缺点
- 在任务比较复杂的情况下可能需要进行多重委派,容易造成紊乱。
- 容易导致职责分散,导致维护麻烦。
何时使用
- 当自身不具备某种功能时,可以通过引入另一种类型来提供相关的能力。
业务场景
- 上司分配任务给下属
- JVM在加载类使用的双亲委派模式。
- Java的Method类里的invoke()方法。
- JS的事件流就是委托模式。