Wann sollte Komplexität beseitigt werden?


14

Eine vorzeitige Einführung von Komplexität durch Implementierung von Entwurfsmustern, bevor sie benötigt werden, ist keine gute Praxis.

Wenn Sie jedoch alle (oder sogar die meisten) SOLID-Prinzipien befolgen und gemeinsame Entwurfsmuster verwenden, werden Sie einige Komplexität einführen, wenn Funktionen und Anforderungen hinzugefügt oder geändert werden, um Ihren Entwurf so wartbar und flexibel wie nötig zu halten.

Sobald diese Komplexität eingeführt ist und wie ein Champion funktioniert, wann haben Sie sie entfernt?

Beispiel. Ich habe eine Bewerbung für einen Kunden geschrieben. Wenn ursprünglich dort erstellt, wo mehrere Möglichkeiten, Mitarbeiter zu erhöhen geben. Ich habe das Strategiemuster und die Fabrik benutzt, um den gesamten Prozess schön und sauber zu halten. Im Laufe der Zeit wurden bestimmte Erhöhungsmethoden vom Anwendungseigner hinzugefügt oder entfernt.

Die Zeit vergeht und ein neuer Besitzer übernimmt. Dieser neue Besitzer hat eine harte Nase, hält alles einfach und hat nur einen einzigen Weg, um eine Gehaltserhöhung zu geben.

Die Komplexität, die das Strategiemuster benötigt, wird nicht mehr benötigt. Wenn ich dies aus den Anforderungen, wie sie jetzt vorliegen, heraus codieren würde, würde ich diese zusätzliche Komplexität nicht einführen (aber sicherstellen, dass ich sie mit geringem oder keinem Aufwand einführen könnte, falls dies erforderlich sein sollte).

Entferne ich jetzt die Strategieimplementierung? Ich glaube nicht, dass dieser neue Besitzer jemals ändern wird, wie Erhöhungen gegeben werden. Die Anwendung selbst hat jedoch gezeigt, dass dies passieren kann.

Dies ist natürlich nur ein Beispiel für eine Anwendung, bei der ein neuer Eigentümer viele Prozesse übernimmt und vereinfacht. Ich könnte Dutzende von Klassen, Schnittstellen und Fabriken entfernen und die gesamte Anwendung viel einfacher machen. Beachten Sie, dass die aktuelle Implementierung einwandfrei funktioniert und der Eigentümer damit zufrieden ist (und überrascht und noch glücklicher, dass ich ihre Änderungen aufgrund der diskutierten Komplexität so schnell implementieren konnte).

Ich gebe zu, dass ein kleiner Teil dieses Zweifels darauf zurückzuführen ist, dass der neue Eigentümer mich höchstwahrscheinlich nicht mehr benutzen wird. Es ist mir eigentlich egal, dass jemand anderes dies übernimmt, da es kein großer Einkommensgenerator war.

Aber ich kümmere mich um 2 (verwandte) Dinge

  1. Es ist mir ein bisschen wichtig, dass der neue Betreuer beim Versuch, den Code zu verstehen, etwas genauer nachdenken muss. Komplexität ist Komplexität und ich möchte den Psycho-Maniac, der hinter mir her ist, nicht verärgern.

  2. Umso mehr mache ich mir Sorgen, dass ein Konkurrent diese Komplexität sieht und denkt, ich implementiere nur Entwurfsmuster, um meine Arbeitsstunden aufzufüllen. Dann dieses Gerücht verbreiten, um mein anderes Geschäft zu verletzen. (Ich habe dies erwähnt gehört.)

So...

Sollte die zuvor benötigte Komplexität im Allgemeinen entfernt werden, obwohl sie funktioniert, und es gab einen historisch nachgewiesenen Bedarf für die Komplexität, aber Sie haben keinen Hinweis darauf, dass sie in Zukunft benötigt wird?

Auch wenn die obige Frage im Allgemeinen mit "Nein" beantwortet wird, ist es ratsam, diese "unnötige" Komplexität zu beseitigen, wenn das Projekt an einen Konkurrenten (oder einen Fremden) übergeben wird?

Antworten:


7

In gewisser Weise denke ich, dass dies größtenteils eine Geschäftsentscheidung ist und nicht unbedingt auf dem Code selbst basiert. Einige Dinge zu beachten:

  • Werden Sie für die Änderungen bezahlt?
  • Funktioniert der Code derzeit wie erwartet?
  • Gibt es Sicherheits- oder Leistungsprobleme mit dem Code wie er ist?
  • Übersteigt die Höhe der technischen Schulden die Kosten für deren Behebung?
  • Was ist realistisch wahrscheinlich, wenn Sie den Code unverändert lassen?
  • Was sind zukünftige Probleme, die mit oder ohne Refactoring auftreten könnten?
  • Wie hoch ist die Haftung für Sie und Ihr Unternehmen?

Sie sind in der besten Position, um diese Fragen zu beantworten. Aufgrund Ihrer Beschreibung weiß ich jedoch nicht, ob ich mich darum kümmern würde, Dinge umzugestalten und zu vereinfachen, da es sich nicht so anhört, als ob es Ihre Zeit wert wäre. Wenn es derzeit funktioniert, ist der Kunde zufrieden und Sie möchten nicht für die Aktualisierung bezahlt werden. Lassen Sie es dann sein und arbeiten Sie an einer umsatzbringenden Aktivität.

Kurz gesagt, machen Sie eine Kosten-Nutzen-Analyse und eine Risikobewertung beider Wege und ergreifen Sie die sicherste, effizienteste und rentabelste Vorgehensweise.


6

Wird dieser Code nicht entfernt und durch einen einfachen Code ersetzt, um die Codierung in Zukunft zu vereinfachen? Dies ist eine Funktion, die der Kunde berücksichtigen und bezahlen muss.

Möglicherweise haben Sie etwas Nützliches, von dem ein anderer Entwickler lernen könnte, aber die Wahrscheinlichkeit, die App eines anderen Kunden zu finden, in die er sie einbinden kann, ist unwahrscheinlich.

Das Klatschen über den Code eines Mitbewerbers kann man nicht verhindern. Sie werden dumm aussehen, wenn sie versuchen, Kunden zu rekrutieren.


+1 für "und bezahlen für". Wenn Sie den Kunden auffordern, die Änderung zu bezahlen, müssen Sie ihm erlauben, zu entscheiden, ob er die Änderung vornimmt. Beachten Sie, dass durch das flexible Verlassen des Systems der Wiederverkaufswert des Unternehmens erhöht wird, da der NEXT-Eigentümer leichter Änderungen vornehmen kann.
John R. Strohm

3

Ein allgemeines Sprichwort lautet: "Wenn es nicht kaputt ist, reparieren Sie es nicht".

Es gibt mehrere Gründe für diese Regel. Einige von diesen könnten sein, dass die "Vereinfachung" das Risiko birgt, neue, andere und möglicherweise größere Fehler einzuführen, die Entwicklungszeit von anderen wertvolleren Unternehmungen zu verlängern und für eine unerwartete zukünftige Geschäftsgelegenheit, die dies ist, die völlig falsche Änderung sein könnte entsteht.

Wenn es einen ausreichenden Geschäftswert gibt, damit dieser Code portierbar und besser wartbar ist, entscheiden Sie, ob dieser Wert wirklich ausreicht, um den aktuellen Code als "defekt" zu betrachten. Es könnte gut sein, dass eine größere Geschäftserweiterung geplant ist, oder dass Sie einen versteckten Fehler in der Komplexität vermuten, der das Geschäft zum Erliegen bringen könnte.


2

Erstens kann es vorkommen, dass die App bereits einmal von einem neuen Eigentümer übernommen wurde. Und der nächste Besitzer kann wieder die Komplexität nutzen, von der er im Moment nicht profitiert.

Abgesehen davon sind nicht-triviale Änderungen des Arbeitscodes immer mit einem Risiko verbunden. Daher sollte der Kunde (wie bereits erwähnt) diesen zustimmen (und dafür bezahlen). Wenn die derzeitige "zusätzliche" Komplexität keine erkennbaren, messbaren Nachteile (wie z. B. Leistungsprobleme) verursacht, gibt es keinen triftigen Grund, sie zu beseitigen.

(Potenzielle) Kunden, die Sie (nicht) ausschließlich aufgrund von Gerüchten der Wettbewerber einstellen, sind es meiner Meinung nach nicht wert, sie zu haben, es sei denn, Sie benötigen dringend Einkommen. Sie haben gute und logische Gründe, warum Sie die App so implementiert haben, wie Sie es getan haben, und jeder ernsthafte Kunde wird dies wahrscheinlich verstehen. Jemand, der Sie nicht - oder nicht einmal danach fragt -, wird Ihnen auf diesem Weg wahrscheinlich mehr Ärger bereiten, als es der Job wert ist.


1

Sollte die zuvor benötigte Komplexität im Allgemeinen entfernt werden, obwohl sie funktioniert, und es gab einen historisch nachgewiesenen Bedarf für die Komplexität, aber Sie haben keinen Hinweis darauf, dass sie in Zukunft benötigt wird?

Nein.

Selbst wenn die oben stehende Frage im Allgemeinen mit "Nein" beantwortet wird, ist es ratsam, diese "unnötige" Komplexität zu beseitigen, wenn das Projekt an einen Konkurrenten (oder einen Fremden) übergeben wird.

Nein. Warum funktioniert es so, Ihre Zeit für die Behebung der niedrigen Priorität zu verschwenden? Kein Schaden für den Code, der dort bleibt.

Wie für Ihre Frage: Wann sollte Komplexität beseitigt werden?

Ich nehme an, wenn es nicht kaputt ist, repariere es nicht .


0

Um die Komplexität beseitigen zu können, muss Folgendes zutreffen:

  1. Das entfernte Stück muss unabhängig vom Programm sein. Wenn es Abhängigkeiten vom umgebenden Programm zum fraglichen Code gibt, funktioniert es nicht, die Komplexität zu entfernen
  2. Wenn es nach Komplexität aussieht, ist es leider sehr wahrscheinlich, dass die Teile nicht unabhängig sind und die Abhängigkeiten Ihr Programm zum Erliegen bringen, wenn Sie das Teil entfernen
  3. Das Entfernen aller Abhängigkeiten wird einige Zeit in Anspruch nehmen, sodass diese Zeit in Betracht gezogen werden muss, wenn Sie abschätzen, ob die Operation den Aufwand wert ist
  4. Die meiste Zeit ist es die Mühe nicht wert, aber Sie werden einfach beschließen, keinen neuen Code zu erstellen, der den alten verwendet

Sie sind unabhängig und ich habe sie tatsächlich entfernt und alle Einheiten- / Integrations- / Regressionstests bestanden. Die Komplexität ist einfach eine Implementierung der Strategie, die mindestens eine Schnittstelle und eine konkrete Implementierung dieser Schnittstelle erfordert. In den rund zwei Dutzend Fällen, in denen der neue Eigentümer alles vereinfacht hat, könnte dies mit einer einzigen Klasse geschehen.
ElGringoGrande

0

Ich denke, hier ist etwas Größeres am Werk ... Skalierbarkeit

Was Sie sprechen, heißt Skalierbarkeit . Es spielt keine Rolle, ob das Codieren komplex ist, es spielt eine Rolle, ob sich die Anwendung basierend auf neuen Geschäftsregeln oder geänderten Geschäftsregeln entwickeln kann. Was passiert, wenn der nächste Besitzer etwas ganz anderes möchte?

Also, ich sage, behalte den Code und dokumentiere ihn. Es ist ein Merkmal, wie die Anwendung verwendet werden kann.


0

Sollte die zuvor benötigte Komplexität im Allgemeinen entfernt werden, obwohl sie funktioniert, und es gab einen historisch nachgewiesenen Bedarf für die Komplexität, aber Sie haben keinen Hinweis darauf, dass sie in Zukunft benötigt wird?

Es gibt einen Aufwand und ein Risiko, die Komplexität zu beseitigen. Wenn dies höher ist als der zusätzliche Aufwand und das Risiko, den übermäßig komplexen Code zu verwalten, behalten Sie ihn bei. Andernfalls entfernen Sie es. Es ist jedoch schwierig, diese Risiken abzuschätzen.

Ich möchte hinzufügen, dass Sie das Risiko einer schwierigeren Wartung verringern können, indem Sie dokumentieren, warum Sie die Entwurfsmusterstrategie an erster Stelle im Code verwendet haben. Ich persönlich bin der Meinung, dass jedes Designmuster auf eine explizite Anforderung (funktional oder nicht funktional) zurückgeführt werden sollte.

Auch wenn die obige Frage im Allgemeinen mit "Nein" beantwortet wird, ist es ratsam, diese "unnötige" Komplexität zu beseitigen, wenn das Projekt an einen Konkurrenten (oder einen Fremden) übergeben wird?

Ihr Szenario, dass Sie von einem Wettkampf um die Padding-Stunden ausgeschlossen werden, ist genau der Grund, warum Sie die Komplexität dokumentieren sollten. Wenn Sie die Verwendung eines Musters dokumentieren und (mit einer bestimmten Kundenanforderung) begründen, sind Sie abgesichert. Wenn Sie ein Muster nicht mit den Anforderungen eines Kunden rechtfertigen können, sieht es nach Überdesign oder Musterentzündung aus.

Wenn sich die Anforderungen ändern, können Sie das Verlassen des Codes aufgrund des Risikos, dass Sie den Code brechen könnten (oder aufgrund des Arbeitsaufwands zum chirurgischen Entfernen des Musters), rechtfertigen.


Ich finde es gut zu unterscheiden zufälliger Komplexität und essentieller Komplexität zu unterscheiden , da Muster oft beides beinhalten.

Das heißt, Ihre Anforderung, unterschiedliche Algorithmen für die Entscheidung über Erhöhungen zu unterstützen, ist eine wesentliche Komplexität (Teil des zu lösenden Problems). Die Wartung Ihres Codes wird durch das Strategy-Pattern erleichtert, aber die fest programmierte if / then-Alternative zu Strategy funktioniert weiterhin. Ich habe in meinen Masterstudiengängen Übungen gemacht, in denen die Studierenden die Möglichkeit finden, Strategie in Open-Source-Projekten anzuwenden. Die Komplexität ist bei der Anwendung der Strategie nicht unbedingt besser / schlechter (da es sich um eine wesentliche Komplexität handelt). Manchmal ist es sogar schwieriger, Strategy zu verstehen, da Code mit Polymorphismus in mehrere Klassen aufgeteilt wird, anstatt in einen großen if / then / else-Block.

Idealerweise funktioniert ein Muster, wenn die Vorteile, die es bietet, die Kosten seiner Nachteile überwiegen. Wiederum ist es schwierig, diese Dinge zu quantifizieren. Oft macht ein Muster den Entwickler glücklich (nicht nur, weil es das Hinzufügen einer neuen Raise-Strategie erleichtert, sondern dem Entwickler auch die Gewissheit gibt, dass ein Muster angewendet wurde). Es ist schwierig, Kunden zu zeigen, wie sie davon profitieren.

Dem Kunden ist es egal oder er versteht nicht einmal die Details. Für den Fall, dass die neue Eigentümerin KISS in ihren Prozessen einsetzt, ist es ihre Reduzierung der wesentlichen Komplexität, die sich auch auf die Softwarelösung auswirken sollte.

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.