
简介
Laravel 中的契约是指框架提供的一系列定义核心服务的接口。 例如,Illuminate\Contracts\Queue\Queue 契约定义了队列任务需要实现的方法,Illuminate\Contracts\Mail\Mailer 契约定义了发送邮件所需要实现的方法。
契约 Vs. 门面
不同于门面不需要再构造器中进行类型提示,契约允许你在类中定义显式的依赖。有些开发者喜欢门面带来的便捷,也有些开发者倾向于使用契约,他们喜欢定义明确的依赖。
注:大多数应用中,不管你使用门面还是契约,合适就好。不过,如果你是在构建一个扩展包,那么就应该使用契约,因为更容易测试。
何时使用契约
正如上面所讨论的,大多数情况下使用契约还是门面取决于个人或团队的喜好,契约和门面都可以用于创建强大的、测试友好的 Laravel 应用。只要你保持类的职责单一,你会发现使用契约和门面并没有什么实质性的差别。
但是,对契约你可能还是有些疑问。例如,为什么要全部使用接口?使用接口是不是更复杂?下面让我们从两个方面来扒一扒为什么使用接口:松耦合和简单。
松耦合
首先,让我们看看一些缓存实现的紧耦合代码:
xxxxxxxxxx
1
2
3
namespaceApp\Orders;
4
5
classRepository
6
{
7
/**
8
* 缓存
9
*/
10
protected$cache;
11
12
/**
13
* 创建一个新的Repository实例
14
*
15
* @param \SomePackage\Cache\Memcached $cache
16
* @return void
17
*/
18
publicfunction__construct(\SomePackage\Cache\Memcached$cache)
19
{
20
$this->cache=$cache;
21
}
22
23
/**
24
* 通过ID获取订单
25
*
26
* @param int $id
27
* @return Order
28
*/
29
publicfunctionfind($id)
30
{
31
if ($this->cache->has($id)) {
32
//
33
}
34
}
35
}
在这个类中,代码和给定缓存实现紧密耦合,由于我们基于一个来自包的具体的缓存类,如果包的API变了,那么相应的,我们的代码必须做修改。
类似的,如果我们想要替换底层的缓存技术(Memcached)为别的技术实现(Redis),我们将再一次不得不修改我们的代码库。我们的代码库应该并不知道谁提供的数据或者数据是怎么提供的。
我们可以基于一种简单的、与提供者无关的接口来优化我们的代码,从而替代上述那种实现:
xxxxxxxxxx
1
2
3
namespaceApp\Orders;
4
5
useIlluminate\Contracts\Cache\RepositoryasCache;
6
7
classRepository
8
{
9
/**
10
* 创建一个新的Repository实例
11
*
12
* @param Cache $cache
13
* @return void
14
*/
15
publicfunction__construct(Cache$cache)
16
{
17
$this->cache=$cache;
18
}
19
}
现在代码就不与任何特定提供者耦合,甚至与 Laravel 都是无关的。由于契约包不包含任何实现和依赖,你可以轻松的为给定契约编写可选实现代码,你可以随意替换缓存实现而不用去修改任何缓存消费代码。
简单
当所有 Laravel 服务都统一在简单接口中定义,很容易判断给定服务提供的功能。契约可以充当框架特性的简明文档。
此外,基于简单接口,代码也更容易理解和维护。在一个庞大而复杂的类中,与其追踪哪些方法是有效的,不如转向简单、干净的接口。
如何使用契约
那么,如何实现契约呢?这很简单。
例如,看看下面这个事件监听器:
xxxxxxxxxx
1
2
3
namespaceApp\Listeners;
4
5
useApp\User;
6
useApp\Events\OrderWasPlaced;
7
useIlluminate\Contracts\Redis\Database;
8
9
classCacheOrderInformation
10
{
11
/**
12
* The Redis database implementation.
13
*/
14
protected$redis;
15
16
/**
17
* Create a new event handler instance.
18
*
19
* @param Database $redis
20
* @return void
21
*/
22
publicfunction__construct(Database$redis)
23
{
24
$this->redis=$redis;
25
}
26
27
/**
28
* Handle the event.
29
*
30
* @param OrderWasPlaced $event
31
* @return void
32
*/
33
publicfunctionhandle(OrderWasPlaced$event)
34
{
35
//
36
}
37
}
契约列表
下面是 Laravel 契约列表,以及其对应的“门面”:
契约
|
对应门面
|
||||||
Illuminate\Contracts\Auth\Access\Authorizable
|
|||||||
Illuminate\Contracts\Auth\Access\Gate
|
Gate
|
||||||
Illuminate\Contracts\Auth\Authenticatable
|
|||||||
Illuminate\Contracts\Auth\CanResetPassword
|
|||||||
Illuminate\Contracts\Auth\Factory
|
Auth
|
||||||
Illuminate\Contracts\Auth\Guard
|
Auth::guard()
|
||||||
Illuminate\Contracts\Auth\PasswordBroker
|
Password::broker()
|
||||||
Illuminate\Contracts\Auth\PasswordBrokerFactory
|
Password
|
||||||
Illuminate\Contracts\Auth\StatefulGuard
|
|||||||
Illuminate\Contracts\Auth\SupportsBasicAuth
|
|||||||
Illuminate\Contracts\Auth\UserProvider
|
|||||||
Illuminate\Contracts\Bus\Dispatcher
|
Bus
|
||||||
Illuminate\Contracts\Bus\QueueingDispatcher
|
Bus::dispatchToQueue()
|
||||||
Illuminate\Contracts\Broadcasting\Factory
|
Broadcast
|
||||||
Illuminate\Contracts\Broadcasting\Broadcaster
|
Broadcast::connection()
|
||||||
Illuminate\Contracts\Broadcasting\ShouldBroadcast
|
|||||||
Illuminate\Contracts\Broadcasting\ShouldBroadcastNow
|
|||||||
Illuminate\Contracts\Cache\Factory
|
Cache
|
||||||
Illuminate\Contracts\Cache\Lock
|
|||||||
Illuminate\Contracts\Cache\LockProvider
|
|||||||
Illuminate\Contracts\Cache\Repository
|
Cache::driver()
|
||||||
Illuminate\Contracts\Cache\Store
|
|||||||
Illuminate\Contracts\Config\Repository
|
Config
|
||||||
Illuminate\Contracts\Console\Application
|
|||||||
Illuminate\Contracts\Console\Kernel
|
Artisan
|
||||||
Illuminate\Contracts\Container\Container
|
App
|
||||||
Illuminate\Contracts\Cookie\Factory
|
Cookie
|
||||||
Illuminate\Contracts\Cookie\QueueingFactory
|
Cookie::queue()
|
||||||
Illuminate\Contracts\Database\ModelIdentifier
|
|||||||
Illuminate\Contracts\Debug\ExceptionHandler
|
|||||||
Illuminate\Contracts\Encryption\Encrypter
|
Crypt
|
||||||
Illuminate\Contracts\Events\Dispatcher
|
Event
|
||||||
Illuminate\Contracts\Filesystem\Cloud
|
Storage::cloud()
|
||||||
Illuminate\Contracts\Filesystem\Factory
|
Storage
|
||||||
Illuminate\Contracts\Filesystem\Filesystem
|
Storage::disk()
|
||||||
Illuminate\Contracts\Foundation\Application
|
App
|
||||||
Illuminate\Contracts\Hashing\Hasher
|
Hash
|
||||||
Illuminate\Contracts\Http\Kernel
|
|||||||
Illuminate\Contracts\Logging\Log
|
Log
|
||||||
Illuminate\Contracts\Mail\MailQueue
|
Mail::queue()
|
||||||
Illuminate\Contracts\Mail\Mailable
|
|||||||
Illuminate\Contracts\Mail\Mailer
|
Mail
|
||||||
Illuminate\Contracts\Notifications\Dispatcher
|
Notification
|
||||||
Illuminate\Contracts\Notifications\Factory
|
Notification
|
||||||
Illuminate\Contracts\Pagination\LengthAwarePaginator
|
|||||||
Illuminate\Contracts\Pagination\Paginator
|
|||||||
Illuminate\Contracts\Pipeline\Hub
|
|||||||
Illuminate\Contracts\Pipeline\Pipeline
|
|||||||
Illuminate\Contracts\Queue\EntityResolver
|
|||||||
Illuminate\Contracts\Queue\Factory
|
Queue
|
||||||
Illuminate\Contracts\Queue\Job
|
|||||||
Illuminate\Contracts\Queue\Monitor
|
Queue
|
||||||
Illuminate\Contracts\Queue\Queue
|
Queue::connection()
|
||||||
Illuminate\Contracts\Queue\QueueableCollection
|
|||||||
Illuminate\Contracts\Queue\QueueableEntity
|
|||||||
Illuminate\Contracts\Queue\ShouldQueue
|
|||||||
Illuminate\Contracts\Redis\Factory
|
Redis
|
||||||
Illuminate\Contracts\Routing\BindingRegistrar
|
Route
|
||||||
Illuminate\Contracts\Routing\Registrar
|
Route
|
||||||
Illuminate\Contracts\Routing\ResponseFactory
|
Response
|
||||||
Illuminate\Contracts\Routing\UrlGenerator
|
URL
|
||||||
Illuminate\Contracts\Routing\UrlRoutable
|
|||||||
Illuminate\Contracts\Session\Session
|
Session::driver()
|
||||||
Illuminate\Contracts\Support\Arrayable
|
|||||||
Illuminate\Contracts\Support\Htmlable
|
|||||||
Illuminate\Contracts\Support\Jsonable
|
|||||||
Illuminate\Contracts\Support\MessageBag
|
|||||||
Illuminate\Contracts\Support\MessageProvider
|
|||||||
Illuminate\Contracts\Support\Renderable
|
|||||||
Illuminate\Contracts\Support\Responsable
|
|||||||
Illuminate\Contracts\Translation\Loader
|
|||||||
Illuminate\Contracts\Translation\Translator
|
Lang
|
||||||
Illuminate\Contracts\Validation\Factory
|
Validator
|
||||||
Illuminate\Contracts\Validation\ImplicitRule
|
|||||||
Illuminate\Contracts\Validation\Rule
|
|||||||
Illuminate\Contracts\Validation\ValidatesWhenResolved
|
|||||||
Illuminate\Contracts\Validation\Validator
|
Validator::make()
|
||||||
Illuminate\Contracts\View\Engine
|
|||||||
Illuminate\Contracts\View\Factory
|
View
|
||||||
Illuminate\Contracts\View\View
|
View::make()
|
摘自:https://xueyuanjun.com/post/8621