Verträge
Laravel Der Vertrag besteht aus einer Reihe von Schnittstellen, die vom Framework bereitgestellt werden und die Kerndienste definieren. Beispielsweise definiert der
-Vertrag die Methoden, die zum Einreihen von Aufgaben in die Warteschlange erforderlich sind, und der-Vertrag definiert die Methoden, die zum Versenden von E-Mails erforderlich sind. IlluminateContractsQueueQueue
IlluminateContractsMailMailer
Jeder Vertrag verfügt über eine Implementierung, die durch das entsprechende Framework bereitgestellt wird. Laravel bietet beispielsweise mehrere Implementierungen von Treiberwarteschlangen und verwendet SwiftMailer zur Implementierung von E-Mail-Verträgen.
Alle Laravel-Verträge befinden sich in
ihren jeweiligen GitHub-Repositories. Dies bietet einen schnellen Referenzeintrag für alle verfügbaren Verträge und ein einzelnes, entkoppeltes Paket, das Entwickler von Erweiterungspaketen verwenden können.
Verträge vs. Fassaden
Fassaden und Hilfsfunktionen von Laravel bieten eine einfache Möglichkeit, Laravel-Dienste ohne Typhinweise zu nutzen und können auch Verträge außerhalb des Service-Containers auflösen. In den meisten Fällen hat jede Fassade einen gleichwertigen Vertrag.
Im Gegensatz zu Facades (bei denen der Konstruktor in Ihrer Klasse nicht auf Abhängigkeiten verweisen muss) können Sie mit Verträgen explizite Abhängigkeiten für Ihre Klasse definieren. Einige Entwickler bevorzugen klar definierte Abhängigkeiten und bevorzugen daher die Verwendung von Verträgen, während andere Entwickler den Komfort von Fassaden schätzen.
{tip} Bei den meisten Anwendungen ist es in Ordnung, ob Sie Fassaden oder Verträge bevorzugen. Wenn Sie jedoch ein Erweiterungspaket erstellen, sollten Sie unbedingt die Verwendung von Verträgen in Betracht ziehen, da diese das Testen im Kontext des Pakets erleichtern.
Wann sollten Verträge eingesetzt werden
Um es zusammenzufassen, ob Verträge oder Fassaden im Großen und Ganzen genutzt werden sollen Umfang Hängt von Ihren persönlichen oder Teampräferenzen ab. Sowohl Contracts als auch Facades können verwendet werden, um robuste, gut getestete Laravel-Anwendungen zu erstellen. Solange Sie die Verantwortlichkeiten Ihrer Klasse einfach halten, werden Sie feststellen, dass der tatsächliche Unterschied zwischen der Verwendung von Verträgen und Fassaden sehr gering ist.
Allerdings haben Sie möglicherweise noch viele Fragen zum Vertrag. Warum verwenden Sie beispielsweise die Schnittstelle? Ist die Verwendung der Benutzeroberfläche nicht komplizierter? Lassen Sie uns die Gründe im folgenden Inhalt extrahieren („geringe Kopplung“ und „Einfachheit“).
Geringe Kopplung
Schauen wir uns zunächst einen Code mit hoher Kopplung für die Cache-Implementierung an. Angenommen, wir haben den folgenden Code:
<?php namespace App\Orders; class Repository{ /** * 缓存实例. */ protected $cache; /** * 创建一个新的仓库实例. * * @param \SomePackage\Cache\Memcached $cache * @return void */ public function __construct(\SomePackage\Cache\Memcached $cache) { $this->cache = $cache; } /** * 根据 ID 获取订单. * * @param int $id * @return Order */ public function find($id) { if ($this->cache->has($id)) { // } } }
In dieser Klasse ist der Code stark an die gegebene Cache-Implementierung gekoppelt. Es ist stark gekoppelt, da wir auf eine bestimmte Cache-Klasse in einem Erweiterungspaket angewiesen sind. Wenn sich die API der Erweiterung ändert, muss sich auch unser Code ändern.
In ähnlicher Weise müssen wir unsere Codebasis erneut ändern, wenn wir die zugrunde liegende Caching-Technologie (Memcached) durch eine andere Caching-Technologie (Redis) ersetzen möchten. Unsere Codebasis sollte nicht zu viel darüber wissen, wer die Daten bereitgestellt hat oder wie die Daten bereitgestellt wurden.
Wir können unseren Code verbessern, indem wir uns auf eine einfache erweiterungsunabhängige Schnittstelle verlassen, um die vorherige Implementierung zu ersetzen:
<?php namespace App\Orders; use Illuminate\Contracts\Cache\Repository as Cache; class Repository{ /** * 缓存实例. */ protected $cache; /** * 创建一个新的仓库实例. * * @param Cache $cache * @return void */ public function __construct(Cache $cache) { $this->cache = $cache; } }
Der aktuelle Code stimmt nicht mit einem bestimmten Erweiterungspaket überein gekoppelt, nicht einmal mit Laravel verwandt. Da das Vertragserweiterungspaket keine Implementierungen und Abhängigkeiten enthält, können Sie problemlos eine alternative Implementierung für einen bestimmten Vertrag codieren und so die zwischengespeicherte Implementierung ersetzen, ohne den Cache-Code zu ändern.
Einfach
Wenn alle Dienste von Laravel sauber in einfachen Schnittstellen definiert sind, ist es einfach, die von einem bestimmten Dienst bereitgestellte Funktionalität zu bestimmen. Der Vertrag dient als prägnantes Dokument der Funktionalität des Frameworks.
Wenn Sie sich außerdem auf einfache Schnittstellen verlassen, ist Ihr Code einfacher zu verstehen und zu warten. Anstatt nachzuverfolgen, welche Methoden in großen, komplexen Klassen verfügbar sind, können Sie auf eine einfache, saubere Schnittstelle zurückgreifen.
Wie verwende ich einen Vertrag?
Wie setzt man also einen Vertrag um? Eigentlich ist es ganz einfach.
Viele Arten von Klassen in Laravel werden über den Service-Container aufgelöst, darunter Controller, Event-Listener, Middleware, Warteschlangenjobs und sogar Routing-Abschlüsse usw. Um dann die Implementierung eines Vertrags zu erhalten, müssen Sie nur noch die Schnittstelle „Typhinweis“ in den Konstruktor der aufzulösenden Klasse eingeben.
Sehen Sie sich zum Beispiel diesen Ereignis-Listener an:
<?php namespace App\Listeners; use App\User;use App\Events\OrderWasPlaced; use Illuminate\Contracts\Redis\Factory; class CacheOrderInformation{ /** * Redis 工厂实现。 */ protected $redis; /** * 创建一个新的事件处理器实例。 * * @param Factory $redis * @return void */ public function __construct(Factory $redis) { $this->redis = $redis; } /** * 处理事件。 * * @param OrderWasPlaced $event * @return void */ public function handle(OrderWasPlaced $event) { // } }
Wenn der Ereignis-Listener aufgelöst ist, liest der Dienstcontainer den Typhinweis im Konstruktor der Klasse und fügt den entsprechenden Wert ein . Weitere Informationen zur Registrierung bei einem Service-Container finden Sie in der Dokumentation zum Service-Container.
Vertragsreferenz
Diese Tabelle bietet eine Kurzreferenz aller Laravel-Verträge und ihrer entsprechenden Fassaden: