Laravel中存储库和接口的用法是什么?

Dre*_*een 25 php interface repository laravel laravel-5

在2年后使用Codeigniter开发了一些项目之后,我开始学习Laravel.

我下载了一些项目,了解它们是如何编码的.据我所知,他们中的许多人只使用与Codeigniter相同的模型,视图和控制器.

但是一个项目使用了存储库和接口.很难理解该项目的最新进展.那么Laravel中存储库和接口的用法是什么?我应该什么时候使用它们?

Des*_*901 21

我将尽可能清楚地解释这两个概念.

接口\合同

通常,OOP接口用于描述实现该接口的类提供哪些方法/功能而不关心实际实现.

Laravel Contracts主要用于将服务与实际实现分开.为了更清楚,让我们举个例子

<?php

namespace App\Orders;

class OrdersCache
{

    protected $cache;

    public function __construct(\SomePackage\Cache\Memcached $cache)
    {
        $this->cache = $cache;
    }


    public function find($id)
    {
        if ($this->cache->has($id))    {
            //
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您在此类中看到的,代码紧密耦合到缓存实现(即\SomePackage\Cache\Memcached),因此如果该Cache类的API更改我们的代码,则必须相应地更改.如果我们想要用另一个(例如redis)更改Cache实现,则会发生同样的事情.

我们的代码可能依赖于与实现无关的接口,而不是这样做:

<?php

namespace App\Orders;

use Illuminate\Contracts\Cache\Repository as Cache;

class OrdersCache
{

    public function __construct(Cache $cache)
    {
        $this->cache = $cache;
    }


    public function find($id)
    {
        if ($this->cache->has($id))    {
            //
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我们的代码没有与任何特定的实现耦合,因为Cache它实际上是一个接口.因此,基本上在我们的类中,我们需要一个类的实例,其行为类似于Cache接口中所描述的,但我们并不真正感兴趣它在内部如何工作.如果我们想要更改缓存实现,我们可以编写一个实现接口的类,Cache而不需要更改我们OrdersCache类中的任何代码行.这样做我们的代码更容易理解和维护,并且您的包可以更加可重用.请参见松耦合的Laravel文档进行进一步的例子英寸

接口和服务容器

Laravel的一个主要功能是它的Service Container,它用于管理依赖项和执行依赖项注入.请查看Laravel文档中的Service Container定义.

Laravel还广泛使用依赖注入将接口绑定到实现.我们举一个例子:

$app->bind('App\Contracts\EventPusher', 'App\Services\RedisEventPusher');
Run Code Online (Sandbox Code Playgroud)

让我们的班级成为

<?php

namespace App\Http\Controllers;

use App\Contracts\EventPusher;

class EventsController extends Controller 
{

    protected $pusher;

    public function __construct(EventPusher $pusher) 
    {

        $this->pusher = $pusher;        

    }

}
Run Code Online (Sandbox Code Playgroud)

在没有声明任何其他事情EventPusher情况下,RedisEventPusher我们基本上每次都说某人需要一个实例,请Laravel提供一个实例.在这种情况下,每次实例化控制器时,Laravel都会将一个实例传递RedisEventPusher给您的控制器,而不指定任何其他内容.

您可以通过查看Laravel文档中的Binding Interfaces to Implementation部分来深入研究.

存储库是独立于任何特定框架的适用于MVC模式的概念.通常,您的模型是数据层(例如,直接与数据库交互),Controller用于处理数据层的访问逻辑,View用于显示Controller提供的数据.

相反,存储库可以定义如下:

简单来说,Repository模式是一种存储数据访问逻辑的容器.它隐藏了业务逻辑中数据访问逻辑的细节.换句话说,我们允许业务逻辑访问数据对象,而无需了解底层数据访问体系结构.
Soruce:https://bosnadev.com/2015/03/07/using-repository-pattern-in-laravel-5

要了解如何在Laravel中使用它们,请查看这篇精彩的文章.

这就是全部,我希望有助于清理你的想法.


del*_*8uk 11

接口是任何实现类应该调用的接口.

interface CanFlyInterface
{
    public function fly();
}
Run Code Online (Sandbox Code Playgroud)

把它想象成编程而不用打扰逻辑.

if ($object instanceof CanFlyInterface) {
    $obj->fly();
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以传递一个Bird对象或一个Airplane对象!PHP没有关注,只要它实现了界面!

class Bird implements CanFlyInterface
{
    public function fly()
    {
        return 'flap flap!';
    }
}

class Aeroplane implements CanFlyInterface
{
    public function fly()
    {
        return 'roar! whoosh!';
    }
}
Run Code Online (Sandbox Code Playgroud)

你的另一个问题,Repository类是什么.它只是一个将所有数据库查询保存在一个位置的类.以此界面为例:

interface RepositoryInterface
{
    public function insert(array $data);
    public function update(array $data);
    public function findById($id);
    public function deleteById($id);
}
Run Code Online (Sandbox Code Playgroud)

希望这应该为你清理!祝你所有的PHP编码都好运:-D


cre*_*re8 5

让我们从一个简单的界面开始:

通常,您可以使用接口通过必需的方法来实现类:http : //php.net/manual/en/language.oop5.interfaces.php

Laravel的合同是一组定义框架提供的核心服务的接口。例如,Illuminate \ Contracts \ Queue \ Queue合同定义了排队作业所需的方法,而Illuminate \ Contracts \ Mail \ Mailer合同定义了发送电子邮件所需的方法。 https://laravel.com/docs/5.4/contracts#introduction

Laravel运行时,可以检查类是否实现了特殊接口:

if ($cls instanceof IInterface) {
    $cls->interfaceFunction();
}
Run Code Online (Sandbox Code Playgroud)

由于Laravel能够处理队列,它将通过检查退出的接口来检查事件是否应该排队。

要通知Laravel应广播给定事件,请在事件类上实现Illuminate \ Contracts \ Broadcasting \ ShouldBroadcast接口。 https://laravel.com/docs/5.4/broadcasting#defining-broadcast-events

仓库:

我没有发现太多有关此的内容:

我们的存储库对于由谁提供数据或如何提供数据的知识应该不多。https://laravel.com/docs/5.4/contracts#loose-coupling

但是我在网页上发现了一些其他信息:

存储库将工厂与网关https://code.tutsplus.com/tutorials/the-repository-design-pattern--net-35804连接起来

该链接将为您提供有关详细信息的更多信息。

希望我能为您提供帮助:)


Abh*_*xit 5

首先,在更大的应用程序中使用存储库和接口不仅是Laravel的受益者,而且是编码标准的所有技术以及关注点的分离.

根据微软(我在这里找到了最好的解释)

为什么要使用Repository:

使用存储库分离检索数据的逻辑,并将其从作用于模型的业务逻辑映射到实体模型.业务逻辑应该与包含数据源层的数据类型无关.存储库在数据源层和应用程序的业务层之间进行调解.它在数据源中查询数据,将数据从数据源映射到业务实体,并将业务实体中的更改持久保存到数据源.
存储库将业务逻辑与与底层数据源或Web服务的交互分开.数据和业务层之间的分离有三个好处:它集中了数据逻辑或Web服务访问逻辑.它为单元测试提供了替换点.它提供了一种灵活的架构,可以随着应用程序的整体设计的发展而进行调整.存储库可以通过两种方式查询业务实体.它可以向客户端的业务逻辑提交查询对象,也可以使用指定业务标准的方法.在后一种情况下,存储库代表客户端形成查询.存储库返回满足查询的匹配实体集.

对于Interface,你上面有很多答案,希望你能理解.