Laravel深入学习3 - 接口约定
声明:本文并非博主原创,而是来自对《Laravel 4 From Apprentice to Artisan》阅读的翻译和理解,当然也不是原汁原味的翻译,能保证90%的原汁性,另外因为是理解翻译,肯定会有错误的地方,欢迎指正。
欢迎转载,转载请注明出处,谢谢!
接口约定
强类型和弱类型
Water Fowl 这里我不知道该怎么翻译,按理解就将他翻译成弱类型?
之前的文章中,涵盖了依赖注入的基础知识:什么是依赖注入;如何实现;以及他有什么好处。在举例的代码中,也展示了如何将接口注入到类之中。在我们继续深入之前,有必要深入一下接口相关的内容,因为很多PHP开发人员对接口都有相当程度的不熟练。
在我成为一个PHP程序员之前,我是写.NET的。难道我喜欢痛苦或者其他什么的么?在.NET中接口无处不在,事实上.NET框架的很多核心内容就是接口,还有一个好处:很多象.NET的语言如C#、VB等都是_强类型_的。通常,传入方法的原生对象,必须预先定义好相关的_类型_。例如下面的C#代码:
public int BillUser(User user)
{this.biller.bill(user.GetId(), this.amount)
}
我们不仅定义了传入参数的_类型_,函数返回的类型都是已经定义好的。C#提倡_安全类型_。函数BillUser
方法传入的参数必须是User
对象。
PHP是一种_弱类型_语言。在弱类型语言中,对象中可用的方法取决于其方法的使用形式,而非方法继承或者实现的位置。例如:
public function billUser($user)
{$this->biller->bill($user->getId(), $this->amount);
}
我们无需告诉方法类型的参数是什么,我们可以传入任意对象,只要他有getId
方法就行。这就是弱类型编码的例子。如果一个东西看起来象鸭子,叫声也象,那么他就是一个鸭子。换言之,如果一个对象象user,行为也象user,那么他就是一个user对象。
难道,PHP就没有强类型特征?答案是明确的,肯定有!PHP其实是一种强类型和弱类型的结合体。为了说明这一点,我们修改下上例的代码:
public function billUser(User $user)
{$this->biller->bill($user->getId(), $amount);
}
在方法参数中,加入User
约定后,就能确保传入方法的参数必须是User
的实例化对象或者是继承自User
的一个实例。
两种类型各有优劣。强类型语言中,编译器通常提供编译检查错误的功能,它也是非常有用的。方法的输入和输出都是明确的。
与此同时,强类型的代码看起来也是很生硬的。比如Eluquent ORM中提供的动态方法whereEmailOrName
就不能象C#那样明确参数和返回值的类型。这里不讨论孰优孰劣,我们各取所长,但是,不假思索的死认某一种方式肯定会埋下很多坑。
示例
接口就是约定,他不包含具体的代码实现,而定义了对象需要实现的一系列的方法。如果一个对象实现了某个接口,那么这个接口的方法肯定都能在这个实例对象中使用。通过约定固化了某些方法的实现,这种_多态_就能保证语言的类型安全。
什么是多态?
多态含义很广,可以理解为一种实体的多种形式。在本书中,我们指代接口的多种实现方式。例如:
UserRepositoryInterface
可以有MySQL和Redis两种存储实现方式,但是每一种都是UserRepositoryInter
接口的实现。
为了说明强类型在接口中的灵活和重要性,我们来实现如下一个酒店预订的例子:
interface ProviderInterface
{public function getLowestPrice($location);public function book($location);
}
当用户预订房间是,我们想将此事件记录到系统中。我们在User
类中添加如下方法:
class User
{public function bookLocation(ProviderInterface $provider, $location){$amountCharged = $provider->book($location);$this->logBookedLocation($location, $amountCharged);}
}
我们限定了参数$provider
的类型,User
类中就能假定book
方法是可安全调用的,这就使得bookLocation
有较强的操作性,我们不用关心酒店是如何实现房间预订这一过程。下面的代码就能体现这一特性:
$location = 'Hilton, Dallas';$cheapestProvider = $this->findCheapest($location, array(new PricelineProvider,new OrbitzProvider,
));$user->bookLocation($cheapestProvider, $location);
赞!我们不用关心那家酒店最便宜,只需要将他传入User
实例中就能成功预订房间。因为User
对象要求传入的参数是继承自ProviderInterface
的对象,未来添加更多的酒店提供商,都能使我们的代码稳定的运行。
忘掉细节
记住,接口_不实现_任何细节,只是简单的定义类必须实现的方法。
接口和团队开发
当团队构建大型应用时,不同的模块进程是不同的。比如,有人处理数据层,有人处理前端web、控制器层。前端开发项测试自己的控制器,但是后端人员开发进度缓慢。但是,如果我们能约定好接口,后端人员只须遵循接口定义:
interface OrderRepositoryInterface
{public function getMostRecent(User $user);
}
一旦约定了接口,前端开发人员,在代码没有实现的情况下,也能测试自己的控制器!这样整个应用中就不用担心不同模块的开发进度,也不会影响到正常的测试用例的编写。更深一点来说,这种方法不会影响到其他组件的开发,做到了无知是福。我们不需要让我们的类必须知道其他类是_怎么_实现的,只需要知道他_能够_干什么。现在,我们已经定义了接口,那么我们可以继续我们控制器代码的实现了:
class OrderController
{public function __construct(OrderRepositoryInterface $orders){$this->orders = $orders;}public function getRecent(){$recent = $this->orders->getMostRecent(Auth::user());return View::make('orders.recent', compact('recent'));}
}
前端开发人员可以自己实现一个“假”接口,来测试应用试图中需要填充的数据。
class DummyOrderRepository implements OrderRepositoryInterface
{public function getMostRecent(User $user){return array('Order 1', 'Order 2', 'Order 3');}
}
接口实现之后,我们就能将其绑定到容器中,就能在整个应用中使用他了:
App::bind('OrderRepositoryInterface', 'DummyOrderRepository');
当后端开发人员实现了他的模块,比如:RedisOrderRepository
。我们再次通过修改绑定将其应用到项目之中。
接口大纲
接口在被用来定义项目“骨架”上是非常有用的。在项目组件设计阶段可以促进团队间设计讨论。比如定义
BillingNotifierInterface
接口,并讨论接口相应的方法,在敲代码前就能用接口定义出一套好的API。
Laravel深入学习3 - 接口约定相关推荐
- 某小公司RESTful、共用接口、前后端分离、接口约定的实践
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:邵磊 juejin.im/post/59eafab36fb9 ...
- 向军2017年最新laravel开发宝典 laravel结合vue与接口开发webapp实战视频教程
课程介绍: Laravel是一套简洁.优雅的PHP Web开发框架(PHP Web Framework).它不仅可以让我们从面条一样杂乱的代码中解脱出来,还可以帮我们构建一个完美的网络APP,而且每行 ...
- 接口入参形式_某小公司RESTful、共用接口、前后端分离、接口约定的实践
点击上方"后端技术精选",选择"置顶公众号" 技术文章第一时间送达! 作者:邵磊 juejin.im/post/59eafab36fb9a045076eccc3 ...
- Laravel POST请求API接口 使用validate表单验证返回欢迎页
突然遇到的问题 就是使用Laravel进行开发API接口的时候 发现在表单验证不通过的时候返回了登录页 猜测问题应该是因为表单验证失败后进行了重定向导致的 因为返回状态码200 网上找了好久没找到 ...
- 某小公司 RESTful、共用接口、前后端分离、接口约定的实践
前言 随着互联网高速发展,公司对项目开发周期不断缩短,我们面对各种需求,使用原有对接方式,各端已经很难快速应对各种需求,更难以提高效率.于是,我们不得不重新制定对接规范.开发逻辑以便快速上线项目. 我 ...
- typescript 接口 java_[Java教程]【TypeScript】TypeScript 学习 2——接口
[Java教程][TypeScript]TypeScript 学习 2--接口 0 2015-06-19 12:00:28 在 TypeScript 中,接口是用作约束作用的,在编译成 JavaScr ...
- laravel database.php,php Laravel框架学习(一) 之 建立数据库并填充测试数据
php Laravel框架学习(一) php Laravel框架学习之Laravel 建立数据库并填充测试数据 建立数据库 前面我们已经明确目标网站的基本功能,现在我们先来建立它的数据库. 设计数据库 ...
- Selenium学习 - WebDriver接口
Selenium学习 - WebDriver接口 一.WebDriver的初始化 def __init__(self, command_executor='htt ...
- Selenium学习 - WebElement接口
Selenium学习 - WebElement接口 WebElement对象代表了一个DOM元素. 一.WebElement的属性 tag_name --- 元素的tagName属性 text ...
- Selenium学习 - ActionChains接口
Selenium学习 - ActionChains接口 ActionChains实现了with上下文对象接口. 一.行为控制 perform --- 执行所有准备好的Action reset_ ...
最新文章
- js 设计模式与继承学习
- 关于范式的一些简单理解
- JavaScript语言基础10
- Ueditor富文本添加视频内容,视频不显示以及编辑富文本时,视频不显示解决方案
- DirectX 高级着色语言HLSL入门
- ai边缘平滑_华为P40的多帧曝光AI智能处理,逆光也能无法阻挡你的美
- VTK:PolyData之PointLocatorRadius
- VMware连续三年获评Gartner广域网边缘基础设施魔力象限领导者
- 线程安全使用相关注意事项
- ios11最新版本_iOS11.2.5 beta6怎么升级 哪些设备可以升级iOS11.2.5系统【详解】
- 亚马逊 kindle 刷机 过程记录
- 手把手教你实现嵌入式SNMP代理第1部分-熊健-专题视频课程
- 最全的珍贵的四大天王合照和成名历程 - 很怀念【组图】
- 计算机如何连接wifi台式,台式机怎么连接wifi_台式机连接wifi教程-太平洋IT百科...
- java控制语句_java基础之 控制语句
- bxSlider——一个精悍的拥有一大波焦点图轮播滑动特效的Js程序
- 黑马程序员————高新技术————反射
- 吴恩达机器学习作业1-线性回归讲解版奔雷手
- 苹果怎么换个性化主题
- FLUKE LinkIQ-100 CH/福禄克LIQ-100 CH可以出测试报告