Wann sollte man Repository vs. Service vs. Trait in Laravel verwenden? [closed]

Lesezeit: 5 Minuten

Um Codeduplizierung in Laravel zu vermeiden, möchte ich eine Methode haben, die von mehreren Controllern verwendet wird, einige Zeilen in die Datenbank einfügt und auch einige Daten in einer anderen Tabelle aktualisiert.

Ich dachte an die Verwendung von Repository, aber ich habe irgendwo gelesen, dass Repository besser zum Abrufen von Daten verwendet wird und nicht zum Einfügen verwendet werden sollte.

Also werde ich jetzt Traits verwenden. aber ich bin etwas verwirrt…

Könnte jemand bitte auf einfache Weise erklären, was die beste Verwendung für jedes dieser (Repository/Service/Trait) ist und wie sie sich unterscheiden?

Benutzeravatar von mrhn
mrhn

Züge

Sind ein alternativer Ansatz zur Vererbung, der einige Einschränkungen der Vererbung einzelner Klassen löst, die PHP Verwendet. Dies wird häufig verwendet, um ähnliche Logik modellübergreifend gemeinsam zu nutzen. Stellen wir uns vor, ein paar Modelle haben eine Firmenbeziehung.

trait HasCompany {
   public function company() {
       return $this->belongsTo(Company::class);
   }
}

Jetzt kann der Benutzer Code aus der Eigenschaft einfach nach Schlüsselwort teilen using. Dies ist ein Beispiel, und meistens wäre ein komplexerer Anwendungsfall erforderlich, damit es Sinn macht.

class User {
   use HasCompany;
}

Aufbewahrungsorte

Repositories ist ein Entwurfsmuster, um Datenschichten von der Anwendung zu abstrahieren. Ihre Logik sollte sich nicht darum kümmern, wie Sie Daten speichern, also wenn Sie das ändern wollten Mysql zu Mongodbwürden Sie nur das Repository austauschen und müssen die Geschäftslogik nicht ändern.

Sehr eigensinnig hier, aber das ist kein passendes Designmuster für Laravel. Laravel hat Eloquent und die Datenbankschicht ist dafür bereits abstrahiert. Repositories wird manchmal für verwendet Laravel Anwendungen, sondern eher ein Ausreißer als ein gewöhnlicher Anblick. Einer der Hauptgründe für Repositorys ist die Agnostik der Datenimplementierung, die bereits vorhanden ist und Sie problemlos zwischen SQL-Servern wechseln können. Ebenfalls Eloquents Funktionen wie ::find(), scopes usw. fühlt sich wie ein Ersatz für Repositories an und ist gleichzeitig eigenartig zu verwenden.

Wenn Sie Doctrine als verwenden ORMin die Sie einsteigen können Laraveles ist der Kern ihrer Architektur und sollte verwendet werden.

Dienstleistungen

Wird häufig als Speicherort für Geschäftslogik oder die Bausteine ​​Ihrer Aktionen in Ihrer Anwendung verwendet. Im traditionellen MVC Design sollten Controller nur Eingaben verarbeiten. Normalerweise würden Sie Ihre Logik in Modelle einfügen, aber sie werden sehr schnell “fett”, wenn dies geschieht, sind Dienste ein üblicher Ort, um Geschäftslogik zu platzieren. Manchmal auch benannte Aktionen oder Befehle, was ähnlichen, aber etwas anderen Ansätzen entspricht.

Eines der Kernprobleme, die es löst, besteht darin, Ihre Geschäftslogik wiederverwendbar zu machen. Imaging filtert alle Benutzer nach einem aktiven Flag, wenn Sie es in seinem Controller abrufen.

public function all() {
    return User::where('active', true)->get();
}

Jetzt haben Sie Ihre Geschäftslogik, die erzwingt, dass Sie nur an aktiven Benutzern arbeiten, später möchten Sie alle aktiven Benutzer mit einer E-Mail benachrichtigen, indem Sie Benachrichtigungen mit einem Befehl verwenden.

class NotifyUsers extends Command {
    public function handle() {
        foreach (User::where('active', true)->get() as $user) {
            $user->notify();
        }
    }
}

Jetzt müssen Sie die Geschäftslogik manuell auf dem neuesten Stand halten. Wenn Sie das nächste Mal eine zweite Bedingung hinzufügen oder die Logik ändern, müssen Sie den Code an zwei Stellen ändern. In einer großen Anwendung, in der dieser Codeblock häufig verwendet wird, kann es ziemlich schwierig sein, die Bedingungen aufrechtzuerhalten, ohne eine der Stellen zu vergessen. Wenn Sie einen Dienst mit dieser Logik erstellen, können Sie problemlos dieselbe Geschäftslogik in der gesamten Anwendung verwenden. Man muss zwar an einer Stelle den Code ändern, wenn sich diese Logik ändern müsste.

class UserService {
    public function all() {
        return User::where('active', true)->get();
    }
}

Überall dort, wo Sie diese Geschäftslogik nutzen möchten, um aktive Benutzer zu gewinnen, können Sie den Service nutzen. Daher nur einen Ort, um die Logik aufrechtzuerhalten. So einfach kann ein Anruf sein resolve(UserService::class)->all(). Beispiel für die aktualisierte Logik mit Diensten wäre.

// controller
public function all(UserService $userService) {
    return $userService->all();
}

// command
class NotifyUsers extends Command {
    public function handle(UserService $userService) {
        $userService->all()->each->notify();
    }
}

Fazit

Die Welt ist nicht schwarz und weiß, man muss seinen eigenen Ansatz finden. Mein Rat ist, verbringen Sie keine Zeit mit Repositories, Laravel hat viele Funktionen, um datenbezogene Operationen zu handhaben scopes, getters setters usw., die mit dem Repository-Entwurfsmuster in Konflikt stehen. Sehen Sie, ob ein Service wie ein Designansatz zu Ihnen passt und Sie ihn nutzen können. Traits ist weniger ein architektonisches Entwurfsmuster als vielmehr eine Alternative zur Klassenvererbung, einfach um Logik zwischen Klassen zu teilen.

  • Das war perfekt, eher ein Artikel als eine Antwort, vielen Dank!

    – J. Reh

    3. Februar 2020 um 1:14 Uhr

  • Freut mich, dass es dir gefallen hat, das ist ein sehr flauschiges Thema, sehr Meinung und Religion sind wichtiger als Fakten 🙂

    – Herr

    3. Februar 2020 um 1:21 Uhr

  • Wäre die Dienstschicht für die Paginierung und ihre Logik vorzuziehen?

    – Schulz

    3. November 2021 um 10:40 Uhr

  • Hmm… Im Allgemeinen sehe ich keinen Zusammenhang zwischen Paginierung und diesen Designmustern. Da diese bereits in Laravel im Abfrageersteller erstellt wurden, verwende ich diese normalerweise nur und transformiere die Metainformationen des Abfrageerstellers in die Antwort.

    – Herr

    3. November 2021 um 11:57 Uhr

  • Ich werde mich freundlicherweise an der Diskussion über Repositories vs. Eloquent-Modelle beteiligen. Repositories in Laravel sind sehr praktisch in großen Projekten mit: 1) Komplexe Caching-Mechanismen abstrahieren. 2) Erstellung komplexer und dynamischer Datensätze basierend auf authentifiziertem Benutzer, Umgebung, Datenstatus usw. 3) Abstrahieren von Transaktionen mit Logik zum Einfügen/Aktualisieren komplexer Daten mit mehreren Tabellen.

    – Umur Karagöz

    27. April um 20:33 Uhr

1433960cookie-checkWann sollte man Repository vs. Service vs. Trait in Laravel verwenden? [closed]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy