Wie schafft man einen Komplexitätssprung?


13

Es scheint eine seltene, aber weit verbreitete Erfahrung zu sein, dass man manchmal an einem Projekt arbeitet und plötzlich etwas unerwartet auftaucht, einen riesigen Schraubenschlüssel in die Werke wirft und die Komplexität erheblich steigert.

Ich habe zum Beispiel an einer Anwendung gearbeitet, die mit SOAP-Diensten auf verschiedenen anderen Computern gesprochen hat. Ich entwarf einen Prototyp, der gut funktionierte, und entwickelte dann ein reguläres Frontend, um alles auf eine nette, recht einfache und leicht zu verfolgende Weise zum Laufen zu bringen. Es hat großartig funktioniert, bis wir angefangen haben, Tests in einem breiteren Netzwerk durchzuführen, und plötzlich begann das Zeitlimit für Seiten zu laufen, da die Latenz der Verbindungen und die für die Durchführung von Berechnungen auf Remote-Computern erforderliche Zeit zu Zeitlimit-Anforderungen an die Soap-Dienste führte. Es stellte sich heraus, dass wir die Architektur ändern mussten, um Anforderungen in ihre eigenen Threads auszulagern und die zurückgegebenen Daten zwischenzuspeichern, damit sie schrittweise im Hintergrund aktualisiert werden konnten, anstatt Berechnungen auf Anforderungsbasis durchzuführen.

Die Details dieses Szenarios sind nicht allzu wichtig - in der Tat ist es kein gutes Beispiel, da es durchaus vorhersehbar war und Leute, die viele Apps dieses Typs für diese Art von Umgebung geschrieben haben, es möglicherweise vorweggenommen haben - mit der Ausnahme, dass dies einen Weg darstellt man kann mit einer einfachen Prämisse und einem einfachen Modell beginnen und plötzlich eine Eskalation der Komplexität bis in die Entwicklung des Projekts hinein erleben.

Welche Strategien haben Sie, um mit solchen funktionalen Änderungen umzugehen, deren Bedarf sich - oft aufgrund von Umweltfaktoren und nicht aufgrund von Spezifikationsänderungen - später im Entwicklungsprozess oder aufgrund von Tests ergibt? Wie lassen sich die vorzeitigen Optimierungs- / YAGNI- / Overerengineering-Risiken vermeiden, wenn eine Lösung entwickelt wird, die mögliche, aber nicht unbedingt wahrscheinliche Probleme abschwächt , anstatt eine einfachere und einfachere Lösung zu entwickeln, die wahrscheinlich genauso effektiv ist, aber keine Bereitschaft für diese beinhaltet? jede mögliche Möglichkeit?

Bearbeiten: Crazy Eddies Antwort beinhaltet "Sie saugen es auf und finden den kostengünstigsten Weg, um die neue Komplexität zu implementieren." Das ließ mich an etwas denken, das in der Frage enthalten war, das ich aber nicht speziell angesprochen habe.

Sobald Sie diese Beule getroffen haben, übernehmen Sie die notwendigen Änderungen. Tun Sie das, was das Projekt so nah wie möglich am Zeitplan hält, aber die Wartbarkeit beeinträchtigt, oder kehren Sie zu Ihrer Architektur zurück und überarbeiten es auf einer detaillierteren Ebene, die möglicherweise wartbarer ist, aber alles während der Entwicklung zurückdrängt?

Antworten:


8

Was mir dabei in den Sinn kommt, ist das agile Sprichwort: Die riskantesten und / oder am wenigsten verstandenen Aufgaben zuerst im Projektlebenszyklus angehen . Das heißt, wir versuchen so früh wie möglich ein funktionierendes Gerüst des Projekts zusammenzustellen, um zu beweisen, dass das Konzept funktioniert. Dies ermöglicht es wiederum, jede Art von grausamen Tests durchzuführen, um festzustellen, ob die Architektur unter realen Umständen wirklich ihr Versprechen erfüllt. Wenn die Lösung eine neue, unbekannte Technologie / Plattform / ein unbekanntes Tool enthält, sollten Sie dies auch frühzeitig berücksichtigen.

Wenn die Kernarchitektur in Ordnung ist, können die einzelnen Funktionen inkrementell hinzugefügt und getestet und bei Bedarf mit relativ geringen Kosten umgestaltet werden. Die Notwendigkeit, die Architektur zu ändern, ist das große Risiko, mit dem man sich im Voraus befassen sollte. Dies gibt schnelles Feedback: Im schlimmsten Fall, wenn das gesamte Konzept auseinanderfällt, wissen wir es frühzeitig und können das Projekt mit minimalem Verlust abbrechen.


6

Ihr Beispiel berührte einige der herausforderndsten Aspekte der Programmierung, nämlich verteiltes Rechnen und gleichzeitiges Programmieren , die immer häufiger eingesetzt werden und die Arbeit von Programmierern immer schwieriger machen.

Sogar die "normale" Programmierung (einzelner Thread auf einer Maschine) ist für ein nicht-trviales Programm so komplex, dass es viel Geschick und jahrelange Erfahrung erfordert, um es zu beherrschen - aber noch lange nicht "gelöst". Selbst auf dieser Ebene übersteigen Komplexitäten, die meist auf eine kombinatorische Explosion zurückzuführen sind , die Fähigkeit des menschlichen Gehirns, vollständig zu erfassen und zu verstehen, bei weitem. Anders zu denken ist dumm.

Durch verteiltes Rechnen und gleichzeitiges Programmieren wird die Größe des "Komplexitäts" -Raums um zwei Dimensionen erweitert, die zumindest in Kubik (sp?) (N ^ 3) größer werden als bei "normaler" Programmierung. Denken Sie zum Beispiel an einige neue Probleme und Irrtümer, mit denen wir fertig werden müssen. Es ist lächerlich, mit einer Idee zu spielen, dass man Zusammenhänge und Nebenwirkungen in dieser Größenordnung ergründen könnte.

Ich habe eindeutig keine Silberkugeln, aber ich bin mir ziemlich sicher, dass der größte Fehler, den man machen kann, darin besteht, zu glauben, dass Sie alles verstehen und es gelöst haben.

Einige Ideen, wie man mit all dem fertig wird, zusätzlich zu den anderen Antworten, die bereits behandelt wurden:

  • Große Demut
  • Akzeptieren Sie, dass Ihr System / Programm unvollkommen, unbeständig und unvollständig ist .
  • Bereiten Sie sich auf Fehler vor
  • Veränderung annehmen
  • Planen Sie für Redundanz
  • Denken Sie an die Zukunftssicherheit
  • Betrachten (oder studieren) Sie Biologie oder Soziologie, wie sich komplexe Systeme verhalten
  • Versuchen Sie alles, um einen veränderlichen Zustand zu vermeiden. Gehen Sie für zustandslose Protokolle (wie REST und HTTP).
  • Funktionale Programmierung kann einige der Schmerzen lindern

Ich schätze, ich könnte so weiter machen. Sehr interessantes Thema :)


Schauen Sie sich die Biologie oder Soziologie an (oder studieren Sie sie), wie sich komplexe Systeme verhalten . Der Rest Ihrer Antwort war solide, aber dies hat eine solche periphere Anwendung auf das beschriebene Problem.
Jim G.

1
@ Jim G. Vielleicht. Die Biologie hilft nicht, Ihre For-Loops zu optimieren, aber wenn Sie neue Perspektiven, Erkenntnisse oder effektive Abstraktionen (zur Softwareentwicklung) entwickeln möchten, hilft es, aus der eigenen Sandbox herauszutreten. Das Argument, dass Biologie (oder Soziologie) nichts mit Programmierung zu tun hat, ist nur ein paar Schritte von der Argumentation entfernt, dass OOP oder Designmuster nichts mit Programmierung zu tun haben. Zum Beispiel: OOP : Biologie -> Alan Kay -> OOP / Smalltalk. Oder Design Patterns : Soziologie -> Städtebau -> Christopher Alexander -> Eine Mustersprache -> Design Patterns.
Maglob

@ Jim G. Cont. Einige Zitate, Alan Kay: "Ich dachte an Objekte, die wie biologische Zellen und / oder einzelne Computer in einem Netzwerk sind und nur mit Nachrichten kommunizieren können." das Feld der Architektur und wurde für verschiedene andere Disziplinen angepasst, einschließlich der Informatik "
Maglob

In Ordung. Ich gebe Ihnen eine +1 für Versuchen Sie Ihr Möglichstes, um veränderlichen Zustand und andere Nuggets zu vermeiden . Mein Punkt ist, dass Sie, wenn Ihr Manager Sie mit der Reduzierung der Komplexität beauftragt, mit Sicherheit Occams Rasiermesser auf das Problem anwenden und sich an die Arbeit machen würden. Ich glaube nicht, dass Sie oder jemand anderes bei dem unmittelbaren Problem "auf die Biologie schauen" würde.
Jim G.

2

Ich bin mit dem Geist der Antwort von @ Péter Török nicht einverstanden, da davon ausgegangen wird, dass ein Team (oder eine Einzelperson) die riskantesten Elemente zu Beginn des Projektlebenszyklus voraussehen kann. Zum Beispiel im Fall des OP, das Team konnte nicht die zunehmende Komplexität jedoch voraussehen zu der Multi-Threaded - Lösung angebracht , bis ihr Rücken gegen die Wand war.

Die Frage des OP ist gut und spricht ein Problem an, das viele Softwareentwicklungsgeschäfte haben.

Hier ist, wie ich mit dem Problem umgehen würde:

  1. Befolgen Sie die Ratschläge von Fred Brooks und organisieren Sie Ihre Entwickler wie ein Operationsteam .
  2. Wählen Sie einen weisen und "wohlwollenden" Chirurgen, der beides kann: A) das Vertrauen und den Respekt seiner Kollegen gewinnen; und B) schwierige Entscheidungen rechtzeitig treffen.
  3. Erwarten Sie vom Master-Chirurgen, dass er die Komplexität am vorderen und hinteren Ende des Entwicklungsprozesses reduziert.

Mehr zu Punkt 3:

  1. Der Meister sollte sich bewusst bemühen, die einfachste Lösung vorzuschlagen, die funktionieren wird. Jahrelange Erfahrung sollte den Chirurgen in die Lage versetzen, dies zu tun.
  2. Die umfassendere Organisation, dh die Vorgesetzten des Master-Chirurgen, sollte dem Team genügend Zeit und Ressourcen zur Verfügung stellen, um die Komplexität nach dem Versanddatum zu verringern. Auf diese Weise kann das Entwicklerteam Code zeitnah versenden und Kaizen ausführen , um die Komplexität kontinuierlich zu reduzieren.

Im Falle des OP hätten sie früher mit dem Testen beginnen sollen, um herauszufinden, wie (und ob) ihre Architektur unter realen Umständen funktioniert. Btw mit dem Vorschlag einen „Master Chirurg“ zu haben, Sie scheinen grundsätzlich zu implizieren , dass es sind Menschen , die die technischen Risiken des Projekts vorhersehen kann - den genauen Punkt , den Sie mit Anspruch zu widersprechen.
Péter Török

@ Péter Török: ... Indem Sie vorschlagen, einen "Meisterschirurgen" zu haben, scheinen Sie im Grunde zu implizieren, dass es Leute gibt, die die technischen Risiken des Projekts vorhersehen können : Nein, das bin ich nicht. Ich sage, dass diese Leute beide sind: A) Am besten geeignet, um Komplexität überhaupt zu vermeiden ; und B) Am besten geeignet, um ein Team aus der Komplexität herauszuholen, nachdem der Code ausgeliefert wurde.
Jim G.

IMHO reden wir über die gleiche Sache. Die Erfahrung, die Ihrem "Meister" bei der Auswahl der einfachsten Lösung hilft, die möglicherweise funktioniert, basiert auf Erinnerungen an frühere Projekte und Lösungen und dem Wissen, welche Lösung in welchem ​​speziellen Fall funktioniert hat (oder nicht). Mit anderen Worten, er sucht nach den zutreffenden Lösungen für ein bestimmtes Problem und bewertet die potenziellen Vorteile und Risiken der einzelnen. Dies hilft ihm, den richtigen für die aktuelle Situation zu finden, und vermeidet so die riskanteren Pfade .
Péter Török

1
Dies erinnert mich an ein Zitat des verstorbenen, großartigen Pferdetrainers Ray Hunt: "Wie bekommst du ein gutes Urteilsvermögen? Erfahrung. Wie bekommst du Erfahrung? Schlechtes Urteilsvermögen."
Glenatron

1

Code für Schnittstellen

Erstellen Sie beim Schreiben neuer Funktionen, die mit anderen Funktionen in Verbindung stehen, eine Grenze in Form einer Schnittstelle (der Java-Art), durch die alle Funktionen geleitet werden. Dieser Wille

  1. Stellen Sie sicher, dass Sie die volle Kontrolle darüber haben, welche Funktionen verwendet werden
  2. Sie können mehrere Implementierungen derselben Funktionalität verwenden.
  3. Halten Sie die Gesamtkomplexität niedrig, da die Module nur dünn miteinander verbunden sind und nicht vollständig miteinander verflochten sind.

0

Man kann mit einer einfachen Prämisse und einem Modell beginnen und plötzlich eine Eskalation der Komplexität bis in die Entwicklung des Projekts hinein erleben

Nicht überraschend.

Das ist Softwareentwicklung. Wenn Sie nichts Neues erfinden, laden Sie eine vorhandene, bewährte Lösung herunter.

Es gibt wenig Mittelweg.

Wenn Sie etwas Neues erfinden, muss es mindestens eine Funktion geben, die Sie nicht vollständig verstehen. (Um es vollständig zu verstehen, müssten Sie eine funktionierende Implementierung haben, die Sie nur verwenden würden.)

Wie geht das?

  1. Haben Sie realistische Erwartungen. Sie erfinden etwas Neues. Es muss Teile geben, die Sie nicht verstehen.

  2. Haben Sie realistische Erwartungen. Wenn es beim ersten Mal richtig zu funktionieren scheint, haben Sie etwas übersehen.

  3. Haben Sie realistische Erwartungen. Wenn es einfach wäre, hätte es zuerst jemand anderes gemacht, und Sie könnten diese Lösung einfach herunterladen.

  4. Haben Sie realistische Erwartungen. Sie können die Zukunft nicht sehr gut vorhersagen.


2
Warten Sie, Sie sagen also: Haben Sie realistische Erwartungen?
Glenatron

0

Design und Code mit Blick auf Veralterung. Angenommen, was Sie heute codieren, muss morgen ausgeschnitten und ersetzt werden.


0

Die Umgebung sollte Teil der Spezifikation sein. Daher ist eine Änderung der Umgebung eine Änderung der Spezifikation. Wenn Sie andererseits Ihren Prototyp und Ihr Design auf eine andere als die in der Spezifikation angegebene Umgebung gestützt haben, haben Sie einen dummen Fehler begangen. So oder so saugen Sie es auf und finden den kostengünstigsten Weg, um die neue Komplexität zu implementieren.


0

Wie bei den meisten Programmierproblemen kommt es meiner Meinung nach darauf an. Dieses Problem ist so grundlegend für die kreative Arbeit, dass Sie nicht vergessen sollten, dass Fehler auftreten werden, und das ist in Ordnung . Das Programmieren ist ein teuflisches Problem, und Sie wissen normalerweise nicht die richtige Lösung für das Problem, bis Sie es bereits gelöst haben.

Es gibt jedoch eine Reihe lokaler, spezifischer Faktoren, die hier eine Rolle spielen könnten, wie zum Beispiel:

  • Die Ziele für dieses System. Ist es eine einmalige Sache? Beabsichtigen Sie, dieses System mittel- bis langfristig funktionsfähig zu halten?

Kurzfristig mag es sich nicht lohnen, mehr als genug darüber nachzudenken, um es zum Laufen zu bringen. Refactoring ist teuer und schafft Ihrem Benutzer keinen unmittelbaren Endwert. jedochIch kann mir so gut wie keinen anderen Fall vorstellen als absolute Wegwerf-Software, bei der es sich kurzfristig so wenig lohnt, Ihr Design zu verbessern. Es ist viel wichtiger, zu verstehen, was Sie getan haben, und es schnell zu beheben, als sofort fertig zu sein. Wenn es längerfristig ist, wird es sich sehr wahrscheinlich irgendwann auszahlen (und möglicherweise viel früher als alle Beteiligten denken) oder umgekehrt (wenn es nicht getan wird, wird es sehr bald Schmerzen verursachen, anstatt "wenn wir es reparieren müssen"). Ich bin fast versucht zu sagen, "nimm dir immer die Zeit, um es besser zu machen", aber es gibt einige Fälle, in denen das nicht möglich ist.

  • Die Ziele des Teams. Ist es eher ein "Jetzt um jeden Preis machen" oder ein "Lass es uns richtig machen"?

Dies sollte Ihre Entscheidungen enorm beeinflussen. Ihr Team wird diese Entscheidung entweder unterstützen, indem es Ihnen Ressourcen für die Neugestaltung zur Verfügung stellt, oder es wird die sofortige Lösung verlangen. Meiner Meinung nach ist es eine große rote Fahne, wenn Sie feststellen, dass das Team Sie ständig in die falsche Richtung treibt. Ich habe gesehen, dass solche Dinge in einem Szenario enden, in dem ständig Feuer gelöscht wird, in dem es nie Zeit für ein Redesign gibt, weil Sie immer die Probleme beheben, die Ihr schlechtes Design verursacht. Es kann aber auch einen Mittelweg geben: "Klebeband" jetzt so schnell wie möglich reparieren (aber tatsächlich tun).

  • Ihr Verständnis des Problems. Warum hat die vorherige Lösung nicht funktioniert?

Wirklich wichtig. Überlegen Sie, was der Fehler oder das Problem ist und warum es passiert. Diese Art von Situation ist eine großartige Gelegenheit, fehlerhafte (oder fehlende) Annahmen, Einschränkungen und Wechselwirkungen zu finden. Im Allgemeinen ist es immer besser, Ihr Problem zu verstehen, als das aktuelle Problem zu lösen. Dies ist wahrscheinlich Ihre größte Verteidigung gegen YAGNI / Overengineering. Wenn Sie Ihr Problem gut genug verstehen, dann werden Sie lösen es und nicht andere Probleme.

Schließlich versuchen , die Dinge den richtigen Weg zu bauen . Ich spreche nicht über die Fehler und Probleme, denen Sie gegenüberstehen, wenn Sie entweder mehr über das Problem oder Ihr inhärentes menschliches Versagen verstehen. Ich meine nicht "mach keine Fehler und mach es beim ersten Mal perfekt" - das ist unmöglich. Ich meine, versuchen Sie, die Komplexität in Ihrer täglichen Arbeit gut zu managen, zerbrochene Fenster zu reparieren, so einfach wie möglich zu halten, Ihren Code und Ihr Denken ständig zu verbessern. Auf diese Weise , wenn (nicht falls) Änderung klopft an der Tür, können Sie es mit offenen Armen statt einer Schrotflinte begrüßen.

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.