Wie gehen professionelle Softwareentwicklungsteams mit der Komplexität des Designs in nicht trivialen Projekten um?

9

Erstens ist mir klar, dass diese Frage etwas lang und vage sein kann, und ich entschuldige mich dafür. Dies ist wahrscheinlich ein grundlegendes Problem mit einem kurzen Namen für jeden, der es "verstanden" hat, aber da mir diesbezüglich etwas fehlt, bitte beschreiben Sie das Problem mit mir.

Ich programmiere auf die eine oder andere Weise, seit ich ungefähr 11 Jahre alt war. Das bedeutet, dass ich mir von Anfang an meistens alles selbst beigebracht habe. Ich habe eine technische Ausbildung erhalten, aber nicht ausschließlich in Informatik (ich habe einen Abschluss in Photonik). Wir hatten natürlich Programmierkurse, aber das waren hauptsächlich grundlegende Dinge für mich und ich habe nicht viel Neues gelernt. Ich habe mich auf diesem Weg aus Freude weitergebildet und wusste immer, dass ich eine Karriere als Programmierer verfolgen würde, aber alle meine Projekte waren zu dieser Zeit ziemlich klein. Ich hatte keine Probleme, sie im Kopf zu behalten und zu pflegen.

Jetzt bin ich in einem Team führend, aber nicht in einem Unternehmensumfeld. Ich arbeite für die Universität und entwickle wissenschaftliche Software (in C ++) für technische Anwendungen. Plötzlich wächst das Projekt (relativ) groß und ich habe die meiste Zeit Probleme, mich darum zu kümmern. Ich verliere viel Zeit und Mühe in zwei Dingen:

  1. Wenn ich zu einem Codeabschnitt zurückkehren muss, an dem ich eine Weile nicht gearbeitet habe, fällt es mir schwer, mich daran zu erinnern, wie er funktioniert hat. Ich verbringe viel Zeit damit, die Header-Dateien für die relevanten Klassen zu überprüfen und die Kommentare zu lesen, die ich unterwegs in die Quelldateien eingefügt habe. Ich wünschte, es gäbe eine Art "Schaltplan", den ich leichter sehen und wiedererlangen könnte.
  2. Wenn ich Änderungen einführe, merke ich manchmal auf halbem Weg, dass das, was ich versuche, die Dinge woanders kaputt macht (oder schlimmer noch, es wird nur zur Laufzeit als Überraschung angezeigt). Ich kehre zurück und beginne es anders zu machen, nur um herauszufinden, dass ich den Einfluss auf eine andere Komponente vernachlässigt habe. Ich wünschte, es gäbe ein "Architekturdiagramm", in dem ich sehen könnte, wie Dinge erledigt werden, wie das, was ich versuche, andere Komponenten beeinflusst und eine Möglichkeit für mich, detailliert zu planen, bevor ich mit der Implementierung von Änderungen beginne.

Die meisten Leute, mit denen ich zusammenarbeite, haben ähnliche Geschichten wie ich - starke technische Orientierung und manchmal großartige Fähigkeiten, aber keine Möglichkeit, ihre Arbeit zu organisieren. Ihre Projekte sind jedoch normalerweise viel kleiner als meine, so dass sie irgendwie zurechtkommen. Für mich bedeutet das jedenfalls, dass ich alleine bin und niemanden habe, von dem ich die guten Praktiken lernen kann.

Ich habe einen Aufbaustudiengang in IT-Management absolviert und finde ihn zwar recht zufriedenstellend, er richtet sich jedoch hauptsächlich an Nicht-Programmierer, die über Projektmanagementmethoden, Budget- / Zeitplanschätzungen, Unternehmensarchitektur usw. unterrichten - nicht über Software-Design und -Planung als solche. Das ist in Ordnung, ich versuche auch das Zeug zu lernen. Natürlich wurden einige Tools (wie UML) und die Arten von Softwareentwicklungsprozessen (Kaskade, iterativ, agil ...) eingeführt, aber offensichtlich nicht sehr detailliert, und es fällt mir schwer, zu entscheiden, was ich auswählen und verwenden soll ( und in welchem ​​Umfang).

Ich habe viele Fragen und Antworten zum Software-Design auf SO gelesen - es gibt viele, die dies mit diesem oder jenem speziellen Tool oder dieser Methode tun, und wenn ich davon überzeugt wäre, dass die UML-Dokumentation meine Probleme lösen würde, würde ich es aufgreifen und fang an es zu benutzen. Aber einige Leute schwören darauf, andere sagen, es sei nutzlos. Ich suche nach einer Antwort auf einer höheren Abstraktionsebene - gibt es Möglichkeiten, die beiden Probleme zu lösen, die ich habe, und wie machen Sie das persönlich? Was soll ich lernen, um es zu können, möglicherweise ohne an ein bestimmtes Werkzeug gebunden zu sein? Diese kommen und gehen von Zeit zu Zeit aus der Mode, und ich gehe davon aus, dass ihre Anwendbarkeit je nach Art des Projekts unterschiedlich ist.

Vielen Dank für das Lesen, ich konnte nicht kurz sagen, was ich meine (mangelnde Erfahrung im Software-Design und Vokabeln).

neuviemeporte
quelle
2
Ich denke, die häufigste professionelle Antwort auf die Schwierigkeiten, über die Sie sprechen, ist "Fuck it", gefolgt von der Schuldzuweisung an das Management, das Produkt oder eine andere zufällige SOB.
Edward Strange

Antworten:

9

Wenn ich zu einem Codeabschnitt zurückkehren muss, an dem ich eine Weile nicht gearbeitet habe, fällt es mir schwer, mich daran zu erinnern, wie er funktioniert hat. Ich verbringe viel Zeit damit, die Header-Dateien für die relevanten Klassen zu überprüfen und die Kommentare zu lesen, die ich unterwegs in die Quelldateien eingefügt habe.

Stellen Sie sich vor, wie sich der arme Kerl, der nach Ihnen kommt, fühlen wird - er hat nicht einmal den Vorteil, einmal gewusst zu haben, wie Ihr Code funktioniert. Anstatt zu versuchen, Ihren Code zu entschlüsseln, sollten Sie die Dokumentation überprüfen, die Sie für das betreffende Modul geschrieben haben. Diese Dokumentation sollte eine ziemlich genaue Ansicht darüber bieten, was das Modul tut, warum. Es ist nicht "das Modul beginnt mit der Initialisierung von drei Arrays mit einer Triple-for-Schleife ...", sondern: "Dieses Modul ruft die vom Hauptsensor des Fabulotron gesammelten Daten ab und ordnet sie in das Standardformat Neopolitan (Schokolade, Vanille, Erdbeere) um. und liefert es an das Analysemodul. "

In einer perfekten Welt hätten Sie ein Designdokument, das die verschiedenen Module im System beschreibt und ihre jeweiligen Verantwortlichkeiten beschreibt, und jedes Ihrer Module könnte einfach auf dieses Dokument zurückgreifen, um zu erklären, was sie tun: "Dieses Modul bietet die Fabulotron-Datenerfassungsdienst gemäß Abschnitt 4.8 des Konstruktionsdokuments: http://fabulotron.org/design/section4-8.html . " Wenn Sie so etwas nicht haben, schreiben Sie sich während der Arbeit einen Überblick über jedes Modul. Sie müssen kein Buch schreiben - ein paar Absätze reichen oft aus, um sich zu orientieren.

Wenn ich Änderungen einführe, merke ich manchmal auf halbem Weg, dass das, was ich versuche, die Dinge woanders kaputt macht (oder schlimmer noch, es wird nur zur Laufzeit als Überraschung angezeigt). Ich kehre zurück und beginne es anders zu machen, nur um herauszufinden, dass ich den Einfluss auf eine andere Komponente vernachlässigt habe.

Dies könnte ein Hinweis darauf sein, dass Ihre Module zu stark miteinander verbunden sind. Je unabhängiger Sie Ihre Module / Klassen / Einheiten gestalten können, desto unwahrscheinlicher ist es, dass Sie auf diese Art von Problem stoßen. Versuchen Sie, die Schnittstellen zwischen Modulen so explizit wie möglich zu gestalten und sie auf das zu beschränken, was vorhanden sein muss. Eine Schnittstelle ist ein Vertrag. Wenn Sie wissen, dass ein Modul seinen in der Schnittstelle angegebenen Verpflichtungen nachkommt, müssen Sie nichts anderes darüber wissen. Dadurch wird verhindert, dass Änderungen an dem Modul, an dem Sie arbeiten, Auswirkungen auf andere Module haben.

Ich wünschte, es gäbe ein "Architekturdiagramm", in dem ich sehen könnte, wie die Dinge gemacht werden

Die Verwendung von Standardteilen kann dabei hilfreich sein. C ++ bietet Standardteile in Form der Standardvorlagenbibliothek. Wenn Sie diese Teile gegebenenfalls verwenden, können Sie auf einer höheren Abstraktionsebene arbeiten. Wenn Sie Ihren eigenen Code geschrieben haben, um Datenstrukturen wie Listen zu verwalten, müssen Sie und die folgenden ständig die Quelle lesen, um herauszufinden, was los ist. Wenn Sie stattdessen Standardteile verwenden, die von der STL bereitgestellt werden, kann jeder C ++ - Programmierer schnell erkennen, was Ihr Code tut, ohne sich in Ihre Datenverwaltungsroutinen zu vertiefen.

Eine andere Art von Standardteil kommt von Designmustern. Dies sind Standardkonzepte, die als Kurzform verwendet werden können, um zu erklären, wie die Beziehung zwischen zwei Objekten funktioniert.

Caleb
quelle
Danke für die Antwort. Natürlich benutze ich STL seit vielen Jahren, aber die Abfolge der Schritte, die mein Programm unternimmt, um eine erfundene Berechnung durchzuführen, ist manchmal selbst bei seiner Verwendung schwer vollständig abzubilden. Gleiches gilt für Module. Ich meinte nicht, dass das Ändern eines anderen das andere bricht, sondern dass das Ändern von etwas irgendwo einen Fehler verursacht, z. B. wenn ein Benutzer etwas nicht Standardmäßiges in der GUI ausführt, wobei eine komplizierte Sequenz durch die unvorhersehbare Reihenfolge der Schritte, die er unternimmt, um es abzuschließen, noch komplizierter wird.
Neuviemeporte
5

Ich war nur für kurze Zeit ein professioneller Entwickler und hatte große Probleme damit, als ich anfing. Ich war in erster Linie Autodidakt, sogar durch die Universität. Zum Glück haben die Leute, mit denen ich zusammengearbeitet habe, viel Erfahrung und konnten mich über die Verwaltung und Bearbeitung großer Projekte informieren.

Eines der ersten Dinge, die ich tun musste, war, mich hinzusetzen und sauberen Code zu lesen . Das ist ein fantastisches Buch, das mir geholfen hat zu verstehen, wie man Code schreibt, den ich verstehen konnte, als ich darauf zurückkam, oder den jemand anderes verstehen konnte.

Das zweite war, gute Qualitätstests zu schreiben, Einheit, Integration, Akzeptanz. Wenn Ihr Code gut getestet ist, wissen Sie schnell, wann Sie etwas kaputt gemacht haben, und können das Problem schnell diagnostizieren. Es gibt viele gute Testressourcen im Internet, und ich bin mir nicht sicher, welche die besten sind, die Sie vorschlagen können.

Meine wichtigsten Punkte sind Testen und Bereinigen von Code.

Klee
quelle
Vielen Dank für den Vorschlag, ich werde das Buch auf jeden Fall lesen (obwohl das "agile" im Untertitel darauf hinweist, dass es für diese Methodik am relevantesten ist). Ich habe Tests und habe viele Bücher im Codierungsstil gelesen (z. B. Pragmatic Programmer). Ich bemühe mich immer, saubere und gut getrennte Schnittstellen zu erstellen, aber ein automatisierter Test ist für den GUI-Teil meiner Anwendung schwierig und ich habe immer noch keine Ein Weg für ein gutes Gesamtdesign in größerem Maßstab, der über die Implementierung "sauberer" Praktiken in relativ kleinen Codestücken hinausgeht.
Neuviemeporte
2

Hier finden Sie einige allgemeine Ideen für die Organisation großer Softwaresysteme. Der größte Teil meiner Erfahrung liegt in Internet-Systemen, aber ich denke, diese Ideen gelten für Engineering-Software.

  • Separate Funktionalität in relativ isolierte modulare Blöcke. Beispielsweise haben Sie möglicherweise ein Modul für jede Berechnungsfamilie, die Ihre Software bereitstellt.
  • Wenden Sie das MVC-Entwurfsmuster für die Benutzeroberfläche an, falls vorhanden. Halten Sie die Schnittstelle und das Modell durch genau definierte Grenzen getrennt.
  • Erwägen Sie die Verwendung von Ebenen zum Gruppieren von Modulen. In einer Anwendung, die Abstraktionsschichten verwendet, hängt jede Schicht nur von der darunter liegenden Schicht ab.
  • Nehmen Sie beim Schreiben der Dokumentation an, dass Sie alle Implementierungsdetails vergessen. Unter dieser Annahme werden Sie eine Menge Dokumentation schreiben - vielleicht wird die Hälfte Ihres Codes aus Kommentaren bestehen, aber Sie werden später viel weniger verwirrt sein.
  • Automatisierte Unit-, Integrations- und Abnahmetests sind in einigen Bereichen großartig, aber C ++ - Entwickler scheinen gemischte Gefühle zu haben.
  • Zeichnen Sie stark auf Designmuster . Designmuster sind nicht nur allgemein gute Ideen, sondern bieten auch ein allgemeines Vokabular in der Softwareentwicklung. Das Aufrufen einer Klasse als WidgetFactory ist eine übersichtliche Methode, um zu kommunizieren, dass es sich um eine Klasse handelt, die zum Erstellen von Widgets vorhanden ist.

Es ist lange her, dass ich mit Engineering-Software gearbeitet habe, daher kann Ihr Kilometerstand bei diesen Vorschlägen variieren. Viel Glück!

greg
quelle
1

Die Antwort lautet Software Engineering.

Das heißt, bei großen Projekten folgen Sie einer festgelegten Abfolge von Anforderungserfassung, Prozessdefinition, Spezifikation usw., lange bevor die eigentliche Codierung erfolgt.

Je nach Umgebung und Kultur werden verschiedene Methoden angewendet. Unternehmen vom Typ Unternehmen tendieren dazu, " Rational Unified Process " oder ähnlichem zu folgen. Tech-Start-ups entscheiden sich normalerweise für eine Variation von Agile , Regierungsabteilungen für eine überarbeitete Waterfall- Methode.

In allen Fällen hilft Ihnen der Prozess dabei, genau zu definieren, was Sie tun, und gegen Ende des Projekts können Sie nachweisen, dass Sie es getan haben.

James Anderson
quelle
Unter der Annahme, dass sich die Anforderungen nicht ändern (eine unrealistische Annahme in vielen Fällen, wie ich weiß), ist es tatsächlich möglich, alles vor dem Codieren anzugeben und dann ohne größere Änderungen eine funktionierende Software aus der Spezifikation zu erstellen? Ich kann es mir einfach nicht vorstellen. Ich muss anfangen zu programmieren, um in das Gefühl zu kommen. ein wenig
zwicken, noch
Dies mag für kleine Projekte funktionieren, aber für große Projekte müssen Sie sich zuerst mit den Anforderungen auseinandersetzen. Ein wesentlicher Bestandteil von RUP ist auch die Modellierung des vorgeschlagenen Systems mit UML- und Sequenzdiagrammen. Es ist viel einfacher, ein Modell zu optimieren und umzugestalten als der eigentliche Code.
James Anderson
@neuviemeporte: Es kommt darauf an. Manchmal ändern sich Anforderungen oder neue Anforderungen werden während der Entwicklung entdeckt. Manchmal sind die Anforderungen von Anfang an klar und nur einige kleine Details ändern sich während der Entwicklung, aber die Gesamtarchitektur bleibt gleich.
Giorgio
1

Ich würde wärmstens empfehlen, Enterprise Architect in die Hände zu bekommen , das zwar nicht kostenlos ist, aber akademische Preise bietet. Es ist ein hervorragendes Werkzeug zum Zeichnen von Projekten sowohl auf Makro- als auch auf Mikroebene. Es kann auch Ihre Quelldateien in Klassendiagramme zurückentwickeln, was wahrscheinlich ein guter Anfang für Sie wäre, um zu dokumentieren und neu zu organisieren, wie Ihre Anwendung zusammenpasst.

Ich würde auch die Empfehlungen von @ Klee unterstützen. Lassen Sie sich nicht von vermeintlichen "agilen" Tools abschrecken, da es sich lediglich um Best-Practice-Elemente handelt, die auch praktisch (wenn nicht obligatorisch) sind, wenn Sie einem agilen Prozess folgen. Eine kontinuierliche Integration (zum Beispiel) ist jedoch unabhängig von Ihrer Methodik wertvoll. Darüber hinaus sind Unit-Tests (cppUnit?) Ihre Freunde. Unit-Tests sollten sehr machbar sein, wenn Sie die von Ihrer Benutzeroberfläche aufgerufenen Logikklassen testen, anstatt die Benutzeroberfläche direkt zu testen. Es gibt auch Tools, mit denen Sie UI-Tests automatisieren können, aber ich würde versuchen, zuerst das Back-End-Material zusammenzustellen.

Viel Glück!

Matthew Flynn
quelle
1

Ich glaube, dass Ihr Problem drei Dimensionen hat

  1. Programmiererorientiert
  2. Programmorientiert
  3. Programmpflege - orientiert

In Bezug auf das erste Problem haben Sie möglicherweise Programmierer, die das Konzept der Programmfunktionen nicht verstehen (dies geschieht häufig in Unternehmenskonfigurationen). Anhand Ihrer Frage und der Domäne, in der Sie sich befinden, scheinen Sie und Ihr Team die Kontrolle über die Funktionsweise des Programms zu haben, können es jedoch nicht in kurzer Zeit in ein Arbeitsprogramm umsetzen (um ein Beispiel zu nennen, ich habe von Menschen gehört Postdoktoranden in Physik haben Probleme beim Verstehen von Zeigern in der Programmierung und ich bin sicher, dass Physik viel schwieriger ist als C ++). Wenn dies der Fall ist, ist Ihr Problem hauptsächlich programmorientiert (Sie müssen das Glück haben, dass die Menschen in Ihrer Umgebung verstehen können, was Ihr Programm tut, und es schätzen können).

Bei programmbezogenen Problemen wäre einer meiner empörenden Vorschläge, auf eine höhere Abstraktionsebene als C ++ zu wechseln, z. B. eine neue Sprache wie Python oder Haskell zu lernen (Python ist recht einfach zu erlernen und wenn Sie gute Mathematiker haben, Haskell ist einfach toll). Wenn Sie auf eine höhere Abstraktionsebene wechseln, bleibt Ihre Codegröße niedrig, ist auf lange Sicht leicht zu verstehen und zu warten, und Änderungen werden schnell vorgenommen. Sie können also 10 Codezeilen anstelle der ursprünglichen 50 Codezeilen verwenden. Außerdem würde es definitiv helfen, jemanden mit Fachkenntnissen in Computerprogrammierung zu haben. Wenn Sie an einer Universität sind, können Sie auch einige Studenten in GUI und Schnittstellen einbeziehen, damit Sie sich mehr auf die Funktionalität konzentrieren können. Ich empfehle auch das Buch Large-Scale C ++ Software Design von John Lakos(Es ist ein ziemlich großes Buch, Sie können in der Zeit, die Sie zum Lesen des Buches benötigt haben, ein erfahrener Python-Programmierer werden.)

Wenn Sie die ersten beiden Dimensionen Ihres Problems sortieren, wird die dritte automatisch gelöst. Da ich glaube, dass Sie an einem einzigen großen Projekt arbeiten, jeder anständigen Projektmanagement-Software, durch die Sie kommen. Vorausplanung ist notwendig. Wenn Sie sofort mit dem Codieren beginnen, werden Sie möglicherweise zu sehr in das Programm involviert, als dass Sie das große Ganze vergessen würden. Dinge im Auge zu behalten würde für ein großes Projekt nicht funktionieren. Legen Sie alles auf Papier (oder in den Computer). Verwenden Sie ein Wiki, um Informationen auszutauschen. In Bezug auf Methoden bevorzuge ich die agile Methodik (Agile ist einfach ein stilvoller Name für inkrementelle Softwareentwicklung). Ich schlage auch vor, jemanden mit Fachkenntnissen auf diesem Gebiet einzustellen, damit er sich um diese kümmert, damit Sie sich auf Ihr Kernprogramm konzentrieren können. Das Fazit ist, dass alle Projektmanagementmethoden nur ein Weg sind, um den Erfolg des Programms sicherzustellen. So können Sie jeden auswählen, der zu Ihnen und Ihrem Team passt, anstatt etwas auszuwählen, das jemand am besten empfiehlt. Die folgende Software kann Ihnen ebenfalls helfen

  • Kostenlose Mind-Mind-Mapping-Software
  • Trac - Schnelles und einfaches Software-Fehlerprogramm und ein Wiki
  • MoinMoin - Schnelles Wiki zum Aktivieren des Wissensaustauschs über das Programm

Obwohl die oben genannten Tipps eine gewisse Lernkurve erfordern würden, lohnt es sich auf lange Sicht. Und schließlich ist das Programmieren einfacher als das Photonic Engineering (wenn auch nicht die C ++ - Programmierung).

Ubermensch
quelle
0

Wie Ihre Frage ist jede Antwort, die für Sie nützlich ist, sehr lang und vage - aber die kurze Antwort lautet "Software Engineering".

Ich schlage vor, dass Sie so viel Freizeit wie möglich frei haben, wenn Sie eine Karriere als Softwareentwickler ernst nehmen, und zunächst die Website von Steve McConnells besuchen . Das Programmieren ist einfach und kann in einem Semester unterrichtet werden. Software Engineering ist um eine Größenordnung komplexer und benötigt viel mehr Zeit zum Lernen.

mattnz
quelle