委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。委托模式是一项基本技巧,许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式。
动态委托的介绍:动态委托概念来自于Jakarta 字节码工程库 (Byte-Code Engineering Library, BCEL)。它能够分析存在的类,并且对于接口,抽象类,甚至运行时的具体类来说,它能够生成以字节编码委托类。
被委托的接口/类应该满足如下条件:动态委托最多只能委托一个类,但是能够代理多个接口。这个限制来自于Java的单继承模式。一个Java类最多只有一个父类。既然生成的委托类把被委托类作为它的父类,那么指定多个被委托类是不合理的。如果没有指定被委托类,那么缺省的父类就是Object。
下面是PHP 反射机制实现动态代理的代码:
06 | print "Generate an Apple" ; |
13 | function __construct() |
15 | $this ->target[] = new Fruit(); |
18 | function __call( $name , $args ) |
20 | foreach ( $this ->target as $obj ) |
22 | $r = new ReflectionClass( $obj ); |
23 | if ( $method = $r ->getMethod( $name )) |
25 | if ( $method ->isPublic() && ! $method ->isAbstract()) |
27 | return $method ->invoke( $obj , $args ); |
33 | $obj = new FruitDelegator(); |
可见,通过代理类FruitDelegator来代替Fruit类来实现他的方法。
同样的,如下的代码也是能够运行的:
13 | function addObject( $obj ) |
15 | $this ->target[] = $obj ; |
18 | function __call( $name , $args ) |
20 | foreach ( $this ->target as $obj ) |
22 | $r = new ReflectionClass( $obj ); |
23 | if ( $method = $r ->getMethod( $name )) |
25 | if ( $method ->isPublic() && ! $method ->isAbstract()) |
27 | return $method ->invoke( $obj , $args ); |
33 | $obj = new ColorDelegator(); |
34 | $obj ->addObject( new Color()); |