分享到:

对PHP接口的思考

日期:2016-10-25 21:18:00     阅读:260     文章来源:源美设计     标签:深圳网站建设,php接口

大家好,在这里【源美设计】就和大家一起谈下关于对PHP接口的思考,我们在PHP的接口自始至终一直在被争议,有人说接口很好,有人说接口像鸡肋。首先要明白,好和不好的判断标准是什么。无疑,这是和Java/C++相比。在上面的例子中,已经讨论了PHP的接口在“面向契约编程”中是不足的,并没有起到应有的作用。

其实,在上面的interface.php代码中,machine类的声明应该在plain类前面。接口提供了一套规范,这是系统提供的,然后machine类提供一组针对接口的API并实现,最后才是自定义的类。在Java里,接口之所以盛行(多线程的runable接口、容器的collection接口等)就是因为系统为我们做了前面两部分的工作,而程序员,只需要去写具体的实现类,就能保证接口可用可控。

为什么要用接口?接口到底有什么好处?接口本身并不提供实现,只是提供一个规范。如果我们知道一个类实现了某个接口,那么就知道了可以调用该接口的哪些方法,我们只需要知道这些就够了。

PHP中,接口的语义是有限的,使用接口的地方并不多,PHP中接口可以淡化为设计文档,起到一个团队基本契约的作用,代码如下所示:

<?php

interface cache{

/**

@describe:缓存管理,项目经理定义接口,技术人员负责实现

**/

const maxKey=10000;//最大缓存量

public function getc($key);//获取缓存

public function setc($key,$value);//设置缓存

public function flush();//清空缓存

PHP是强调灵活,所以并不推荐大规模使用接口,而是仅在部分“内核”代码中使用接口,因为PHP中的接口已经失去很多接口应该具有的语义。从语义上考虑,可以更多地使用抽象类。至于抽象类和接口的比较,不再赘述。

另外,PHP5对面向对象的特性做了许多增强,其中就有一个SPL(标准PHP库)的尝试。SPL中实现一些接口,其中最主要的就是Iterator迭代器接口,通过实现这个接口,就能使对象能够用于foreach结构,从而在使用形式上比较统一。比如SPL中有一个DirectoryIterator类,这个类在继承SplFileInfo类的同时,实现Iterator、Traversable、SeekableIterator这三个接口,那么这个类的实例可以获得父类SplFileInfo的全部功能外,还能够实现Iterator接口所展示的那些操作。

Iterator接口的原型如下:

*current()

This method returns the current index's value.You are solely

responsible for tracking what the current index is as the

interface does not do this for you.

*key()

This method returns the value of the current index's key.For

foreach loops this is extremely important so that the key

value can be populated.

*next()

This method moves the internal index forward one entry.

*rewind()

This method should reset the internal index to the first element.

*valid()

This method should return true or false if there is a current

element.It is called after rewind()or next(). 

如果一个类声明了实现Iterator接口,就必须实现这五个方法,如果实现了这五个方法,那么就可以很容易对这个类的实例进行迭代。这里,DirectoryIterator类之所以拿来就能用,是因为系统已经实现了Iterator接口,所以可以像下面这样使用:

<?php

$dir=new DirectoryIterator(dirname(_FILE_));

foreach($dir as$fileinfo){

if(!$fileinfo->isDir()){

echo

$fileinfo->getFilename(),"\t",$fileinfo->getSize(),PHP_EOL;

}

可以想象,如果不用DirectoryIterator类,而是自己实现,不但代码量增加了,而且循环时候的风格也不统一了。如果自己写的类也实现了Iterator接口,那么就可以像Iterator那样工作。

为什么一个类只要实现了Iterator迭代器,其对象就可以被用作foreach的对象呢?其实原因很简单,在对PHP实例对象使用foreach语法时,会检查这个实例有没有实现Iterator接口,如果实现了,就会通过内置方法或使用实现类中的方法模拟foreach语句。这是不是和前面提到的_toString方法的实现很像呢?事实上,_toString方法就是接口的一种变相实现。

接口就是这样,接口本身什么也不做,系统悄悄地在内部实现了接口的行为,所以只要实现这个接口,就可以使用接口提供的方法。这就是接口“即插即用”思想。

我们都知道,接口是对多重继承的一种变相实现,而在讲继承时,我们提到了用来实现混入(Mixin)式的Traits,实际上,Traits可以被视为一种加强型的接口。

来看一段代码:

<?php

trait Hello{

public function sayHello(){

echo'Hello';

}

}

trait World{

public function sayWorld()

echo'World';

}

}

class MyHelloWorld{

use Hello,World;

public function sayExclamationMark(){

echo'!';

}

}

$o = new MyHelloWorld();

$o ->sayHello();

$o ->sayWorld();

$o ->sayExclamationMark();

?> 

上面的代码运行结果如下:

Hello World! 

这里的MyHelloWorld同时实现了两个Traits,从而使其可以分别调用两个Traits里的代码段。从代码中就可以看出,Traits和接口很像,不同的是Traits是可以导入包含代码的接口。从某种意义上来说,Traits和接口都是对“多重继承”的一种变相实现。

总结关于接口的几个概念:

接口作为一种规范和契约存在。作为规范,接口应该保证可用性;作为契约,接口应该保证可控性。

接口只是一个声明,一旦使用interface关键字,就应该实现它。可以由程序员实现(外部接口),也可以由系统实现(内部接口)。接口本身什么都不做,但是它可以告诉我们它能做什么。

PHP中的接口存在两个不足,一是没有契约限制,二是缺少足够多的内部接口。

接口其实很简单,但是接口的各种应用很灵活,设计模式中也有很大一部分是围绕接口展开的。



文章引用:http://www.szymweb.com/new/142.html

本站文章为深圳网站建设·源美设计原创策划,如有版权纠纷或者违规问题,请联系我们删除,谢谢!

上一篇: 电源里的病毒

下一篇: 在网站制作中各种语言中的多态

返回列表
最新案例
OUR ADVANTAGE WORKS

售后响应及时

全国7×24小时客服热线

数据备份

更安全、更高效、更稳定

价格公道精准

项目经理精准报价不弄虚作假

合作无风险

重合同讲信誉,无效全额退款