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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • FileSystemWatcher触发多次Change事件的解决办法

    FileSystemWatcher触发多次Change事件的解决办法FileSystemWatcher监视文件夹中数据变化时,会多次出发Change事件。EnableRaisingEvents=true,启动文件监控,网上查到的做法是通过一个定时器来避免多次触发。其实可以通过,在第一次触发后EnableRaisingEvents=false先关闭在打开EnableRaisingEvents=true,简单解决这个问题。

    2022年6月18日
    26
  • Java 单例模式[通俗易懂]

    Java 单例模式[通俗易懂]单例模式(SingletonPattern)是Java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。注意:1、单例类只能有一个实例。 2、单例类必须自己创建自己的唯一实例。 3、单例类必须给所有其他对象提供这一实例。…

    2022年7月9日
    20
  • 深入理解FT,DTFT,DFT 之间的关系[通俗易懂]

    学习了数字信号处理之后,被里面的几个名词搞的晕头转向,比如DFT、DTFT、FS、FT、FFT、DFS等,参考整理的资料,重新写了一下各种变换的概念。 学过卷积,我们都知道有时域卷积定理和频域卷积定理,在这里只需要记住两点:1.在一个域的相乘等于另一个域的卷积;2.与脉冲函数的卷积,在每个脉冲的位置上将产生一个波形的镜像。(在任何一本信号与系统课本里,此两条性质有详细公式证明) 下面,就用这两…

    2022年4月3日
    224
  • 分布式计算概述_分布式计算与处理

    分布式计算概述_分布式计算与处理**分布式计算是当前计算机领域常见的名词,那么到底什么是分布式,什么又是分布式计算呢?今天和大家共同研究一下这个话题。**分布式计算的概念一个分布式系统是由若干通过网络互联的计算机组成的软硬件系统,且这些计算机互相配合以完成一个共同目标(往往这个共同目标称为“项目”)分布式计算的优缺点优点:1.超大规模2.虚拟化3.高可靠性4.通用性5.高伸缩性6.按需服务7….

    2025年8月7日
    1
  • Code Coverage 小结

    Code Coverage 小结在软件测试中 CodeCoverage 常常作为公司衡量软件测试是否充分的一个指标 这其中包括 UTCoverage TestAutomati 下面我列举出常用编程语言所用的 coveragetool 编程语言 工具 评论 LinuxC gcov lcov nbsp Window

    2025年8月25日
    3
  • E: Sub-process /usr/bin/dpkg returned an error code (1)解决办法

    E: Sub-process /usr/bin/dpkg returned an error code (1)解决办法E:Sub-process/usr/bin/dpkgreturnedanerrorcode(1)解决办法安装libapache2-svn出现了这个错误,是由于apt-get安装软件时出现了类似于:dpkg:errorprocessingpackagelibapache2-mod-svn(–configure):subprocessinstalledpost-i…

    2025年7月24日
    3

发表回复

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

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