php工作原理及功能(php设计模式之适配器模式原理、用法及注意事项详解)
php工作原理及功能
php设计模式之适配器模式原理、用法及注意事项详解本文实例讲述了php设计模式之适配器模式原理、用法及注意事项。分享给大家供大家参考,具体如下:
在这个有没有对象都要高呼“面向对象”的年代,掌握面向对象会给我们带来意想不到的方便。学编程的小伙伴从开始能写几行代码实现简单功能到后来懂得将一些重复的操作组合起来形成一个“函数”,再到后来将“函数”和属性组合起来形成一个“类”。一步步走来,我们在考虑着机器运行代码效率的提高的同时也在考虑减轻程序员的工作量。 那么我们今天讲到的适配器模型更着重考虑的是什么呢?是程序员工作量。
什么时候会用到适配器模式?
其实最简单的例子是当我们引用一个第三方类库。这个类库随着版本的改变,它提供的API也可能会改变。如果很不幸的是,你的应用里引用的某个API已经发生改变的时候,除了在心中默默地骂“wocao”之外,你还得去硬着头皮去改大量的代码。
难道真的一定要如此吗?按照套路来说,我会回答“不是的”。我们有适配器模式啊~~
当接口发生改变时,适配器模式就派上了用场。
举个栗子
如果通过上面的简单描述,你都能懂,那在下只能佩服你的领悟能力超群了。一般人一定还是不知所云。为了方便理解,我引用一位博友的例子。原文地址。
一开始的和谐
黑枣玩具公司专门生产玩具,生产的玩具不限于狗、猫、狮子,鱼等动物。每个玩具都可以进行“张嘴”与“闭嘴”操作,分别调用了openMouth与closeMouth方法。
在这个时候,我们很容易想到可以第一定义一个抽象类Toy,甚至是接口Toy,这些问题不大,其他的类去继承父类,实现父类的方法。一片和谐,信心向荣。
平衡的破坏
为了扩大业务,现在黑枣玩具公司与红枣遥控公司合作,红枣遥控公司可以使用遥控设备对动物进行嘴巴控制。不过红枣遥控公司的遥控设备是调用的动物的doMouthOpen及doMouthClose方法。黑枣玩具公司的程序员现在必须要做的是对Toy系列类进行升级改造,使Toy能调用doMouthOpen及doMouthClose方法。
考虑实现的方法时,我们很直接地想到,你需要的话我再在我的父类子类里给你添加这么两个方法就好啦。当你一次又一次在父类子类里面重复添加着这两个方法的时候,总会想着如此重复的工作,难道不能解决么?当有数百个子类的时候,程序员会改疯的。程序员往往比的是谁在不影响效率的时候更会“偷懒”。这样做下去程序员会觉得自己很傻。(其实我经常当这样的傻子)
|
abstract class Toy { public abstract function openMouth(); public abstract function closeMouth(); //为红枣遥控公司控制接口增加doMouthOpen方法 public abstract function doMouthOpen(); //为红枣遥控公司控制接口增加doMouthClose方法 public abstract function doMouthClose(); } class Dog extends Toy { public function openMouth() { echo "Dog open Mouth\n" ; } public function closeMouth() { echo "Dog open Mouth\n" ; } //增加的方法 public function doMouthOpen() { $this ->doMouthOpen(); } //增加的方法 public function doMouthClose() { $this ->closeMouth(); } } class Cat extends Toy { public function openMouth() { echo "Cat open Mouth\n" ; } public function closeMouth() { echo "Cat open Mouth\n" ; } //增加的方法 public function doMouthOpen() { $this ->doMouthOpen(); } //增加的方法 public function doMouthClose() { $this ->closeMouth(); } } |
更加烦躁
程序员刚刚码完代码,喝了口水,突然间另一个消息传来。
黑枣玩具公司也要与绿枣遥控公司合作,因为绿枣遥控公司遥控设备更便宜稳定。不过绿枣遥控公司的遥控设备是调用的动物的operMouth(type)方法来实现嘴巴控制。如果type)方法来实现嘴巴控制。如果type为0则“闭嘴”,反之张嘴。
这下好了,程序员又得对Toy及其子类进行升级,使Toy能调用operMouth()方法。搁谁都不淡定了。
|
abstract class Toy { public abstract function openMouth(); public abstract function closeMouth(); public abstract function doMouthOpen(); public abstract function doMouthClose(); //为绿枣遥控公司控制接口增加doMouthClose方法 public abstract function operateMouth( $type = 0); } class Dog extends Toy { public function openMouth() { echo "Dog open Mouth\n" ; } public function closeMouth() { echo "Dog open Mouth\n" ; } public function doMouthOpen() { $this ->doMouthOpen(); } public function doMouthClose() { $this ->closeMouth(); } public function operateMouth( $type = 0) { if ( $type == 0) { $this ->closeMouth(); } else { $this ->operateMouth(); } } } class Cat extends Toy { public function openMouth() { echo "Cat open Mouth\n" ; } public function closeMouth() { echo "Cat open Mouth\n" ; } public function doMouthOpen() { $this ->doMouthOpen(); } public function doMouthClose() { $this ->closeMouth(); } public function operateMouth( $type = 0) { if ( $type == 0) { $this ->closeMouth(); } else { $this ->operateMouth(); } } } |
在这个时候,程序员必须要动脑子想办法了,就算自己勤快,万一哪天紫枣青枣黄枣山枣这些遥控公司全来的时候,忽略自己不断增多的工作量不说,这个Toy类可是越来越大,总有一天程序员不崩溃,系统也会崩溃。
问题在出在哪里呢?
像上面那样编写代码,代码实现违反了“开-闭”原则,一个软件实体应当对扩展开放,对修改关闭。即在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展。也就是说每个尸体都是一个小王国,你让我参与你的事情这个可以,但你不能修改我的内部,除非我的内部代码确实可以优化。
在这种想法下,我们懂得了如何去用继承,如何利用多态,甚至如何实现“高内聚,低耦合”。
回到这个问题,我们现在面临这么一个问题,新的接口方法我要实现,旧的接口(Toy抽象类)也不能动,那么总得有个解决方法吧。那就是引入一个新的类--我们本文的主角--适配器。 适配器要完成的功能很明确,引用现有接口的方法实现新的接口的方法。更像它名字描述的那样,你的接口不改的话,我就利用现有接口和你对接一下吧。
到此,解决方法已经呼之欲出了,下面贴上代码。
|
<?php abstract class Toy { public abstract function openMouth(); public abstract function closeMouth(); } class Dog extends Toy { public function openMouth() { echo "Dog open Mouth\n" ; } public function closeMouth() { echo "Dog close Mouth\n" ; } } class Cat extends Toy { public function openMouth() { echo "Cat open Mouth\n" ; } public function closeMouth() { echo "Cat close Mouth\n" ; } } //目标角色:红枣遥控公司 interface RedTarget { public function doMouthOpen(); public function doMouthClose(); } //目标角色:绿枣遥控公司及 interface GreenTarget { public function operateMouth( $type = 0); } //类适配器角色:红枣遥控公司 class RedAdapter implements RedTarget { private $adaptee ; function __construct(Toy $adaptee ) { $this ->adaptee = $adaptee ; } //委派调用Adaptee的sampleMethod1方法 public function doMouthOpen() { $this ->adaptee->openMouth(); } public function doMouthClose() { $this ->adaptee->closeMouth(); } } //类适配器角色:绿枣遥控公司 class GreenAdapter implements GreenTarget { private $adaptee ; function __construct(Toy $adaptee ) { $this ->adaptee = $adaptee ; } //委派调用Adaptee:GreenTarget的operateMouth方法 public function operateMouth( $type = 0) { if ( $type ) { $this ->adaptee->openMouth(); } else { $this ->adaptee->closeMouth(); } } } class testDriver { public function run() { //实例化一只狗玩具 $adaptee_dog = new Dog(); echo "给狗套上红枣适配器\n" ; $adapter_red = new RedAdapter( $adaptee_dog ); //张嘴 $adapter_red ->doMouthOpen(); //闭嘴 $adapter_red ->doMouthClose(); echo "给狗套上绿枣适配器\n" ; $adapter_green = new GreenAdapter( $adaptee_dog ); //张嘴 $adapter_green ->operateMouth(1); //闭嘴 $adapter_green ->operateMouth(0); } } $test = new testDriver(); $test ->run(); |
最后的结果就是,Toy类及其子类在不改变自身的情况下,通过适配器实现了不同的接口。
最后总结
将一个类的接口转换成客户希望的另外一个接口,使用原本不兼容的而不能在一起工作的那些类可以在一起工作.
适配器模式核心思想:把对某些相似的类的操作转化为一个统一的“接口”(这里是比喻的说话)--适配器,或者比喻为一个“界面”,统一或屏蔽了那些类的细节。适配器模式还构造了一种“机制”,使“适配”的类可以很容易的增减,而不用修改与适配器交互的代码,符合“减少代码间耦合”的设计原则。
希望本文所述对大家PHP程序设计有所帮助。
原文链接:https://www.cnblogs.com/DeanChopper/p/4770572.html
- php 经典模式(php设计模式之装饰模式应用案例详解)
- php如何异步操作(php链式操作的实现方式分析)
- thinkphp继承model如何使用(Thinkphp5.0 框架使用模型Model添加、更新、删除数据操作详解)
- php错误提示问题(php提示Creating default object from empty value 的问题解决方法)
- php提供哪些函数来避免sql的注入(PHP与SQL语句写一句话木马总结)
- thinkphp框架案例(thinkphp5.1框架容器与依赖注入实例分析)
- php7内核剖析(浅析PHP7的多进程及实例源码)
- php实现非递归快速排序(PHP实现无限极分类的两种方式示例递归和引用方式)
- php使用面向对象如何写好代码(PHP面向对象程序设计模拟一般面向对象语言中的方法重载overload示例)
- phpredis存储对象(PHP使用redis位图bitMap 实现签到功能)
- php中把字符串分开的函数(PHP字符串中抽取子串操作实例分析)
- php常用执行函数(PHP自动载入类文件函数__autoload的使用方法)
- php数组写法(php文件操作之文件写入字符串、数组的方法分析)
- thinkphp表单提交不到数据(ThinkPHP5.1表单令牌Token失效问题的解决)
- webapp前端能用yii2开发吗(Yii Framework框架使用PHPExcel组件的方法示例)
- php支付系统(php实现的支付宝网页支付功能示例基于TP5框架)
- 阿里最新财报公布 三季度营收增长3 ,将增加150亿美元回购额度 在美股价小涨(阿里最新财报公布)
- 赵薇时胖时瘦 最近变美少女 原因在这里 躺着就变瘦(赵薇时胖时瘦最近变美)
- 学会这26种姿势,你就可以和兵哥哥切磋了(你就可以和兵哥哥切磋了)
- 吴彦祖陈冠希 恩怨 ,失去曾让他流泪的女友,终遇走过18年真爱(吴彦祖陈冠希恩怨)
- 痴情男神 吴彦祖 与妻子恋爱8年,结婚10年,家庭幸福美满(痴情男神吴彦祖)
- 成功破圈,小牛电动SQi强势开 跨(小牛电动SQi强势开)
热门推荐
- python计算csv的行数(对Python 多线程统计所有csv文件的行数方法详解)
- tomcat环境配置都正确无法运行(为什么我的tomcat启动不起来)
- html5炫酷代码(HTML5超炫酷粒子效果的进度条的实现示例)
- 怎么使用阿里云cdn(阿里云CDN加速和全站加速DCDN区别及如何选择)
- python将一个字符串逆序输出(Python字符串逆序的实现方法一题多解)
- phpstudy使用教程(phpstudy是什么)
- nginx查看请求协议(Nginx之Http模块系列之autoindex模块的具体使用)
- dedecms标签怎么调用(DEDECMS自定义表单提交后的跳转链接修改方法)
- sql语言怎么删除某列(SQL删除多列语句的写法)
- HTTP状态码的意思
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9