代理模式与父类和接口的异同
下面先来看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()方法,此处就不再赘述了