PHP的代理模式
php的代理模式的实现:
理解一种模式,可以融会贯通,和其它的模式进行对比。找出为什么要 代理模式呢?跟父类、接口的区别是什么?
为什么需要这种模式?存在的价值?
原文:https://www.cnblogs.com/zemliu/archive/2012/05/20/2509377.html
-----------------------------------------------------------------------------------------------------------------------------
代理模式与父类和接口的异同
- 相同点:代理模式的作用和父类以及接口和组合的作用类似,都是为了聚合共用部分,减少公共部分的代码
- 不同点:
- 相比起父类,他们的语境不同,父类要表达的含义是 is-a, 而代理要表达的含义更接近于接口, 是 has-a,而且使用代理的话应了一句话"少用继承,多用组合",要表达的意思其实也就是降低耦合度了
- 相比起接口,他们实现的功能又不太一样,语境都是has-a,不过接口是has-a-function,而代理对象时是has-a-object,这个object是has-a-function的object,此外,接口是为了说明这个类拥有什么功能,却没有具体实现,实现了多态,而代理对象不但拥有这个功能,还拥有这个功能的具体实现
- 对于组合来说,他比组合更具灵活性,比如我们将代理对象设为private,那么我可以选择只提供一部分的代理功能,例如Printer的某一个或两个方法,又或者在提供Printer的功能的时候加入一些其他的操作,这些都是可以的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | <html> <body> <?php class Printer { //代理对象,一台打印机 public function printSth() { echo 'I can print <br>' ; } // some more function below // ... } class TextShop { //这是一个文印处理店,只文印,卖纸,不照相 private $printer ; public function __construct(Printer $printer ) { $this ->printer = $printer ; } public function sellPaper() { //卖纸 echo 'give you some paper <br>' ; } public function __call( $method , $args ) { //将代理对象有的功能交给代理对象处理 if (method_exists( $this ->printer, $method )) { $this ->printer-> $method ( $args ); } } } class PhotoShop { //这是一个照相店,只文印,拍照,不卖纸 private $printer ; public function __construct(Printer $printer ) { $this ->printer = $printer ; } public function takePhotos() { //照相 echo 'take photos for you <br>' ; } public function __call( $method , $args ) { //将代理对象有的功能交给代理对象处理 if (method_exists( $this ->printer, $method )) { $this ->printer-> $method ( $args ); } } } $printer = new Printer(); $textShop = new TextShop( $printer ); $photoShop = new PhotoShop( $printer ); $textShop ->printSth(); $photoShop ->printSth(); ?> </body> </html> |
文印处理店和照相店都具有文印的功能,所以我们可以将文印的功能代理给一台打印机,这里打印机只有一个功能,假如打印机还有n个功能,我们使用__call()方法就能够省去很多重复的代码了
假如是使用继承,这样语境上就不合理,一个店显然不应该继承一台打印机
而使用接口,因为我们的功能实现都是一样,也没有必要去重新实现接口的功能
所以此处使用代理是最佳选择
Java中的代理模式实现其实类似,只不过Java没有__call()方法,还需要手动声明printSth()方法,然后在方法体里去调用$printer的printSth()方法,此处就不再赘述了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2017-09-04 【转】】}linux awk 命令详解
2017-09-04 理解linux安装软件
2017-09-04 cat<<EOF获取标准输入到文件中