PHPer善用接口与Trait
2019-07-24 08:57:59来源:编程学习网 阅读 ()
接口是两个php对象的契约。其目的不是让一个对象依赖另一个对象的身份,而是依赖另一个对象的能力。接口把我们的代码和依赖解耦,而且允许我们的代码依赖任何实现了预期接口的第三方代码。我们不关心第三方代码如何实现接口,只去关心他有没有去实现接口。
如果我们写的类去处理特定的对象, 那么类的功能就被限定了,只能处理那个类。但是我们的对象如果是处理的接口,那么代码立即就能知道如何处理实现这一接口的任何对象,我们的代码不管接口如何实现只需要关心有没有实现。
文档处理类实现
<?php class DocumentStore { protected $data = []; /** * 参数限定为 Documentable 对象,这是一个接口 */ public function addDocument(Documentable $document) { $key = $document->getId(); $value = $document->getContent(); $this->data[$key] = $value; } public function getDocuments() { return $this->data; } }
这个是我们的文档处理类,它面向的是接口操作 Documentable 实现:
<?php interface Documentable { public function getId(); public function getContent(); }
具体实现接口的类,比如是从html获得的文档 实现:
<?php class HtmlDocument implements Documentable { protected $url; public function __construct($url) { $this->url = $url; } public function getId() { return $this->url; } public function getContent() { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $this->url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_MAXREDIRS, 3); $html = curl_exec($ch); curl_close($ch); return $html; } }
读取流数据的文档 实现:
<?php class StreamDocument implements Documentable { protected $resource; protected $buffer; public function __construct($resource, $buffer = 4096) { $this->resource = $resource; $this->buffer = $buffer; } public function getId() { return 'resource-' . (int)$this->resource; } public function getContent() { $streamContent = ''; rewind($this->resource); while (feof($this->resource) === false) { $streamContent .= fread($this->resource, $this->buffer); } return $streamContent; } }
具体使用 :
<?php require 'Documentable.php'; require 'DocumentStore.php'; require 'HtmlDocument.php'; require 'StreamDocument.php'; require 'CommandOutputDocument.php'; $documentStore = new DocumentStore(); // Add HTML document $htmlDoc = new HtmlDocument('http://php.net'); $documentStore->addDocument($htmlDoc); // Add stream document $streamDoc = new StreamDocument(fopen('stream.txt', 'rb')); $documentStore->addDocument($streamDoc); // Add terminal command document $cmdDoc = new CommandOutputDocument('cat /etc/hosts'); $documentStore->addDocument($cmdDoc); print_r($documentStore->getDocuments());
需要说明的是参数类型 addDocument 参数类型限定为 Documentable 实现该接口的对象都可以做参数。
性状( trait )
性状是类的部分实现,可以混入一个或者多个现有的类实现中,有两个作用:
1表明类可以做什么;
2 提供模块化实现;
使用场景:
我们做面向对象的开发的时候都会通过基类实现基本功能,完后子类具体实现详细的功能,各类之间有明显的自然的继承关系,如果有一个逻辑既不属于A类也不属于B类,那么在性状出现之前我们怎么解决:
解决办法一:做一个父类 让A, B都继承,这样做的缺点是,强制把两个不相关的类继承同一父类,结构混乱破坏了封装。
解决方法二:做一个接口,让A, B都去实现这个接口,强于上一个方法,但是缺点是相同的逻辑会在多个类中实现,代码逻辑冗余,加大维护成本。
解决办法三:使用性状(trait)推荐做法。
定义性状:
<?php // 推荐把性状当类看待,一个文件定义一个性状 trait MyTrait { protected $p1; public $p2; public function f1() { } }
使用性状:
<?php class MyClass { use MyTrait; }
之后实例对象就可以使用性状里的属性方法就像使用本类的一样;php解释器会把性状的代码复制到类定义中,有点像c语言中的宏。
原文链接:http://www.phpxs.com/post/6307/
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:PHP 的 self 关键字
- Swagger 生成 PHP API 接口文档详细步骤 2019-09-23
- WebSocket 通信过程与实现,PHPer必备知识 2019-09-04
- Thinkphp5微信小程序获取用户信息接口的实例详解 2019-08-27
- 用PHP调用微博接口实现微博登录,可参考学习下! 2019-08-23
- PHP开发api接口安全验证的实例,值得一看 2019-08-23
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash