Java >> Java Tutorial >  >> Java

Wir werden es brauchen

Es gab eine Zeit (vor nicht allzu langer Zeit), in der wir alles entworfen haben, bevor wir irgendeinen Code geschrieben haben.

Wir haben die Anforderungen unserer Anwendung gesammelt und die Anforderungsspezifikation geschrieben. Wir nahmen diese Anforderungen und entwarfen eine Architektur, die uns half, sie zu erfüllen. Wir haben ein Architekturdesigndokument als Leitfaden geschrieben, dem wir bei der Implementierung unserer Anwendung gefolgt sind.

Leider hatten wir nie die Gelegenheit, diese Dinge zu tun .

Wir waren nur Entwickler, die den Plänen anderer folgen mussten. Unsere Aufgabe war es, Code zu schreiben, indem wir der Architektur folgten, die von den Architekten entworfen wurde.

Trotzdem hätte unser Job einfach sein sollen. Wir kannten alle Anforderungen und hatten eine Architektur, die uns helfen sollte, alle technischen Probleme zu lösen, denen wir begegnen könnten.

Das war ein schöner Traum. Leider liefen die Dinge nicht wie geplant:

  • Die Anforderungen waren nicht korrekt. Um die Sache noch schlimmer zu machen, fanden wir dies heraus, nachdem wir die meisten (oder alle) bereits implementiert hatten. Das bedeutete, dass wir große Teile der Anwendung neu schreiben mussten. Das hat Zeit und Geld gekostet.
  • Die Architektur hat uns nicht geholfen, weil die Architekten dachten, dass sie ein gut strukturiertes Problem lösen, für das es nur eine richtige Lösung gibt. Unglücklicherweise lösen Softwareprojekte schlecht strukturierte Probleme. Das bedeutete, dass wir keine Möglichkeit hatten zu lernen, und wir mussten auf jeden Fall dem ursprünglichen Plan folgen. Schlechte Entscheidungen wurden nicht verworfen, denn das hätte die Architekten schlecht aussehen lassen.
  • Wir waren frustriert, weil wir keine Kontrolle über unsere Arbeit hatten. Wir waren im Grunde nur Schreibmaschinen.

Dann hörten wir von agiler Softwareentwicklung.

Großes Design vorne ist ein Anti-Muster

Das Agile Manifest versprach, uns zu befreien. Darin steht:

"Personen und Interaktionen über Prozesse und Tools
Funktionierende Software über eine umfassende Dokumentation
Kundenzusammenarbeit über Vertragsverhandlungen
Auf Veränderungen reagieren über das Befolgen eines Plans

Das heißt, während die Elemente
rechts einen Wert haben, schätzen wir die Elemente auf der linken Seite mehr."

Wir waren aufgeregt. Wir begannen zu glauben, dass das große Design vorne ein Anti-Muster ist, das vermieden werden sollte. Wir begannen mit dem Schreiben von Code, indem wir diesen Prinzipien folgten:

  • Just-In-Time (JIT)-Architektur
  • Halte es einfach, Dummkopf (KISS)
  • Du wirst es nicht brauchen (YAGNI)

Wir hatten nur eine Regel:

"Tue das Einfachste, was möglicherweise funktionieren könnte"

Es machte für uns absolut Sinn. Das vorweggenommene Architekturdesign hat unsere Arbeit nicht einfacher gemacht. Tatsächlich machte es unsere Arbeit schwieriger. Wir waren von dem Wasserfallmodell begeistert und wollten etwas ganz anderes machen. Wir haben das Architekturdesign im Voraus aufgegeben und beschlossen, alle technischen Probleme zu lösen, wenn wir auf sie stoßen.

Dies funktionierte ziemlich gut in kleinen Softwareprojekten (und am Anfang eines größeren Softwareprojekts). Als wir jedoch das Architekturdesign im Voraus aufgegeben haben, begannen wir, die Konsequenzen unserer Entscheidungen zu ignorieren.

Wir waren aufgeregt, motiviert und dachten, dass wir das Richtige tun. Aber die Wahrheit war, dass unsere Aktionen drei sehr häufige Probleme verursachten:

  • Wir haben unseren Code in kleinen Schritten geschrieben und ihn basierend auf dem Feedback unserer Kunden geändert. Wir hätten anhalten und unseren Code umgestalten sollen, bevor wir mit unserer nächsten Aufgabe fortfahren, aber das erfordert Disziplin und die hatten wir nicht.
  • Wir haben Sonderfälle, Ausnahmesituationen oder Fehler nicht richtig gehandhabt. Wir haben das Einfachste getan, was möglicherweise funktionieren könnte, und weil es schwierig war, mit diesen Situationen umzugehen, entschieden wir uns, es später zu implementieren, wenn es wirklich nötig war. Das Problem war, dass unser Code, als er gebraucht wurde, bereits so ein Durcheinander war, dass die Reparatur zu lange gedauert hätte. Deshalb haben wir uns entschieden, einfach eine Fehlermeldung in die Logdatei zu schreiben und weiterzumachen.
  • Wir haben verschiedene Muster, Frameworks oder Bibliotheken verwendet, um dasselbe Problem zu lösen. Da wir keine technische Autorität hatten, wählte jeder von uns das „beste“ Werkzeug für die Aufgabe aus und benutzte es. Wir haben eine Codebasis erstellt, die unter dem Anti-Pattern der Lavaschicht leidet. Das mag über mehrere Jahre passiert sein, aber ich habe es im ersten Monat eines Greenfield-Projekts erlebt.

Es scheint, dass der Verzicht auf das Architekturdesign im Voraus uns glücklicher gemacht und uns wahrscheinlich geholfen hat, unseren Kunden einen Mehrwert zu bieten. Es hat uns jedoch nicht geholfen, bessere Software zu entwickeln.

Wir haben unsere kurzfristige Produktivität gegenüber unserer langfristigen Produktivität priorisiert. Wir haben einen großen Schlammball geschaffen und dafür gesorgt, dass die Aufrechterhaltung unserer Anwendung schmerzhaft ist unbequem.

„Upfront Design“ richtig gemacht

Übertreibe ich? Sie können darauf wetten, dass ich das bin, aber meine Erfahrung hat mir gezeigt, dass das Team diese Fehler sehr wahrscheinlich macht, wenn es nicht im Voraus entwirft. Ich habe das immer und immer wieder gesehen, und die Chancen stehen gut, dass Sie das auch gesehen haben.

Aus diesem Grund denke ich, dass wir von der Architektur im Voraus profitieren können, aber wir sollten es nicht übertreiben. Wir müssen uns daran erinnern, dass das Ziel des „altmodischen“ Vorabdesigns darin besteht, den einzigen Weg zu finden, um das Problem des Kunden zu lösen. Wir brauchen diese Art von Design im Voraus nicht.

Wir brauchen vorab ein Design, das uns nicht die Hände bindet. Wir brauchen ein Design im Voraus, das uns hilft, unsere Optionen so lange wie möglich offen zu halten, und uns nicht daran hindert, Dinge zu ändern, die wir beim ersten Mal nicht richtig machen.

Es ist schwer, die Balance zwischen dem „altmodischen“ Design im Voraus und keinem Design zu finden, aber es ist definitiv möglich. Wir können beginnen, indem wir diese fünf Regeln befolgen:

  • Wir sollten unsere Werkzeuge kennen. Wenn ein bestimmtes Problem oft auf die gleiche Weise gelöst wird, hat das wahrscheinlich einen guten Grund. Deshalb sollten wir auch diese Methode in Erwägung ziehen.
  • Wir sollten Best Practices vermeiden, die uns nicht dabei helfen, unsere Arbeit besser zu machen. Der gesunde Menschenverstand ist das wichtigste Werkzeug eines Softwareentwicklers, und wir sollten immer daran denken, ihn zu verwenden.
  • Bevor wir Code schreiben, sollten wir entwerfen, wie wir mit bereichsübergreifenden Anliegen wie Fehlerbehandlung, Validierung, Transaktionen und Sicherheit umgehen. Wir sollten auch eine ungefähre Vorstellung von der Architektur unserer Anwendung haben, aber wir sollten sie nicht in Stein gemeißelt haben. Es ist nur eine Skizze und wir werden (oder sollten) sie aktualisieren, wenn wir mehr über das Problem des Kunden erfahren.
  • Wenn wir ein einzelnes Feature implementieren, sollten wir das einfachste tun, was möglicherweise funktionieren könnte. Nachdem wir den Code geschrieben haben, müssen wir die Konsequenzen unserer Entscheidungen bewerten. Wenn sich unsere Änderungen negativ auf die Architektur unserer Anwendung auswirken, müssen wir unseren Code umgestalten oder neu schreiben. Dies ist ein Gefallen, den wir den Entwicklern tun müssen, die unsere Anwendung pflegen, nachdem wir weitergezogen sind.
  • Wir müssen sicherstellen, dass jedes Mitglied unseres Teams ein Architekt ist. Wenn alle Teammitglieder am Architekturdesign teilnehmen dürfen, befolgen sie mit größerer Wahrscheinlichkeit die gemeinsamen Richtlinien, da sie uns bei der Erstellung geholfen haben.

P.S. Wenn Sie mehr über dieses Thema erfahren möchten, sollten Sie die Doktorarbeit von Veli-Pekka Eloranta lesen.


Java-Tag