php设计模式之Proxy(代理模式)和Facade(外观)设计模式

Proxy(代理模式)和Facade(外观)设计模式
它们均为更复杂的功能提供抽象化的概念,但这两种实现抽象化的过程大不相同

Proxy案例中,所有的方法和成员变量都来自于目标对象,必要时,该代理能够对它所传递的数据进行修改或检查
魔术方法使得Proxy的实现变的简单,Proxy模式的一类应用时用来记录方法的访问信息
还可以利用Proxy的类确定代码的范围或调试程序中存在的问题

<?php
class LoggingProxy{
    private $target;
    //传递进去一个对象
    public function __construct($target){
        $this->target=$target;
    }
    protected function log($line){
        echo "[".$line."]\r\n";
    }
    public function __set($name,$value){
        $this->target->$name=$value;
        $this->log("setting value for $name:$value ");
    }
    public function __get($name){
        $value=$this->target->$name;
        $this->log("Getting value for $name:$value");
        return $value;
    }
    public function __isset($name){
        $value=isset($this->target->$name);
        $this->log("checking isset for $name".($value?"true":"false"));
        return $value;
    }
    public function __call($name,$arguments){
        $this->log("calling method $name width:".implode(",", $arguments));
        return call_user_func_array(array($this->target,$name), $arguments);
        
    }
}
class People{
    public $name=‘hk‘;
    public $age;
    public function sayname(){
        return $this->name;
    }
    public function plus($a,$b){
        return $a+$b;
    }
}
$p=new People();
$proxy=new LoggingProxy($p);
echo $proxy->name;//hk
echo "<br>";
$proxy->age=10;
echo $p->age;//10
echo "<br>";
echo $proxy->sayname();
echo "<br>";
echo $proxy->plus(2,3);

结果

[Getting value for name:hk] hk
[setting value for age:10 ] 10
[calling method sayname width:] hk
[calling method plus width:2,3] 5

多数情况下Proxy不应该改变它所代理的类的行为
Proxy与它所代理的在类型上不完全一致,这也是其一个缺点。
因而若需要进行类型提示或代码检查以确保对象是某一特定类型,这种情况下就不能使用代理模式


Facade(外观)模式提供了不同的功能,用来抽象化复杂功能,以使应用程序无需了解子系统处理
各请求的细节,就能完成整个处理过程
例如:处理典型api请求时,用户需要通过子系统进行认证,认证通过后,请求通过api子系统传递给远程服务器
处理,最后通过其它api的函数对相应解码
Facade方法实现如下

<?php
class Facade{
    public function apiRequestJson($method,$parameters){
        $user=User::getAuthenticatedUser();
        if($user->hasPermission($method)){
            $result=$this->api->$method($parameters);
            return json_encode($result);
        }
    }
}

Facade并不为子系统添加任何新的功能,而是为子系统委托合适的责任。
子系统无需知道Facade的存在,而应用程序也无需知道子系统的存在。

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。