Was sind „Dekorateure“ und wie werden sie verwendet?


148

Ich bin gespannt, was genau Dekorateure in AngularJS sind. Es gibt nicht viele Online-Informationen für Dekorateure, außer einem Klappentext in der AngularJS-Dokumentation und einer kurzen (wenn auch interessanten) Erwähnung in einem Youtube-Video .

Wie die Angular-Leute es ausdrücken, ist ein Dekorateur:

Durch die Dekoration des Dienstes kann der Dekorateur die Erstellung der Dienstinstanz abfangen. Die zurückgegebene Instanz kann die ursprüngliche Instanz oder eine neue Instanz sein, die an die ursprüngliche Instanz delegiert.

Ich weiß nicht genau, was das bedeutet , und ich bin mir nicht sicher, warum Sie diese Logik vom Dienst selbst trennen würden. Wenn ich beispielsweise unter verschiedenen Bedingungen etwas anderes zurückgeben möchte, übergebe ich einfach unterschiedliche Argumente an die relevanten Funktionen oder verwende eine andere Funktion, die diesen privaten Status teilt.

Ich bin immer noch eine Art AngularJS-Noob, also bin ich mir sicher, dass es nur Unwissenheit und / oder schlechte Gewohnheiten sind, die ich aufgegriffen habe.

Antworten:


219

Ein guter Anwendungsfall $provide.decoratorist, wenn Sie kleinere "Optimierungen" an einem Drittanbieter- / Upstream-Dienst vornehmen müssen, von dem Ihr Modul abhängt, während Sie den Dienst intakt lassen (da Sie nicht der Eigentümer / Betreuer des Dienstes sind). Hier ist eine Demonstration auf plunkr.


6
Tolles Beispiel. Ich habe mich tatsächlich gefragt, wie ich die Funktionalität von Modulen von Drittanbietern erweitern kann, ohne mich in sie einzumischen
Arthur Kovacs

5
Geben Dekorateure tatsächlich alle Instanzen eines Dienstes ein oder sind sie nur auf das Modul beschränkt, das sie dekoriert? Mit anderen Worten, ich habe Modul A, das einen Dienst von Modul B dekoriert. Ich habe dann Modul C, das von Modul A und Modul B abhängt. Ist der Dienst von Modul B innerhalb von Modul C die ursprüngliche oder dekorierte Version?
Jon Jaques

3
@ JonJaques - Das ist eine gute Frage. Ich bin auf eine solche Situation nicht gestoßen. Wenn ich raten sollte, sollte die Version des Dienstes, die Modul C sieht, die dekorierte Version von Modul A sein, aber ich kann das nicht sicher sagen, bis ich es selbst versuche. Warum schreibst du nicht ein einfaches plunkr / jsffidle und experimentierst damit? Es wäre großartig, wenn Sie uns Ihre Erkenntnisse mitteilen könnten. Prost.
Tamakisquare

6
@ JonJaques - Konnte meine Neugier nicht aufhalten, deshalb habe ich meinem ursprünglichen Beispiel ein paar Zeilen hinzugefügt, um die Antwort auf Ihre Frage zu finden, Link . Kurz gesagt, die Vermutung in meinem vorherigen Kommentar ist richtig.
Tamakisquare

17
Fabriken, Dienstleistungen usw. sind Singletons (wie sie bereitgestellt werden), also einmal dekoriert, immer dekoriert.
FlavorScape

66

Mit Dekorateuren können wir Querschnittsthemen ausräumen und den Diensten ermöglichen, das Prinzip der Einzelverantwortung beizubehalten, ohne sich um den Code der "Infrastruktur" kümmern zu müssen.

Praktische Verwendung von Dekorateuren:

  • Caching: Wenn wir einen Dienst haben, der möglicherweise teure HTTP-Aufrufe ausführt, können wir den Dienst in einen Caching-Dekorator einbinden, der den lokalen Speicher überprüft, bevor der externe Aufruf getätigt wird.
  • Debugging / Tracing: Abhängig von Ihrer Entwicklungs- / Produktionskonfiguration haben Sie einen Schalter, der Ihre Services mit Debugging- oder Tracing-Wrappern dekoriert.
  • Drosselung: Wrap häufig ausgelöste Aufrufe in einem Debouncing-Wrapper. Ermöglicht uns beispielsweise die einfache Interaktion mit Diensten mit eingeschränkter Rate.

In all diesen Fällen beschränken wir den Code im Service auf seine Hauptverantwortung.


10

decoratorkann die von erstellte Dienstinstanz abfangen factory, service, value, providerund bietet die Optionen zum Ändern einiger instance(service)ansonsten nicht konfigurierbarer / mit Optionen.

Es kann beispielsweise auch Modellinstanzen zu Testzwecken bereitstellen $http.


1
Es ist erwähnenswert, dass Sie auch directiveDefinitionen überschreiben können, wie sie von Ben Nadel
David Salamon

Hier ist die Referenz in den offiziellen Angular-Dokumenten: https://docs.angularjs.org/guide/decorators
David Salamon

3

Mit einfachen Worten können wir sagen, dass es wie eine Erweiterungsmethode ist. Zum Beispiel. Wir haben eine Klasse und sie hat zwei Methoden und zur Laufzeit möchten wir mehr Methoden hinzufügen, als wir Decorator verwenden.

Wir können $ require.decorator nicht mit Konstanten verwenden, da wir die Konstanten, die sie schreibgeschützt sind, nicht ändern können.


1

Kurz gesagt können Dekorateure wie folgt beschrieben werden: -

Eine Dekorationsfunktion fängt die Erstellung eines Dienstes ab und ermöglicht es ihm, das Verhalten des Dienstes zu überschreiben oder zu ändern.

Es verwendet den $provideDienst durch Winkel und modifiziert oder ersetzt die Implementierung eines anderen Dienstes

$provide.decorator('service to decorate',['$delegate', function($delegate) {
  // $delegate - The original service instance, 
  //             which can be replaced, monkey patched, 
  //             configured, decorated or delegated to. 
  //             ie here what is there in the 'service to decorate'

  //   This function will be invoked, 
  //   when the service needs to be provided 
  //   and should return the decorated service instance.
  return $delegate;
}]);

Beispiel:

$provide.decorator('$log', ['$delegate', function($delegate) {
  // This will change implementation of log.war to log.error
  $delegate.warn = $delegate.error; 
  return $delegate;
}]);

Anwendungen

Zusätzlich zu @JBland Antwort.

  • Anwendungsweite Gebietsschemaeinstellungen: -

    Ein Beispiel finden Sie hier

  • Ändern des Standardverhaltens und der vorhandenen Implementierung eines Dienstes durch einen Winkeldienst: -

    Ein Beispiel finden Sie hier

  • Schaltverhalten einer Funktion in verschiedenen Umgebungen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.