• PHP的代理模式


    代理模式与父类和接口的异同

    • 相同点:代理模式的作用和父类以及接口和组合的作用类似,都是为了聚合共用部分,减少公共部分的代码
    • 不同点:
      • 相比起父类,他们的语境不同,父类要表达的含义是 is-a, 而代理要表达的含义更接近于接口, 是 has-a,而且使用代理的话应了一句话"少用继承,多用组合",要表达的意思其实也就是降低耦合度了
      • 相比起接口,他们实现的功能又不太一样,语境都是has-a,不过接口是has-a-function,而代理对象时是has-a-object,这个object是has-a-function的object,此外,接口是为了说明这个类拥有什么功能,却没有具体实现,实现了多态,而代理对象不但拥有这个功能,还拥有这个功能的具体实现
      • 对于组合来说,他比组合更具灵活性,比如我们将代理对象设为private,那么我可以选择只提供一部分的代理功能,例如Printer的某一个或两个方法,又或者在提供Printer的功能的时候加入一些其他的操作,这些都是可以的

    下面先来看PHP如何实现代理

     1 <html>
     2      <body>
     3         <?php
     4             class Printer {    //代理对象,一台打印机
     5                 public function printSth() {
     6                     echo 'I can print <br>';
     7                 }
     8                 
     9                 // some more function below
    10                 // ...
    11             }
    12              
    13             class TextShop {    //这是一个文印处理店,只文印,卖纸,不照相
    14                 private $printer;
    15                 
    16                 public function __construct(Printer $printer) {
    17                     $this->printer = $printer;
    18                 }
    19                 
    20                 public function sellPaper() {    //卖纸
    21                     echo 'give you some paper <br>';
    22                 }
    23                 
    24                 public function __call($method, $args) {    //将代理对象有的功能交给代理对象处理
    25                     if(method_exists($this->printer, $method)) {
    26                         $this->printer->$method($args);
    27                     }
    28                 }
    29             }
    30              
    31             class PhotoShop {    //这是一个照相店,只文印,拍照,不卖纸
    32                 private $printer;
    33                 
    34                 public function __construct(Printer $printer) {
    35                     $this->printer = $printer;
    36                 }
    37                 
    38                 public function takePhotos() {    //照相
    39                     echo 'take photos for you <br>';
    40                 }
    41                 
    42                 public function __call($method, $args) {    //将代理对象有的功能交给代理对象处理
    43                     if(method_exists($this->printer, $method)) {
    44                         $this->printer->$method($args);
    45                     }
    46                 }
    47             }
    48             
    49             $printer = new Printer();
    50             $textShop = new TextShop($printer);
    51             $photoShop = new PhotoShop($printer);
    52             
    53             $textShop->printSth();
    54             $photoShop->printSth();
    55         ?>
    56      </body>
    57  </html>

    文印处理店和照相店都具有文印的功能,所以我们可以将文印的功能代理给一台打印机,这里打印机只有一个功能,假如打印机还有n个功能,我们使用__call()方法就能够省去很多重复的代码了

    假如是使用继承,这样语境上就不合理,一个店显然不应该继承一台打印机

    而使用接口,因为我们的功能实现都是一样,也没有必要去重新实现接口的功能

    所以此处使用代理是最佳选择

    Java中的代理模式实现其实类似,只不过Java没有__call()方法,还需要手动声明printSth()方法,然后在方法体里去调用$printer的printSth()方法,此处就不再赘述了

  • 相关阅读:
    扑克牌大小
    简单错误记录
    聊天室
    GMM的EM算法实现
    Spark SQL 源代码分析之 In-Memory Columnar Storage 之 in-memory query
    JSP简单练习-使用JDOM创建xml文件
    PowerDesigner使用教程
    setsockopt()使用方法(參数具体说明)
    SQL注入原理解说,非常不错!
    Offer是否具有法律效力?
  • 原文地址:https://www.cnblogs.com/zemliu/p/2509377.html
Copyright © 2020-2023  润新知