__call()方法实现委托机制

__call()方法可能是最有用的拦截器方法。当客户端代码要调用类中未定义的方法时,__call()
会被调用。__call()带有两个参数,一个是方法的名称,另一个是传递给要调用方法的所有参数
(数组)。__call()方法返回的任何值都会返回给客户,就好像调用一个真实存在的方法一样
ca11()方法对于实现委托也很有用。委托是指一个对象转发或者委托一个请求给另一个对
象,被委托的一方替原先对象处理请求。这类似于继承,和在子类中调用父类的方法有点相似。
但在继承时,父类与子类的关系是固定的,而使用委托则可以在代码运行时改变使用的对象,这
意味着委托比继承具有更大的灵活性。我们用例子来解释一下。

<?php

class PersonWriter{
	function writeName(Person $p){
		print $p->getName()."\n";
	}
	function writeAge(Person $p){
		print $p->getAge()."\n";
	}
}

<?php
include 'PersonWriter.php';
class Person{
	private $writer;
	
	function __construct(PersonWriter $writer){
		$this->writer=$writer;
	}
	function __call($methodname,$args){
		if(method_exists($this->writer, $methodname)){
			return $this->writer->$methodname($this);
		}
	}
	
	function getName(){
		return "Bob";
	}
	function getAge(){
		return 44;
	}
}

$person=new Person(new PersonWriter());
$person->writeName();



代码中Person类接受一个PersonWriter对象作为构造方法的参数,并将它存储在属性变量$writer中。在__call()方法中,我们使用参数$methodname,检查PersonWriter对象中是否存在同名的方法。如果相应的方法存在,我们就委托PersonWriter对象来处理对方法的调用,把当前类(Person)的实例作为参数传递给PersonWriter对象(使用$this伪变量)。因此,如果这样调用Person类:
$person=new Person( new PersonWriter() );
$person->writeName();

__call()方法就会被调用。然后会在PersonWriter对象中查找writeName()方法,并调用之。这样我们就可以不用手动在Person类中调用以下委托方法:
function writeName(){
    $this->writer->writeName($this);
}
现在Person类神奇的增加了2个新方法,如果你要委托很多方法的处理,那么这样的自动委托可以为你节省很多时间。但代码也会变得有点不太清晰,不易理解。对于外部世界来说,你提供的是一个动态的接口,没有办法进行反射。因为委托类和被委托类之间的交互可能比较模糊————用__call()方法来调用,而不是显式的继承关系或者参数类型提示。拦截器方法是非常有用的,但是在使用时要慎重考虑,而且最好附上文档,清楚的说明代码细节。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值