Wie bekämpfen Sie die Komplexität des Designs? [geschlossen]

8

Ich kämpfe oft mit Overengineering - die für die Entwicklung der Software verantwortliche Person hat eine Architektur, die viel zu kompliziert ist.

Es ist alles gut und schön, all die esoterischen Features zu haben, von denen die Benutzer nie etwas wissen werden, und dieses Erfolgserlebnis zu bekommen, wenn du etwas tust, was dir all die Artikel sagen, ist das neueste, coole Ding, aber wir sind es Wir werden die Hälfte unserer Entwicklungszeit auf dieses Denkmal für unsere Cleverness verwenden, und nicht, wissen Sie, das tatsächliche Produkt, das unsere Benutzer brauchen, und das obere Management erwartet, dass es in einem angemessenen oder zumindest zeitlich begrenzten Zeitraum abgeschlossen wird.

Und Sie werden wahrscheinlich sowieso nur auf die einfachere Lösung zurückgreifen müssen, wenn Ihnen die Zeit davonläuft, das heißt, wenn Sie diese Chance bekommen.

Wir haben alle den Refrain gehört: Keep It Simple, Stupid ™.

Wie kämpfen Sie mit Überkomplexität in Ihrem Team?

Ein Beispiel, mit dem ich in letzter Zeit wiederholt arbeiten musste, ist die Entscheidung, zu einem vollständig denormalisierten Datenbankentwurf statt zu einem RDBMS zu gehen. "Weil es schneller ist!" Vollständig denormalisierte Datenbanken sind sehr schwer zu korrigieren und eignen sich nur für wirklich spezielle Datenprobleme wie Flickr oder Ebay, und sie können im Verhältnis zum Rest Ihrer Entwicklung extrem teuer sein.

    
ʞɔıu 02.03.2009, 16:31
quelle

14 Antworten

12

Zahn und Nagel, und manchmal verlierst du. Das Problem ist, dass es immer leicht ist, versucht zu werden, etwas cool zu bauen.

  

Warum etwas Einfaches und Effizientes bauen, wenn es kompliziert und wunderbar sein kann?

Versuchen Sie, die Leute an die XP-Regel zu erinnern, die einfachste Sache zu bauen, die möglicherweise funktionieren kann.

    
Charlie Martin 02.03.2009, 16:38
quelle
6

Stellen Sie sicher, dass Sie irgendwelche Ideen von jemand anderem abprallen lassen. Oft sind wir so sehr damit beschäftigt, Dinge auf eine bestimmte Art und Weise zu tun, dass es andere Augen braucht, um dich richtig zu stellen. Es gab viele Male, dass ich schwierige Probleme herausgefunden habe, indem ich jemand anderen dort hatte, der sagte "Müssen wir das wirklich?" Dies macht meinen Code einfacher.

Im Hinblick auf den Umgang mit Menschen, mit denen Sie nicht einverstanden sind, hat Ward Cunningham einen guten Punkt:

  

Es war ein Wendepunkt in meiner Programmierkarriere, als mir klar wurde, dass ich nicht jedes Argument gewinnen musste. Ich würde über Code mit jemandem sprechen und ich würde sagen: "Ich denke, der beste Weg, es zu tun, ist A." Und sie sagten: "Ich denke, der beste Weg, es zu tun, ist B. Ich würde sagen:" Nun, nein, es ist wirklich A. "Und sie würden sagen:" Nun, wir wollen B. machen. "Das war es Ein Wendepunkt für mich, als ich sagen konnte: "Gut. Do B. Es wird uns nicht so sehr weh tun, wenn ich falsch liege. Es wird uns nicht so sehr weh tun, wenn ich richtig liege und du B, weil wir Fehler korrigieren können. Lasst uns herausfinden, ob es ein Fehler ist. Normalerweise ist es C. Es ist eine Lernerfahrung für uns beide. Wenn wir ohne die Erfahrung entscheiden, lernt keiner von uns wirklich. Ward gewann und jemand anderes nicht. Oder umgekehrt. Es ist zu viel Kampf. Warum sagst du nicht: "Nun, lass es uns einfach aufschreiben und sehen, was passiert. Wenn es nicht funktioniert, werden wir es ändern." "

Mein Rat? Wenn Sie etwas Besseres machen wollen, stellen Sie sich einen einfachen Prototyp vor, der zeigt, dass es besser ist. Die Meinungen sind großartig, aber Code spricht.

    
Jason Baker 02.03.2009 17:38
quelle
6

Ich habe diese Formel irgendwo gesehen:

skill = Komplexität des Problems / Komplexität der Lösung http://img39.imageshack.us/img39/1586/ whatisskill.png

Mit anderen Worten, es erfordert Geschick, um eine einfache Lösung für ein komplexes Problem zu erstellen. Wenn jemand absichtlich komplexe überentwickelte Lösungen entwirft und stolz darauf ist, dann ist er unbewusst inkompetent.

Was mir persönlich dabei hilft, meine Entwürfe einfach zu halten, ist der TDD-Zyklus. Schreiben Sie zuerst einen Test, der angibt, was Sie erreichen möchten und dann "die einfachste Sache, die möglicherweise funktionieren könnte" . Und überlege von Zeit zu Zeit, was du produziert hast und denke darüber nach, wie du es einfacher machen kannst.

Bauen Sie niemals zusätzliche Flexibilitäts- und Abstraktionsschichten in das System ein, bis es von etwas benötigt wird, das Sie jetzt haben. Das Ändern des Codes ist einfach, wenn Sie eine gute Komponententestsuite haben, sodass Sie diese Abstraktionsschichten später bei Bedarf hinzufügen können, falls es jemals auftritt. Sonst "Du wirst es nicht brauchen" .

Einige Symptome von zu komplexem Design sind beim Schreiben von Tests kompliziert. Wenn die Tests einen langen Setup-Code erfordern, haben Sie möglicherweise zu viele Abhängigkeiten oder auf andere Weise zu viel Komplexität. Wenn Sie auf Nebenläufigkeitsfehler stoßen, sollten Sie vielleicht darüber nachdenken, wie Sie das System so gestalten, dass die Nebenläufigkeit auf die absolute Mindestanzahl von Klassen beschränkt ist. Vielleicht verwenden Sie eine Message-Passing-Architektur wie das Actor-Modell und machen praktisch jede Komponente single-threaded, obwohl das System als Ganzes Multi-Threading ist.

    
Esko Luontola 30.05.2009 17:16
quelle
4

Zumindest für mich ist das größere Problem, dass es oft schwer ist zu sagen, welches Feature da drin ist, wegen seiner buzzwordfreundlichen, magazinartigen Unternehmensgüte und was da drin ist, weil es ein Maß an Flexibilität hinzufügt, das in die Zukunft.

Es hat sich gezeigt, dass Menschen im Allgemeinen schrecklich sind, wenn sie zukünftige Komplexität und Nebenwirkungen von aktuellen Entscheidungen antizipieren. Leider bedeutet das nicht immer das Einfachste - in meinem Fall gab es viele Dinge, von denen ich dachte, dass sie auf den ersten Blick zu kompliziert waren und den Wert von bis viel später (äh ... Frühling) nicht sahen. Auch Dinge, die ich für sinnvoll hielt, erwiesen sich als wild überkompliziert (EJB1). Ich weiß also, dass meine Intuition über diese Dinge fehlerhaft ist.

Am besten - jede Art von Indirection-Layer sollte mit einem Argument unterstützt werden, das den Wert der hinzugefügten Flexibilität gegenüber der hinzugefügten Dev-Komplexität unterstützt.

Allerdings sind Leute, die dogmatisch ein bestimmtes db-Setup auf abstraktem Boden halten, wahrscheinlich im "Bauen, weil ich lese, dass es das Richtige ist" -Camp. Es könnte unrealistisch sein, aber einige Leute könnten davon überzeugt sein, wenn Sie eine Testversion und einen Benchmark erstellen, insbesondere wenn die Ergebnisse mehr Aufwand zeigen, was zu einer geringfügigen Leistungssteigerung führt.

    
Steve B. 02.03.2009 16:48
quelle
3
  

Es ist alles gut und schön, alles zu haben   die esoterischen Eigenschaften, die Benutzer werden   weiß nie über und ...

Dies wäre feature creep , nicht unnötig kompliziertes Design. Es unterscheidet sich von Ihrem Beispiel in Datenbanken.

  

Ein Beispiel, mit dem ich arbeiten musste   in letzter Zeit wiederholt sich die Entscheidung   wurde gemacht, um zu einem voll zu gehen   denormalized Datenbank-Design eher   als ein RDBMS. "Weil es schneller ist!"

In diesem Fall können verschiedene Dinge passieren. Einer von ihnen ist, Sie könnten sich irren und diese Leute könnten wirklich wissen, was sie sagen, weil sie mit sehr ähnlichen Beispielen gearbeitet haben. Eine andere ist, dass sie falsch sein könnten, d. H. Ihr Design bietet nicht die Geschwindigkeitsvorteile, die sie beanspruchen. In diesem Fall könnte es zwei verschiedene Situationen geben: (1) Sie geben Geschwindigkeit zu viel Gewicht in ihrem Design, oder (2) Geschwindigkeit ist wirklich kritisch. Wenn die Geschwindigkeit tatsächlich so wichtig ist, sollte sich das Team nicht nur auf Annahmen verlassen - sie sollten verschiedene Prototypen ausprobieren und ihre Geschwindigkeit in den kritischen Pfaden bewerten. Man baut ein F1-Auto nicht nur "weil es schneller ist", sondern man probiert mehrere alternative Konstruktionslösungen aus und wählt die schnellste aus, die die Wartungskosten immer noch nicht zu stark erhöht.

Manchmal können Sie streiten und eine Einigung erzielen, manchmal können Sie nicht. Es ist Leben.

Aber ein letztes Wort. Sie kämpfen nicht mit Komplexität. Du behandelst es. Du identifizierst die wirklich wichtigen Dinge und handelst entsprechend.

    
Daniel Daranas 02.03.2009 17:01
quelle
2

Ich nehme an, Sie meinen "vollständig denormalisiertes Datenbankdesign und nicht ein normalisiertes (z. B. drittes oder viertes normales Formular) Modell", weil ein relationales Modell von einem RDBMS unabhängig davon verwaltet wird, wie normal es ist.

Kann nicht beurteilen, ohne mehr über Ihre Anforderungen, Ihre Fähigkeiten und die Ihrer Teammitglieder zu erfahren.

Ich befürchte, dass Ihre KISS-Ermahnung in diesem Fall nicht funktioniert, weil eine große, denormalisierte Tabelle als die einfachste mögliche Sache verteidigt werden könnte.

Wie löst jemand diese Art von Problemen? Kommunikation, Überzeugung, bessere Daten, Prototypen alternativer Technologien und Techniken. Dies macht die Softwareentwicklung so schwierig. Wenn es nur einen Weg gäbe, um diese Dinge zu tun, und jeder mit ihnen einverstanden wäre, könnten wir es wirklich skripten oder jemanden dazu bringen, Systeme zu entwickeln und damit fertig zu werden.

Holen Sie sich Daten. Deine Worte sind vielleicht nicht genug. Wenn ein schneller Prototyp Ihren Punkt demonstrieren kann, erstellen Sie ihn.

"Starke Meinungen, leicht gehalten" sollte dein Motto sein.

Manchmal ist ein technischer Punkt es nicht wert, Ihr gesamtes Team zu entfremden. Manchmal ist es. Ihr Anruf.

    
duffymo 02.03.2009 16:43
quelle
2

Du kämpfst jemandes Überdesign / Feature Creep auf verschiedene Arten:

  1. Anforderung der Funktionspriorität basierend auf den tatsächlichen Benutzeranforderungen. Mock-up-Funktionen für Alpha-und Beta-Tester, und fragen, ob sie N Monaten Verzögerung dafür handeln würden.

  2. Aggressiv refaktorisieren, um Spezialgehäuse zu vermeiden. Teilen Sie den Code bei Bedarf in Schichten oder modulare Komponenten auf. Finden Sie ein Gleichgewicht zwischen "funktioniert jetzt gut" und "einfach später zu erweitern".

  3. Benachrichtigen Sie Ihr Management, wenn Sie mit Designentscheidungen nicht einverstanden sind, bereiten Sie sich darauf vor, übergangen zu werden, und akzeptieren Sie die Entscheidung. Geh nicht über irgendjemandes Kopf oder Sabotage-Code.

HUAGHAGUAH 02.03.2009 17:34
quelle
2

Der beste Weg, den ich gefunden habe, ist, unaufhörlich zu fragen - immer wieder - "Was ist das Geschäftsproblem, das wir zu lösen versuchen" und "Wie hilft diese Entscheidung, dieses Problem zu lösen".

Ich finde, dass Leute zu oft zu Lösungen springen, anstatt klar darüber zu sein, was das Problem ist.

In Ihrem Beispiel für die Organisation einer Datenbank lautet meine Frage: "Was denken wir, sind die Transaktionsanforderungen für dieses Projekt heute, nächsten Monat, nächstes Jahr, in fünf Jahren?" Es könnte sein, dass es Sinn macht, viel Zeit zu investieren, um das Datenmodell richtig zu machen, es könnte Zeitverschwendung sein. Sie wissen nicht, was die Parameter sind, bis Sie die Problemdefinition löschen.

    
John Chenault 02.03.2009 18:45
quelle
1

Sie leiden unter "zu vielen Architekten im Team" -Syndrom. Ein oder zwei Personen sollten höchstens ein System entwerfen / entwerfen, das von einem Team von 5 bis 10 Personen kodiert wird. Input ist von allen willkommen, aber die Entscheidungsträger in der Architektur sollten wenig und erfahren sein.

(die Zahlen sind halb zufällig und können je nach anderen Faktoren auch anders sein)

    
cherouvim 02.03.2009 16:39
quelle
0

Ich versuche offen zu sein, wenn ich die Dinge diskutiere. Aber wenn ich mit jemand anderem zwischen etwas, das einfach und ein anderes kompliziert ist, diskutiere, werde ich so stur wie es sein kann. Es hilft ziemlich viel, solange Sie von einer Entscheidung zur anderen sehr kohärent sind.

    
Benoît 02.03.2009 16:39
quelle
0

Ihr Beispiel ist nicht wirklich ein kompliziertes Design, es ist eine Design-Wahl, der Sie nicht zustimmen. Da Sie an dem Code arbeiten, könnten Sie leicht Recht haben, da viele dieser Entscheidungen von Leuten getroffen werden, die einen Artikel in einem Artikel lesen und denken, dass es sich wie ein gutes Ziel anhört, oder die Entscheidung könnte von jemandem getroffen worden sein, der darauf gestoßen ist Probleme vorher und versuchte zu verhindern, dass es wieder passiert.

Persönlich habe ich eine Menge Dinge auf einfache Art und Weise und eine Menge davon auf die harte Tour gemacht, und ich bin nie glücklich, wenn ich etwas auf die leichte Art und Weise auf die harte Tour mache. Jetzt habe ich Tricks wie "gehe nie um eine nackte Sammlung herum, wickle es immer in eine Business-Klasse".

Wenn ich jemandem, der die gleichen Erfahrungen nicht gemacht hat, die Gründe dafür erklären würde, würden sie es nicht verstehen, bis sie den "leichten Weg" einige Male auf den "harten Weg" zu vergleichen versuchen / p>     

Bill K 02.03.2009 17:18
quelle
0

Die Lösung sollte nicht komplexer als das Problem sein.

Die Frage verflechtet sich mit dem Gedanken der essentiellen Komplexität. Ein sort muss jedes Element durch sein Wesen berühren. Wie viel komplexer muss es dann sein, um das Problem zu lösen, angesichts der technischen Einschränkungen, die es gibt?

    
Paul Nathan 02.03.2009 17:23
quelle
0

Haben die Beteiligten genug Zeit und Ansporn, um eine einfache Lösung zu finden? Ohne Vorsicht wird die Komplexität zunehmen. Wenn du die meiste Zeit damit verbringst, einen möglichst schnellen Bugfix oder Feature-Zusatz zu machen, dann reicht es nicht, "Keep it simple" zu sagen.

Stellen Sie sicher, dass einige Leute im Team Kriegswunden aus der Wartung großer Programme und Personen mit Erfahrung im Refactoring haben, und geben Sie ihnen dann Zeit, die Software zu sortieren. Wenn Sie festlegen können, dass bestimmte Funktionen und Opportunities nicht verfügbar sind, können Benutzer nicht benötigten Code entfernen. Wenn Sie eine Metrik möchten, sollten Sie Codezeilen reduzieren. aber versuch nicht darüber nachzudenken. Verbesserung der Testabdeckung Überlegen Sie, Code-Bits zu eliminieren, die schwer zu testen sind.

    
Dickon Reed 02.03.2009 17:24
quelle
0

Versuchen Sie nicht, alles auf einmal zu machen. Brechen Sie jedes Problem / jede Aufgabe in handhabbare Teile. Dann priorisiere und behalte KISS und YAGNI im Hinterkopf. Dadurch können Sie sich darauf konzentrieren, das zu erstellen, was Sie benötigen . Wenn du es richtig gemacht hast, wirst du einen guten Kern haben, den du später hinzufügen kannst, mit der Zeit, dem Geld, den Ressourcen und der Inspiration.

    
PartialOrder 02.03.2009 17:34
quelle