| | | | |
| |||||||
| Software-Design Diskussionen auf Profi-Niveau: PHP Lösungen auf konzeptioneller Ebene |
|
| | LinkBack | Themen-Optionen | Bewertung: |
| | |
| Erfahrener Benutzer Registriert seit: 30.07.2008
Beiträge: 1.169
PHP-Kenntnisse: Fortgeschritten ![]() ![]() ![]() | Aufgrund dieser Aufforderung http://www.php.de/software-design/78...tml#post591110 (Eigenes CMS entwickeln) würde ich mal gerne das Für und Wider von AOP diskutieren. Ich persönlich halte das für eine gefährliche Sache, aber vielleicht gibt es ja Möglichkeiten und Einsatzzwecke, wo das wirklich notwendig/geeignet ist (Mal unabhängig von PHP). Mit Prozess meine ich nicht Prozesse im programmtechnischen Verständnis, sondern Vorgänge.Meine Erfahrung: Die Beispiele, die ich bisher gesehen habe, sorgen in meinen Augen für ein Durcheinander, bei dem nach einiger Zeit keiner mehr durchblickt - Schon gar nicht jemand, der neu in ein Projekt kommt. Wo ich das Problem sehe, ist, dass mehr oder weniger willkürlich feste "Applikations-Flows" per - ich nenne es mal so - Hack umgebogen werden können, wodurch feste Strukturen aufgeweicht werden. Auf mich wirkt das so, als ob man einen Prozess ändern möchte, aber aus Faulheit oder sonst welchen Gründen nicht an der Applikation selber Hand anlegen möchte. Geeigneter finde ich da Prozessabbildungen über Konfigurationen o. ä., bei denen man festlegen kann, was wo in welchem Prozess geschieht. Aber ich lasse mich gerne vom Gegenteil überzeugen ![]() |
| | |
| | |
| PHP Code Flüsterer Registriert seit: 21.08.2005 Beiträge: 4682 PHP-Kenntnisse: Fortgeschritten | |
| | ||
| Erfahrener Benutzer | Die Grundvoraussetzung ist zunächst einmal, das Ansinnen zu verstehen, warum AOP erfunden wurde. Von je her stellt sich die Frage nach der Domäne, in die ein Stückchen Code gehört. Sehr typisch, weil leicht zu verstehen, wird bei AOP immer das Protokollieren genommen. Annahme: Es gibt eine Klasse "User-Service". Dort gibt es eine Methode "changePassword". Wie verhält es sich nun mit dem Logging, dass diese Methode aufgerufen wurde? Streng genommen gehört die Frage, wie die Klasse "User-Service" an ein Logging-Objekt kommt und dass es loggen muss, nicht zur Businness-Logik des User-Service selbst. Es gehört in eine Domäne Logging. Mit AOP wird genau sowas möglich. Du biegst den Aufruf der Methode in einem für das Logginn zuständigem Aspekt um und führst das Logging dort aus. Ein wesentlicher Vorteil ist, dass gleichartiger Code nur einmal geschrieben wird. Hier wieder das Logging: Statt in jeder Methode zu schreiben "Logger:logInfo('enteringMethod '.__CLASS__.'::'.__FUNCTION__);" schreibst du es nur einmal und setzt beispielsweise per Wildcards pauschal alle Methoden einer Klasse. In Flow3 (Steuerung via PHP-Tags) sieht das dann in etwa so aus: PHP-Code: Gibt es beispielsweise im User-Service eine Methode deleteUser, brauche ich nur einen Aspekt zu diesem definieren um alle Private Messages des Users zu löschen, sobald der User selbst gelöscht wird. Da die Domäne User von PrivateMessages nichts weiss, ist die einzige Alternative ein aufwändiges Listener/Signal-Modell. Der Nachteil am Signal-Modell ist u.U. der Verwaltungsoverhead. Du musst dich ggf. als Listebner am User-Service registrieren ohne zu wissen, ob überhaupt Code darauf ausgeführt wird. Mittels geschickter Konfigurationsdateien kann man das zwar umgehen, dennoch ist es nicht immer schön. Weiteres Anwendungsbeispiel: Gegeben sei ein allgemeines SOA-Modell. Dieses gibt eindeutige fachliche Fehlercodes zurück, wenn im Service was passiert, was nicht OK ist. Auch hier wieder das Logging. Per Aspekt habe ich wenige Codezeilen um an allen SOA-Methoden aufzupassen und per LogError zu potokollieren, falls ein Service auf einen Fehler läuft. Der Code im Service selbst ist sauber. Nun kommt das ABER: Erst mal ein Zitat von mir selbst. Zitat:
a) Nicht ausreichende Dokumentation und dadurch nicht klare Programmabläufe b) Mangelhafte IDE-Unterstützung c) AOP zum Selbstzweck ohne Sinn und Verstand. zu a) Natürlich verlangt AOP gerade bei komplexeren Abhängigkeiten eine klare Vereinbarung im Projekt. Es werden klare Vorgaben benötigt, für welche Dinge AOP verlangt wird. Und jeder neue Fall sollte zuerst ncohmal durchdacht werden. Damit vermeidet man Willkür. AOP exzessiv häufig einzusetzen, läuft schief. Es gibt zwei Unterscheidungen: Ist der AOP-Ablauf ein optionaler zusätzlicher Ablauf? Das ist beispielsweise bei Logging der Fall, das ist der Fall bei einem Aspekt, der sich um jeden Controller-Aufruf hängt um einen Standard-Admin bei leerer Datenbank vorzubelegen. Ein solcher Aspekt tut zwar was wichtiges, hat aber auf den eigentlichen Controller keinen direkten Einfluss. Zweite Möglichkeit: Ist der AOP-Ablauf ein manipulierener Ablauf? Wenn der AOP-Ablauf dazu dient, tatsächlich die Arbeitsweise zu verändern, Ergebnisse zu verfälschen u.ä., dann muss das nach meiner Erfahrung immer gut dokumentiert werden. zu b) Insbesondere in PHP ist AOP neu. IDEs raffen das nicht. Sie unterstützen dich als Entwickler nicht. Aus dem Java-Umfeld, wo man das bereits länger kennt, gibt es einen Vorbild. An jeder Klasse, an jeder Methode, die per Aspekt verändert wird (egal wie) zeigt Eclipse hier einen kleinen Bupperl an. So sieht man, dass es einen besonderen Ablauf gibt. Wenn du so etwas tatsächlich auch für PHP hast (wie gesagt habe ich das mal für Flow3 und Eclipse gebastelt), ist das eine enorme Arbeitserleichterung. Stacktraces sind bei Flow3 leicht zu lesen, da die Original-Klassen verwendet werden und es lediglich On-top einen Proxy drauf gibt. Je nach Framework ist das u.U. schwieriger, weil dort Klassen zusammengewoben werden und dann die Original-Dateinamen/Klassennamen nicht mehr verwendet werden. c) Natürlich sollte AOP nicht eingesetzt werden, weil mans kann. Man sollte per AOP nicht in der Domäne umherpfuschen. Alles, was zur Domäne A dazu gehört, sollte auch dort entwickelt werden und nicht verstreut in zig Aspekten. Wenn du sowas jedoch in Aspekte verstreust, hast du ein mittelschweres Problem mit der Nachvollziehbarkeit, das ist richtig. Ich setze AOP derzeit auch nur gezielt ein. Es gibt bei Flow3 einen kleinen Trick. Aktivieren eines Aspektes via Config. Wieder das Beispiel von oben: Das automatische Anlegen eines Default-Admins. Ich habe eine Konfigurationsoption mit Namen "myapp.create.default.admin". Im Aspekt steht nun in etwa: PHP-Code: Also: AOP ist sinnvoll, wenn man einige Grundregeln beachtet und es ebend nicht dazu einsetzt, die Arbeitsweise einer Domäne gravierend zu verändern. Ansonsten wirds schnell kontraproduktiv. Nachtrag: Zum deleteUser. Wenn ich ein Zusatzplugin habe, was ein Veto einlegt (User darf nicht gelöscht werden, wenn es noch offene Rechnungen gibt), habe ich u.U. ebenfalls ein Problem. In diesem Fall können Aspekte elegant helfen, Bedingungen vor Ablauf des UserService auszuführen und ein veto (= eine Exception) zu werfen.
__________________ www.php-maven.org PHP und Maven vereint: Build/Deploy/Produktion/Konfiguration, Projekt Management, CI, PHPUnit, zahlreiche Frameworks Twitter @ https://twitter.com/#!/mepeisen und Facebook @ http://t.co/DZnKSUih Geändert von mepeisen (11.05.2011 um 12:51 Uhr). | |
| | |
| | |
| Erfahrener Benutzer | Welche Klassen musst du denn bei AOP anfassen? Du musst im Prinzip nichts anfassen. Oder meinst du den Engine-Teil, der das zusammenstöpselt? Das sollte hoffentlich unsichtbar vonstatten gehen.
__________________ www.php-maven.org PHP und Maven vereint: Build/Deploy/Produktion/Konfiguration, Projekt Management, CI, PHPUnit, zahlreiche Frameworks Twitter @ https://twitter.com/#!/mepeisen und Facebook @ http://t.co/DZnKSUih |
| | |
| | |
| Erfahrener Benutzer | Ein weitres Beispiel: Sicherheitschecks. Gegeben sei ein MVC-Modell. Um nun nicht in jede einzelne Action des Controllers Prüfungen einzubauen kann ich einen Aspekt bauen, der sich um jede Action hängt. Dieser Aspekt prüft vor Aufruf: Hat der eingeloggte User die Rechte? Wenn Nein, springt es zu einem Alternativablauf (z.B. Redirect an eine Access-Denied-Seite). Ebenfalls im MVC-Modell die Verarbeitung von Plugins, die auf beliebiger Seite ausgeführt werden. Beispielsweise das Verändern der Sprache oder der Login/Logout. Diese lassen sich ebenfalls per Aspekt um die Actions eines Controllers drumherum bauen. Bei solchen Dingen ist der Programmablauf nach wie vor sehr klar. Der Code wird nicht aufgebläht durch Aufruf und Delegation von irgendwelchen Aufgaben. In einer Doku steht dann idealerweise: Login/Logout wird in Aspekt XYZ umgesetzt. Ich habe beispielsweise einen Aspekt, der auf ein Tag hört. Dieser Aspekt ist ebenfalls eine Berechtigungsprüfung, ob eine Methode aufgerufen werden soll und bewirkt zudem, dass ich dieses Recht im Admin-Bereich vergeben kann. Das sieht dann so aus: PHP-Code:
__________________ www.php-maven.org PHP und Maven vereint: Build/Deploy/Produktion/Konfiguration, Projekt Management, CI, PHPUnit, zahlreiche Frameworks Twitter @ https://twitter.com/#!/mepeisen und Facebook @ http://t.co/DZnKSUih |
| | |
| | |
| Erfahrener Benutzer | Ich spreche mal von Flow3, wo das relativ umfassend umgesetzt ist. Drei Grundvoraussetzungen/ Vereinbarungen: a) Auf Include-Techniken wird umfassend verzichtet. Es kommen entsprechend versierte ClassLoader zum Einsatz. b) Für diverse Techniken (beispielsweise Serialisierung) kommen versierte Lösungen zum Einsatz. Vieles geschieht unsichtbar für den Entwickler, beispielsweise wird eine Klasse als Session-relevant markiert und damit weiss der Objekt-Container, wo sie herzukommen hat. c) Es gibt einen Objektcontainer und eine Objektfactory, auf "new" wird verzichtet. In Flow3 wird jede Klasse, die von Aspekten betroffen ist, über eine Proxy-Klasse realisiert. Dieser Proxy tut nichts anderes als die eigentliche Klasse zu überschreiben, um selbst die Aspekte aufzurufen. Es werden gezielt die Ziel-Methoden überschrieben. Das ist eine der Ecken, was Flow3 derzeit (zur Entwicklungszeit) sehr langsam macht. Es scannt permanent als Teil des Bootstrap alle Dateien auf Änderungen und ermittelt dann die Auswirkungen auf Klassen, Proxies und Aspekte. Natürlich lässt sich das für produktive Umgebungen ausschalten. Das Vererben hat einen wesentlichen Vorteil: Stack-Traces zeigen auf die ursprüngliche Klasse. Sowohl bei Aspekten, als auch bei den Ziel-Klassen. Flow3 kann, da es eine reine PHP-Lösung ist, neimals bestmögliche Sicherheit bieten. Es gibt in den Proxies immer einen Getter/Setter und eine Call-Methode, du kannst also theoretisch von außen, wenn du weisst dass es ein Proxy ist, herumpfuschen. Generell kann ein Aspekt vom Design her auch Setter und Getter bedienen, sowie andere Methoden eines Ziel-Objektes aufrufen (auch geschützte). Das kann zu Sicherheitsproblemen führen. Ein korrumpiertes Plugin könnte beispielsweise dafür sorgen, dass es das Passwort eines User-Objektes per Aspekt verändert. Ich denke aber, dass man über mögliche Sicherheitslöcher aus zwei Gründen nicht diskutieren sollte: a) wenn einer bereits soweit ist, gezielt Code einzuschleusen, findet er genug Wege, auch ohne Aspekte das System zu übernehmen. b) Der Sicherheitsgedanke kann in reinen PHP-Lösungen nie hoch genug sein, dazu gibt es, Code einmal eingeschleust, zu viele Varianten, anzugreifen. Denkbar sind aus Sicherheitssicht Varianten, bei denne Flow3 den direkten Aufruf der Proxy-Methoden außerhalb berechtigter Aspekte verbietet. Auch denkbar ist eine echte C-Extension, die die Proxy-Methoden nicht als öffentliche Methoden anbietet und die Sicherheit dadurch deutlich erhöht.
__________________ www.php-maven.org PHP und Maven vereint: Build/Deploy/Produktion/Konfiguration, Projekt Management, CI, PHPUnit, zahlreiche Frameworks Twitter @ https://twitter.com/#!/mepeisen und Facebook @ http://t.co/DZnKSUih |
| | |
| | |
| Erfahrener Benutzer | Wenn dein CMS ein Privates ist, helfe ich dir da gerne bei
__________________ www.php-maven.org PHP und Maven vereint: Build/Deploy/Produktion/Konfiguration, Projekt Management, CI, PHPUnit, zahlreiche Frameworks Twitter @ https://twitter.com/#!/mepeisen und Facebook @ http://t.co/DZnKSUih |
| | |
|
| Themen-Optionen | |
| Thema bewerten | |
|
|
| Besucher kamen über folgende Suchanfragen bei Google auf diese Seite |
| aop php, flow3 getter and setter manually, php aop, aop in php, aop mit php, php-aop, flow3 redirect, lambda funktionen php, delegation php flow3, wann kommt aop support für php, aop-php, aop php tutorial, wie findet man den zahnrad aop, php getter setter flow3, flow3 getter setter, aop in php deutsch, aop skype, java aop in php, aop php flow3, aop php class |