Grundlegende Implementierung der AOP-Programmierung in JavaScript

Grundlegende Implementierung der AOP-Programmierung in JavaScript

Einführung in AOP

Die Hauptfunktion von AOP (Aspect Oriented Programming) besteht darin, einige Funktionen zu extrahieren, die nicht mit dem Kernmodul der Geschäftslogik zusammenhängen. Diese Funktionen, die nicht mit der Geschäftslogik zusammenhängen, umfassen normalerweise Protokollstatistiken, Sicherheitskontrollen, Ausnahmebehandlung usw. Nach dem Extrahieren dieser Funktionen werden sie durch "dynamisches Weben" in das Geschäftslogikmodul integriert.

Aspektorientierte Programmierung bietet uns eine Möglichkeit, Code in vorhandene Funktionen oder Objekte einzufügen, ohne die Ziellogik zu ändern.

Obwohl dies nicht erforderlich ist, soll eingefügter Code übergreifende Belange erfüllen, z. B. das Hinzufügen von Protokollierungsfunktionen, das Debuggen von Metadaten oder andere weniger allgemeine, aber zusätzliche Verhaltensweisen, die eingefügt werden können, ohne den Inhalt des Originalcodes zu beeinträchtigen.

Um Ihnen ein gutes Beispiel zu geben: Angenommen, Sie haben Ihre Geschäftslogik geschrieben, stellen jetzt aber fest, dass Sie keinen Protokollierungscode hinzugefügt haben. Der übliche Ansatz besteht darin, die Protokollierungslogik in einem neuen Modul zu zentralisieren und dann die Protokollierungsinformationen Funktion für Funktion hinzuzufügen.

Allerdings wäre es sicherlich viel einfacher, wenn Sie in denselben Logger nur eine Codezeile an einem bestimmten Punkt der Ausführung jeder Methode einfügen könnten, die Sie protokollieren möchten. Nicht wahr?

Aspekte, Ratschläge und Pointcuts (was, wann, wo)

Um die obige Definition formaler zu gestalten, nehmen wir den Logger als Beispiel, um drei Konzepte zu AOP vorzustellen. Wenn Sie sich entscheiden, dieses Paradigma weiter zu erforschen, wird Ihnen Folgendes helfen:

  • Aspekte (was sie sind): Dies ist der „Aspekt“ oder das Verhalten, das Sie in Ihren Zielcode einfügen möchten. In unserem Kontext (JavaScript) bezieht sich dies auf eine Funktion, die das Verhalten kapselt, das Sie hinzufügen möchten.
  • Benachrichtigen (um welche Uhrzeit): Wann möchten Sie, dass dieser Aspekt ausgeführt wird? „Ratschlag“ gibt einige allgemeine Momente an, in denen der Aspektcode ausgeführt werden soll, z. B. „vorher“, „nachher“, „um“, „beim Werfen“ usw. Sie beziehen sich wiederum auf Zeitpunkte relativ zur Ausführung des Codes. Bei Teilen, auf die nach der Codeausführung referenziert wird, wird dieser Aspekt den Rückgabewert abfangen und ihn bei Bedarf möglicherweise überschreiben.
  • Pointcuts (wo): Diese beziehen sich auf die Stellen in Ihrem Zielcode, an denen der Aspekt eingefügt werden soll. Theoretisch können Sie explizit angeben, dass Aspektcode an jeder beliebigen Stelle im Zielcode ausgeführt werden soll. Dies ist eigentlich nicht praktikabel, aber Sie könnten beispielsweise Folgendes angeben: „Alle Methoden in meinem Objekt“ oder „Nur diese eine bestimmte Methode“. Wir könnten sogar etwas wie „Alle Methoden, die mit get_ beginnen“ verwenden.

Mit dieser Erklärung sollte es Ihnen relativ leicht fallen, eine AOP-basierte Bibliothek zu erstellen, um beispielsweise einer vorhandenen OOP-basierten Geschäftslogik eine Protokollierungslogik hinzuzufügen. Sie müssen lediglich die vorhandene Matching-Methode des Zielobjekts durch eine benutzerdefinierte Funktion ersetzen, die die Aspektlogik zum entsprechenden Zeitpunkt hinzufügt und dann die ursprüngliche Methode aufruft.

Grundlegende Implementierung

Da ich ein visueller Lerner bin, dachte ich, es wäre zu weit hergeholt, ein einfaches Beispiel für die Implementierung eines切面zum Hinzufügen von AOP-basiertem Verhalten zu zeigen.

Die folgenden Beispiele veranschaulichen, wie einfach die Implementierung ist und welche Vorteile es für Ihren Code bringt.

`/** Hilfsfunktion zum Abrufen aller Methoden in einem Objekt*/ const getMethods = (obj) => Object.getOwnPropertyNames(Object.getPrototypeOf(obj)).filter(item => typeof obj[item] === 'function')

/** Ersetzen Sie die ursprüngliche Methode durch eine benutzerdefinierte Funktion, die unseren Aspekt aufruft, wenn der Ratschlag dies erfordert. */ function replaceMethod(target, methodName, aspect, advice) { const originalCode = target[methodName] target[methodName] = (...args) => { if(["before", "around"].includes(advice)) { aspect.apply(target, args) } const returnedValue = originalCode.apply(target, args) if(["after", "around"].includes(advice)) { aspect.apply(target, args) } if("afterReturning" == advice) { return aspect.apply(target, [returnedValue]) } else { return returnedValue
 } } }

module.exports = { // Hauptmethode des Exports: Aspekte bei Bedarf in das Ziel einfügen inject: function(target, aspect, advice, pointcut, method = null) { if(pointcut == "method") { if(method != null) { replaceMethod(target, method, aspect, advice)
} else { throw new Error("Versuch, einer Methode einen Aspekt hinzuzufügen, aber keine Methode angegeben") } } if(pointcut == "methods") { const methods = getMethods(target) methods.forEach( m => { replaceMethod(target, m, aspect, advice) 
}) } } }`

Ziemlich unkompliziert. Wie bereits erwähnt, deckt der obige Code nicht alle Anwendungsfälle ab, aber er sollte für das nächste Beispiel ausreichen.

Aber bevor wir weitermachen, werfen wir einen Blick auf die Funktion replaceMethod . Hier geschieht die Magie. Es kann neue Funktionen erstellen und auch entscheiden, wann wir unseren Aspekt aufrufen und wie mit seinem Rückgabewert verfahren werden soll.

Als nächstes erkläre ich, wie diese Bibliothek verwendet wird:

`const AOP = require("./aop.js")

Klasse MyBusinessLogic {
hinzufügen(a, b) {
    console.log("Aufruf von add")
    gib a + b zurück
}

concat(a, b) {
    console.log("Concat wird aufgerufen")
    gib a + b zurück
}

Leistung(a, b) {
    console.log("Anrufleistung")
    gib a ** b zurück
}
}

const o = neue MyBusinessLogic()

function loggingAspect(...args) { console.log("== Aufruf der Logger-Funktion ==") console.log("Empfangene Argumente: " + args) }

Funktion printTypeOfReturnedValueAspect(Wert) { console.log("Zurückgegebener Typ: " + Typ des Wertes) }

AOP.inject(o, loggingAspect, "vorher", "Methoden") AOP.inject(o, printTypeOfReturnedValueAspect, "nach der Rückgabe", "Methoden")

o.add(2,2) o.concat("hallo", "auf Wiedersehen") o.power(2, 3)`

Dies ist nur ein einfaches Objekt mit drei Methoden, nichts Besonderes. Wir möchten zwei generische Aspekte einfügen, einen zum Protokollieren eingehender Eigenschaften und einen anderen zum Analysieren ihrer Rückgabewerte und Protokollieren ihrer Typen. Zwei Aspekte, zwei Codezeilen (es müssen nicht sechs sein).

Dies ist das Ende des Beispiels. Hier ist die Ausgabe, die Sie erhalten:

https://camo.githubusercontent.com/f18ef187f4acddab8df097c8aa4521d632e17759bc1c0831a22ada934388d7b5/68747470733a2f2f63646e2d696d616765732d312e6d656469756d2e636f6d2f6d61782f323030302f312a394b5a42774f6262714145754a4176314757537279672e706e67

Vorteile von AOP

Nachdem Sie das Konzept und den Zweck von AOP kennen, haben Sie vielleicht erraten, warum Leute aspektorientierte Programmierung verwenden möchten. Lassen Sie uns jedoch eine kurze Zusammenfassung machen:

  • Eine großartige Möglichkeit, übergreifende Belange zusammenzufassen. Ich bin ein großer Fan der Kapselung, da dadurch Code leichter gelesen und verwaltet werden kann und in mehreren Projekten wiederverwendet werden kann.
  • Flexible Logik. Die rund um Ratschläge und Pointcuts implementierte Logik kann Ihnen beim Einfügen von Aspekten viel Flexibilität bieten. Dies wiederum hilft Ihnen, verschiedene Aspekte Ihrer Codelogik dynamisch ein- und auszuschalten (Wortspiel beabsichtigt).
  • Verwenden Sie Aspekte projektübergreifend wieder. Sie können sich Aspekte als Komponenten vorstellen: kleine, entkoppelte Codeteile, die überall ausgeführt werden können. Wenn Sie Ihre Aspekte richtig formulieren, können Sie diese problemlos in verschiedenen Projekten nutzen.

Hauptprobleme mit AOP

Da nicht alles perfekt ist, gibt es auch einige Kritiker dieses Paradigmas.

Sie weisen vor allem darauf hin, dass der Hauptvorteil darin besteht, die Code-Logik und -Komplexität zu verbergen, was, wenn es nicht klar ist, Nebenwirkungen haben kann.

Wenn man darüber nachdenkt, haben sie recht, denn AOP bietet Ihnen eine Menge Möglichkeiten, bestehenden Methoden unabhängiges Verhalten hinzuzufügen oder sogar deren gesamte Logik zu ersetzen. Natürlich ist dies möglicherweise nicht der genaue Grund, warum dieses Paradigma eingeführt wurde, und es war sicherlich nicht die Absicht der Beispiele, die ich oben angeführt habe.

Allerdings können Sie damit tun, was Sie wollen, was in Kombination mit mangelndem Verständnis guter Programmierpraktiken zu einem großen Durcheinander führen kann.

Um nicht zu klischeehaft zu klingen, zitiere ich Onkel Ben:

Mit großer Macht geht große Verantwortung einher

Wenn Sie AOP richtig verwenden möchten, müssen Sie die Best Practices der Softwareentwicklung verstehen.

Nur weil man mit diesem Tool großen Schaden anrichten kann, bedeutet das meiner Meinung nach nicht, dass es ein schlechtes Tool ist, denn es bringt auch viele Vorteile mit sich (z. B. kann man einen Großteil der allgemeinen Logik an einem zentralen Ort extrahieren und sie mit einer einzigen Codezeile dort einfügen, wo man sie braucht). Für mich ist das ein leistungsstarkes Tool, das es wert ist, erlernt und auf jeden Fall verwendet zu werden.

Aspektorientierte Programmierung ist eine perfekte Ergänzung zu OOP, insbesondere dank der dynamischen Natur von JavaScript können wir sie sehr einfach implementieren (wie im Code hier gezeigt). Es bietet leistungsstarke Funktionen zum Modularisieren und Entkoppeln großer Mengen an Logik und ermöglicht sogar die spätere gemeinsame Nutzung dieser Logik mit anderen Projekten.

Natürlich kann bei unsachgemäßer Anwendung eine echte Sauerei entstehen. Aber Sie können es definitiv verwenden, um viel Code zu vereinfachen und zu bereinigen. Das ist meine Meinung zu AOP, was ist mit Ihnen? Haben Sie schon einmal von AOP gehört? Haben Sie es schon einmal benutzt? Bitte hinterlassen Sie unten einen Kommentar und teilen Sie uns Ihre Meinung mit!

Dies ist das Ende dieses Artikels über AOP-Programmierung in JavaScript. Weitere relevante Inhalte zur JS-AOP-Programmierung finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Detaillierte Erklärung der AOP-Implementierung in JavaScript (aspektorientierte Programmierung, Dekorationsmuster)
  • JavaScript AOP-Programmierbeispiel
  • JavaScript AOP-Programmierbeispiel
  • Javascript AOP (Aspect Oriented Programming) rund um (Umgebungs-)Analyse

<<:  Methoden zur Installation und Deinstallation der virtuellen Python-Umgebung sowie aufgetretene Probleme

>>:  Detaillierte Erläuterung der 4 gängigen Datenquellen in Spark SQL

Artikel empfehlen

Codebeispiel für die Linux-SSH-Serverkonfiguration

Verwenden Sie den folgenden Terminalbefehl, um de...

Detaillierte Erklärung des VueRouter-Routings

Inhaltsverzeichnis Vue-Router 1. Verstehen Sie da...

Detaillierte Erläuterung der Mysql-Funktionsaufrufoptimierung

Inhaltsverzeichnis Funktionsaufrufoptimierung Fun...

So beheben Sie das Eingabe-Jitter-Problem beim WeChat-Applet

Finden Sie das Problem Schauen wir uns zunächst d...

Eine kurze Analyse von Kubernetes-Controllern und -Labels

Inhaltsverzeichnis 01 Gemeinsame Controller in k8...

HTML-Elemente (Tags) und ihre Verwendung

a : Gibt die Start- oder Zielposition eines Hyper...

Detaillierte Erläuterung der Angular-Routing-Grundlagen

Inhaltsverzeichnis 1. Routing-bezogene Objekte 2....

Über Generika der C++ TpeScript-Reihe

Inhaltsverzeichnis 1. Vorlage 2. Generika 3. Gene...

Implementierung der Navigationsleiste und des Dropdown-Menüs in CSS

1. CSS-Navigationsleiste (1) Funktion der Navigat...

Detaillierte Erklärung von MySQL-Transaktionen und MySQL-Protokollen

Transaktionale Merkmale 1. Atomarität: Nach dem S...