Facebook
Twitter
Google+
Kommentare
5

Don’t fight the framework

Klingt wie ein Songtitel, ist aber keiner. Zumindest keiner, den ich kenne. Ich gehe jetzt mal von aus, dass jetzt in jedem Kopf eine mögliche Melodie zu dem Song komponiert wird. Also wie komme ich zu dem Thema. Gestern hat mir ein Leser (Andy) eine interessante Frage gestellt bezüglich PHP_CodeSniffer Sniffs. Das ganze habe ich dann mal zum Anlass genommen, da einen Artikel draus zu machen.

Andys Frage war eine sehr berechtigte. In den Sniffs, wird eine Projektkonfiguration dadurch hergestellt, dass man eine Klasse ableitet und einfach Attribute ändert. Konfiguration über Ableitung finde ich sehr fies. Zumindest so wie es dort betrieben wird. Die Frage von Andy war ungefähr folgende: „Macht das Sinn, wie das da gehandhabt wird“ und wenn nein „Wie sollte man es lösen“.

Anfänglich wollte ich ausholen, wie man es schön machen könnte, wie die perfekte Architektur aussehen sollte. Dann kam mir aber ein Leitspruch, den ich mal von einem Kollegen (Danke Jan) gehört hatte. „Don’t fight the framework„. Wenn ich das jetzt für mich anwende, dann bedeutet das, ich mache alles so wie die Macher des Frameworks es mir vorleben. Und das ist nun mal das Konfigurieren über Ableitung. Also sollte man es bei eigenen Sniffs auch so machen.

Den großen Vorteil, den man so gewinnt, ist die Wartbarkeit. Jeder, der schon mal mit dem PHP_CodeSniffer gearbeitet weiß genau, wie er rangehen muss. Er kann intuitiv die Sniffs erweitern/konfigurieren, weil es überall so funktioniert. Natürlich tut einem das anfänglich weh, aber an Standards sollte man sich halten, auch wenn es einem dumm vorkommt – in dem Kontext ist es meistens der Weg des geringsten Widerstandes. Das bedeutet natürlich auf keinen Fall, dass ihr in euren Projekten so arbeiten sollt, aber wenn man was bestehendes Verwendet, hält man sich an die dort geltenden Regeln.

Natürlich ist das wie immer eine persönliche Meinung, die ich gerne von euch mit besseren Ideen/Meinungen bombadiert bekommen hätte.

Über den Autor

Nils Langner

Nils Langner ist der Gründer von "the web hates me" und auch der Hauptautor. Im wahren Leben leitet er das Qualitätsmanagementteam im Gruner+Jahr-Digitalbereich und ist somit für Seiten wie stern.de, eltern.de und gala.de aus Qualitätssicht verantwortlich. Nils schreibt seit den Anfängen von phphatesme, welches er ebenfalls gegründet hat, nicht nur für diverse Blogs, sondern auch für Fachmagazine, wie das PHP Magazin, die t3n, die c't oder die iX. Nebenbei ist er noch ein gern gesehener Sprecher auf Konferenzen. Herr Langner schreibt die Texte über sich gerne in der dritten Form.
Kommentare

5 Comments

  1. Ich stimme dir vollkommen zu!
    Wenn ich eine Software wie z.B. Ein Framework einsetze, dann setze ich damit automatisch auch dessen (techn.) Konzepte ein. Wenn ich mit diesen nicht zufrieden bin, sollte ich mir die Frage stellen, ob ich die richtige Technologie Wahl getroffen habe. Habe ich das aber (aus anderen Gründen als denen, die mir missfallen) oder habe ich nicht die Chance die Entscheidung zu korrigieren (mein Chef hat sich’s ausgedacht), dann muss ich einen Weg finden mit diesen Konzepten umzugehen.

    Ich kann zum einen das Framework dahingehen ändern, meinen Anforderungen gerecht zu werden.
    Das nennt man Forken! Die Inkompatibilitäten mit dem „Original“, die ich so erzeuge, verhindern weitere Updates und damit Bugfixes, neue Features, .. Und sie lasten mir einen weiteren Maintenance Job auf, vermutlich für ein Stück Software, welches ich von vorneherein nicht selbst entwickeln wollte.

    Ich kann natürlich auch eine Abstraktion schaffen.
    Wie in deinem Beispiel könnte ich mir eine Abstraktion einfallen lassen, die eine Konfiguration in separaten Konfigurationsdateien erlaubt. Damit stehe ich aber nicht viel besser da. Denn zum einen hast du Recht, andere Entwickler, die das Original kennen, werden sich mit meiner Abstraktion nicht intuitiv zurechtfinden. Vor allem aber verlasse ich mich auf stabile Schnittstellen und wahrscheinlich nutze ich sogar Schnittstellen, die nicht für den normalen Gebrauch vorgesehen waren, sondern Komponenten intern gedacht waren. Diese können sich natürlich auch wieder ändern. Nicht schön, aber passiert. Und was ist dann mit meiner Abstraktion? Dann muss ich die Migrieren. Für die Nutzung, wie sie ursprünglich gedacht war, wird der Entwickler der Komponente sicherlich einen Migrationspfad dokumentiert haben, aber für meine Abstraktion? Unwahrscheinlich?

    Als dritte Variante sollte ich lernen die Konzepte zu akzeptieren und entsprechend zu handeln. Das muss ja nicht in meine eigenen Projekte einfliessen.

    Für den seltenen Fall, dass ich doch abstrahieren/erweitern muss, muss ich ich wissen, warum das so ist.

    Ist es, weil meine Projekt Situation dies erfordert? Dann muss ich mich mit der Maintenance der Erweiterung abfinden.

    Ist es aber, weil ich der Überzeugung bin, dass die vorgefundenen Konzepte lückenhaft/fehlerhaft sind? Dann sollte ich versuchen, mich in das jeweilige Projekt einzubringen.

    Im Fall PHP_Codesniffer gibt es da sogar ein Beispiel:

    „Greg Sherwood took a look at SQLI_CodeSniffer, liked it, and decided these functionalities were worthy the main package.

    So we decided to join efforts and port this and more back into PHP_CodeSniffer. All the work will be avalaible in the 1.3.0 release, we will be really careful of backward compatibility.“
    http://bit.ly/55rg2w

    Reply
  2. @Christian: Da muss ich dir in allen Punkten Recht geben. Danke für den detaillierten Kommentar. Den Blog, den du verlinkt hast werde ich mir auch mal näher anschauen. Klingt interessant.

    Reply
  3. Volle Zustimmung.

    Ich finde man kann, auch selbst wenn Details vielleicht hätten besser gelöst werden können, eigentlich immer noch von allen (großen) Frameworks etwas lernen… und wenn es nur der Fakt ist, dass keine Architektur perfekt sein kann oder nur für bestimmte Zwecke geeignet ist. Alles hat Vor- und Nachteile.

    Aber würde mich doch mal interessieren, was du statt der Vererbung noch so zur Konfiguration vorgeschlagen hättest, die Möglichkeiten sind ja sehr vielfältig und haben sicher alle Vor & Nachteile.

    Möglichkeiten die mir so einfallen würden, wären Init-Funktionen, mit denen ich recht flexibel wäre oder die Bereitstellung von Schnittstellen zur Einbindung von (XML/…)-Konfigurationen, …

    Reply
  4. Ja – XML wäre sicher das Mittel der Wahl gewesen.

    Aber: das Vorbild „CheckStyle“ für Java macht es genauso. Schaut man genauer hin, so findet man unter der Haube sicher einen Code-Parser/Lexer. Auch wenn es altertümlich anmutet, ist diese Lösung für diesen Anwendungsfall zur Zeit einfach State-of-the-Art.

    „Don’t fight the Framework“ sollte nicht heißen, dass man sich nicht trotzdem Gedanken macht, wie es besser gehen kann.

    Natürlich geht es auch mit XML: wenn man seine Wahlmöglichkeiten einschränkt, Methoden vordefiniert und Parameter festlegt. Vielleicht reicht das für 80% der Fälle ja bereits aus? Und siehe: CheckStyle macht es tatsächlich so.

    Wer sollte dich also daran hindern, über ein erweitertes Command-line Interface für CodeSniffer nachzudenken, oder einen Wrapper, der die Konfiguration in ähnlicher Weise wie CheckStyle aus einer XML-Datei lädt? Das hat mit „don’t fight the …“ nichts zu tun.
    Es wäre eine saubere Lösung UND es greift nicht in das bestehende Programm ein.

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen