Laravel核心内容:契约,你了解多少?

Laravel核心内容:契约,你了解多少?

大家好,又见面了,我是全栈君。

接口如同契约。接口并不包含任何代码实现,只是定义了一个实现该接口的对象必须实现的一系列方法。

如果一个对象实现了一个接口,那么我们就能保证这个接口所定义的一系列方法都能在这个对象上调用。

由于有接口契约保证特定方法的实现,通过多态也能使类型安全的语言变得更灵活。

关于多态:多态含义很广,从本质上说,是一个实体拥有多种形式。在本书中,我们讲多态说的是一个接口有多钟实现方式。例如,UserRepositoryInterface 可以有 MySQL 和 Redis 两种实现,并且每一种实现都是 UserRepositoryInterface 的一个实例。

为了说明接口在强类型语言中的灵活性,我们们来写一个简单的酒店客房预订代码。考虑以下接口:(代码可滑动查看)

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 类的 bookLocation 方法中,就可以放心大胆的认为 $provider 实例上的 book 方法是可以调用的。

这给我们复用 bookLocation 方法带来了灵活性,完全不必关心用户倾向哪家酒店提供商。最后,我们编写一些代码来体验下这种灵活性:(代码可滑动查看)

$location = '希尔顿, 达拉斯';

$cheapestProvider = $this->findCheapest($location, array(
    new PricelineProvider,
    new OrbitzProvider,
));

$user->bookLocation($cheapestProvider, $location);

不管哪家酒店是最便宜的,我们都能够将它传入 User 对象来预订房间了。由于 User 对象只需要有一个遵从 ProviderInterface 契约的对象实例就可以了,所以未来如果有新的酒店供应商,我们的代码也可以很好的工作。

忘掉细节:记住,接口实际上并不做任何事情。它只是简单的定义了实现类必须拥有的一系列方法。

构建大型应用

当你的团队在构建大型应用时,不同的功能模块往往有着不同的开发进度。例如,一个开发人员在开发数据层,另一个开发人员在做前端和控制器层。前端开发者想要测试他的控制器,但是后端开发进度比较慢,无法联调。

如果这两个开发者能以接口或契约的方式达成协议,然后后端开发的所有类都遵循这种协议,就像下面这段代码:(代码可滑动查看)

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');
    }
}

编写好假实现之后,就可以在服务容器里将其绑定到契约上,然后在整个应用中都可以调用它了:(代码可滑动查看)

$this->app->bind(OrderRepositoryInterface::class, function ($app) {
    return new DummyOrderRepository();
});

接下来,如果后台开发者写完了真正的实现代码,如RedisOrderRepository。服务容器中的绑定可以轻松切换到新的实现,整个应用将会使用开始从 Redis 读取出来的订单数据。

接口即纲领:接口有助于开发应用所提供的、已定义好的功能「框架」。 在组件的设计阶段,团队里使用接口进行讨论是很方便的,例如,定义一个 BillingNotifierInterface 接口,然后讨论它提供哪些方法。在编写任何实现代码前,最好先通过接口讨论达成一致,这是构建一套好 API 的必要前提!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/111527.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • qt中readyread信号的使用_心动的信号cp组合有哪些

    qt中readyread信号的使用_心动的信号cp组合有哪些本文主要介绍readyread函数的触发机制,会涉及到一点tcp/ip和流的知识。tcp/ip和流这方面其他朋友介绍很多了,这里我就不再赘述。本文不打算使用太过专业的词汇,一方面主要目的是让大家明白,另一方面是我也不太专业。一、问题描述:你之所以会来看我这篇文章,大概是遇到了一下几个问题:1、使用QTcpSocket时,readyread函数没有触发,或者触发了,但是触发次数不是自己想…

    2022年9月9日
    0
  • 制作WIN7+XP+DOS+PE多系统启动光盘

    制作WIN7+XP+DOS+PE多系统启动光盘本文详细介绍了怎样制作自定义的多系统启动光盘的流程,从零开始!达到完成系统盘制作的目的。

    2022年7月26日
    11
  • hibernate二级缓存(一)一级缓存与二级缓存

    hibernate二级缓存(一)一级缓存与二级缓存hibernate二级缓存(一)一级缓存与二级缓存1.hibernate一级缓存hibernate的一级缓存是session级别的缓存,一级缓存hibernate默认启用且不能被卸载,一个事务内有效。特点:使用一级缓存的目的是为了减少对数据库的访问次数,从而提升hibernate的执行效率;(当执行一次查询操作的时候,执行第二次查询操作,先检查缓存中是否有数据,如果有数据就不查询数据库…

    2022年5月24日
    34
  • Web中常用的Javascript技巧(1)「建议收藏」

    Web中常用的Javascript技巧(1)

    2022年3月8日
    35
  • Python量化交易学习笔记(50)——程序化交易1

    Python量化交易学习笔记(50)——程序化交易1easytrader安装pipinstalleasytrader下载安装e海通财PC独立交易版

    2022年10月8日
    0
  • 360天擎卸载方法[通俗易懂]

    360天擎卸载方法[通俗易懂]具体方法如下:1、先找到360天擎软件的安装文件夹,通常是:C:\ProgramFiles(x86)\360\360Safe\EntClient\conf2、先下载我们使有记事本打开目录下的EntBase.dat文件[base]persistent_connetion=closeshow_tip=1net_env=1communication_interval=900[api_frequency]checkupdate=180get_client_tasks=180getconf=

    2022年9月25日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号