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保留两位小数的几种方法)
- apachephp环境搭建(apache集成php7.3.5的详细步骤)
- thinkphp快速入门手册(从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解)
- php处理app上传的图片(php用wangeditor3实现图片上传功能)
- php中isset函数有什么功能(PHP中的empty、isset、isnull的区别与使用实例)
- php如何获取当前日期(php实现获取近几日、月时间示例)
- 解释php中可变变量并举例说明(PHP Primary script unknown 解决方法总结)
- phpstudymysql启动又自动停止(Win下解决phpStudy MySQL启动失败)
- ubuntu安装php(在Ubuntu 18.04上安装PHP 7.3 7.2和7.0的方法)
- phpstudyv8.0部署多站点(phpstudy v8.1 全站301重定向设置教程)
- thinkphp5.1 执行流程(Thinkphp5.0 框架的请求方式与响应方式分析)
- php中抽象类和接口的区别(PHP抽象类和接口用法实例详解)
- php怎么设置静态成员函数(php输出控制函数和输出函数生成静态页面)
- php开发技巧和方法(php+ajax实现商品对比功能示例)
- thinkphp5 api开发(thinkphp5框架前后端分离项目实现分页功能的方法分析)
- php如何创建二维数组(PHP二维索引数组的遍历实例分析2种方式)
- 以前全椒人是怎么过冬的 满满都是回忆(以前全椒人是怎么过冬的)
- NVIDIA显卡份额冲上88 A饭发愁 游戏优化恐没A卡份了(NVIDIA显卡份额冲上88A饭发愁)
- AMD YES A卡还是N卡 A卡和N卡的区别(AMDYESA卡还是N卡)
- 以后显卡多了一个新选择,N卡和A卡外又多了个I卡(以后显卡多了一个新选择)
- 读卖乐园的彩灯(读卖乐园的彩灯)
- 新疆80后在淘宝卖干果 以前是 不务正业 如今帮乡亲致富(新疆80后在淘宝卖干果)
热门推荐
- sql server语法大全(SQL Server 全文搜索功能介绍)
- docker镜像无法删除 Error:No such image:xxxxxx解决(docker镜像无法删除 Error:No such image:xxxxxx解决)
- mysql 死锁产生的原因和必要条件(Mysql查看死锁与解除死锁的深入讲解)
- mysql怎么创建联合索引(mysql的联合索引复合索引的实现)
- mysql子查询用法(MySQL 子查询和分组查询)
- jquery 选择器的用法
- 怎么进入云服务器(云服务器端口怎么打开?)
- docker怎么创建mysql服务(Docker部署MySQL8集群一主二从的实现步骤)
- mysql数据字段默认值怎么设置(MySQL 字段默认值该如何设置)
- 10款免费好用的云服务器/VPS主机控制面板推荐(10款免费好用的云服务器/VPS主机控制面板推荐)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9