Ich habe eine Codebasis, in der der Programmierer dazu neigte, Dinge in Bereichen zusammenzufassen, die keinen Sinn ergeben. Angenommen, Sie haben ein Fehlerprotokoll, über das Sie sich anmelden können
ErrorLog.Log(ex, "friendly message");
Er fügte verschiedene andere Mittel hinzu, um genau dieselbe Aufgabe zu erfüllen. Z.B
SomeClass.Log(ex, "friendly message");
Was sich einfach umdreht und die erste Methode aufruft. Dies erhöht die Komplexität ohne zusätzlichen Nutzen. Gibt es ein Anti-Pattern, um dies zu beschreiben?
design-patterns
anti-patterns
P. Brian Mackey
quelle
quelle
Antworten:
Es lohnt sich nur, eine schlechte Codierungsgewohnheit als Antipattern zu bezeichnen, wenn sie einigermaßen verbreitet ist.
Den Rest nennen wir einfach "Müllcode" ...
Wenn ich einen Namen für diese schlechte Angewohnheit vorschlagen würde, wäre es "Obsessive Abstraktionsstörung" :-)
quelle
Nein, es ist kein Anti-Pattern, aber ich würde die folgenden Probleme ansprechen.
Verstoß gegen das Prinzip der Einzelverantwortung
SRP sagt, dass eine Klasse einen Grund haben sollte, sich zu ändern. Das Hinzufügen einer Protokollierungsmethode bedeutet, dass sich auch die Klasse ändern muss, wenn die Protokollierungslogik geändert werden soll.
Verletzung einer
is-a
BeziehungBasisklassen sind keine Toolboxes, in denen Sie verschiedene Komfortmethoden hinzufügen können.
Auf diese Weise werden alle geerbten Klassen effektiv mit den Implementierungen der Basisklasse gekoppelt.
Vergleichen Sie das mit der Zusammensetzung.
quelle
Nicht, dass dies akzeptabel wäre, aber dies könnte nur eine unvollendete Umgestaltung sein. Vielleicht hatte SomeClass.log () eine eigene Logik und wurde zuerst implementiert. Und später wurde ihnen klar, dass sie ErrorLog.Log () verwenden sollten. Anstatt also 100 Stellen zu ändern, an denen SomeClass.Log () aufgerufen wird, haben sie nur an ErrorLog.Log () delegiert. Persönlich würde ich alle Verweise auf ErrorLog.Log () ändern oder zumindest SomeClass.log () kommentieren, um zu sagen, warum es so delegiert, wie es tut.
Nur etwas zu beachten.
quelle
Der Begriff "Lasagne Code" kommt mir in den Sinn, obwohl er anscheinend verschiedene Dinge für verschiedene Menschen bedeutet . Meine Interpretation war immer "geschichtet, um geschichtet zu werden".
quelle
Ich bin mir nicht sicher, ob dies als Verstoß gegen das Prinzip der Einzelverantwortung zu bezeichnen ist, da bei einer Änderung der ErrorLog-Methodensignatur (der von SomeClass aufgerufenen Methode) jeder Clientcode, der diese Methode aufruft, fehlschlägt.
Es gibt offensichtlich eine Möglichkeit, die Vererbung zu verwenden (oder Klassen zu erstellen, die protokolliert werden müssen, indem eine Protokollierungsschnittstelle implementiert wird).
quelle
Oder wir könnten dies als einen "lehrbaren Moment" ansehen :)
Ihr Entwickler ist möglicherweise auf halbem Weg zu einer guten Idee. Angenommen, Sie möchten die Anforderung haben, dass alle Ihre Geschäftsobjekte in der Lage sind, intelligent zu protokollieren. Sie könnten definieren:
Jetzt können Sie innerhalb Ihrer Objekte das ErrorLog-Objekt verwenden, um die Protokollierung tatsächlich durchzuführen, während SomeClass-Code der Protokollnachricht einen objektspezifischen Wert hinzufügt. Anschließend können Sie Ihre Protokollierungs-APIs erweitern, um dateibasierte, datenbankbasierte oder nachrichtenbasierte Protokollierungsfunktionen zu implementieren, ohne Ihre Geschäftsobjekte zu berühren.
quelle
Ich bin mir nicht sicher, ob das automatisch böse ist.
Wenn Sie SomeClass.Log aufrufen, ist es mit Sicherheit böse, aber wenn Log nur von WITHIN SomeClass verwendet wird, wird die Kopplung abgeschnitten, und ich würde es als akzeptabel bezeichnen.
quelle
Dies ist in bestimmten Codierungsstilen tatsächlich ziemlich häufig, und die Grundlagen der Gedankenrichtung sind an sich kein Anti-Pattern.
Es ist sehr wahrscheinlich das Ergebnis von jemandem, der notwendigerweise ohne Kenntnis der breiteren Codebasis codiert: "OK, dieser Code muss einen Fehler protokollieren, aber diese Funktion ist nicht der primäre Zweck des Codes. Daher benötige ich eine Methode / Klasse, die dies erledigt für mich". Das ist eine gute Denkweise. Aber ohne zu wissen, dass ErrorLog existiert, haben sie SomeClass erstellt. Sie fanden dann zu einem späteren Zeitpunkt ErrorLog, und anstatt alle Verwendungen der von ihnen eingegebenen Methode zu ersetzen, führten sie ihren Methodenaufruf ErrorLog aus. Hier wird das zum Problem.
quelle
Zufällige Komplexität ist Komplexität, die in Computerprogrammen oder deren Entwicklungsprozessen auftritt und für das zu lösende Problem nicht wesentlich ist. Während wesentliche Komplexität inhärent und unvermeidbar ist, wird zufällige Komplexität durch den Ansatz verursacht, der zur Lösung des Problems gewählt wurde.
http://en.wikipedia.org/wiki/Accidental_complexity
quelle
Dies kann ein Missbrauch / Missverständnis des Fassadenmusters sein . Ich habe ähnliche Dinge in einer Codebasis gesehen, mit der ich gearbeitet habe. Die Entwickler machten eine Phase durch, in der sie verrückt nach Designmustern waren, ohne die übergeordneten Prinzipien des OO-Designs zu verstehen.
Ein Missbrauch des Fassadenmusters führt zu einer Unschärfe der Abstraktionsebenen in den Anwendungsebenen.
quelle
Dieser Programmierer verpackt Code so, dass er nicht direkt vom Protokollierungsmodul abhängt. Ohne spezifischere Informationen ist es nicht möglich, ein spezifischeres Muster anzugeben. (Dass diese Wrapper nicht nützlich sind, ist Ihrer Meinung nach unmöglich, ohne weitere Informationen zuzustimmen oder abzulehnen.)
Mögliche Muster hierfür sind Proxy , Delegate , Decorator , Composite oder andere, die mit dem Umbrechen, Ausblenden oder Verteilen von Anrufen zu tun haben. Es kann eines dieser Dinge in einem unvollständigen Entwicklungszustand sein.
quelle
Ich könnte mir vorstellen, dass es ein kultureller Unterschied ist. Vielleicht gibt es einen guten Grund für doppelte Funktionalität in dieser speziellen Codebasis. Ich könnte mir die Leichtigkeit des Schreibens als einen solchen Grund vorstellen. Die Python - Programmierer in mir würde immer noch sagen , dass es schlecht ist, da „ Es one-- sein sollte und vorzugsweise nur eine --obvious Weg , es zu tun. “, Aber einige Perl Jungs vielleicht die Tatsache gewöhnt, dass " Es gibt mehr als eine Weg, es zu tun ".
quelle