Ich wollte mir kürzlich die Architektur von Softwaresystem (Java Open Source) genauer ansehen. Sobald ich die jeweiligen Software dann als Source Code in Eclipse geöffnet habe, werde ich fast jedesmal von Klassen und Packages erschlagen
Da viel mir ein, es muss doch irgendeinen Plan der Software geben (wie diese gebaut/aufgebaut) ist. Ich hielt also ausschau ob ich irgendwo UML Diagramme (Klassendiagramme wären schon klasse) finden könnte. Leider ohne Erfolg.
Meine Frage nun: Ist es wirklich so, dass die meiste Software ohne Architekturbeschreibung und Dokumentation veröffentlich wird?
JavaDoc ist findest du eigentlich bei jeder Open Source Software. Dinge wie UML Diagramme oder ähnliches sind eher unüblich und durch modener IDEs auch eigentlich nicht mehr nötig.
Ja wobei größere und viel verwendete OSS meist eine recht brauchbare Dokumentation der verschiedenen Aspekte enthält.
Falls du jedoch glaubst mittels Klassendiagrammen die Architektur eines vll. größeren Stück Softwares schnell zu begreifen bist auf dem Holzweg. Klassen sind die feinste Ebene, Architekturbeschreibungen hingegen eine Abstraktion die bestimmte Aspekte in aggregierter Form, also groberen Darstellung präsentiert. Wobei wir bei den Abstraktionen schon wieder beim nächsten Problem sind nämlich das keine einheitliche Sprache existiert. Z.B. das Wort Komponente, das ist in der Bedeutung völlig überladen.
Ein weiteres und das ist das weitaus größte Problem ist die Diskrepanz zwischen Architekturmodell und dem eigentlichen Code (model-code-gap). Die meisten Programmiersprachen bieten nur ungenügende Möglichkeiten um zu beschreiben was denn nun für die Architektur strukturrelevant ist und wie die Abbildung der einzelnen Architekturteile auf den Code aussieht. Derzeit muss man mit Konventionen arbeiten und mittels hässlicher Werkzeuge (wie Visio) die separate Architekturbeschreibung aktuell halten was mit ziemlichen Aufwand verbunden sein kann. Da Dokumentation also oft schnell altert gibt es mittlerweile Ansätze um nach der initialen Modellierung diese Informationen in den Code zu transportieren bzw. den Code damit anzureichern um später die Informationen auszuwerten und ein immer aktuelles Architekturmodell zu generieren. Ein Beispiel was mir dazu einfällt wäre GitHub - structurizr/java: Structurizr for Java.
kommt drauf an was mit Klassendiagrammen gemeint ist,
Bilder mehrerer Klassen mit Pfeilen dazwischen, also wiederum UML, das schafft schon Wissen
jede Klasse einzeln mit JavaDoc oder Kommentaren direkt in der Klasse, das ist sicher Standard, alles andere wäre ja Geheimcode,
aber der Blick darüber, das ist der schwierige
nötig wäre Dokumentation egal welcher Art, auch ein simpler Text über wichtige Klassen und Verbindungen, schon,
in einer komplexeren Software nur mit den Klassen irgendwas zu finden ist ein Heuhaufen, davon bin ich zumindest überzeugt
aber ihr Nichtvorhandensein ist genauso verständlich, umso mehr bei kleinen Projekten einzelner Tüftler,
Zeit fehlt immer und überall, jede Stunde Doku (oder Tests ) ist eine Stunde weniger Features,
und Doku wird leicht über den Haufen geworfen, Code zwar auch, aber begründet, in der Versuchen etwas gelernt, wird dynamisch umgewandelt, alter Test-Vergleich,
wer dagegen Doku nicht mag und dann zig Stunden nervig zusammengebastelter Texte oder gar bunter Diagramme ohne sonstigen Nutzen in den Papierkorb geschoben sieht…
Doku erschwert auch Änderungen, jede Code-Winzigkeit kann lange Doku-Arbeit mit sich bringen, allein die Prüfung ob die vorhandene Doku noch passt, wo überall erwähnt,
Vorteile hat Doku zwar auch (für sich selber), aber das ist ja wie immer der unsichtbare Nutzen
je größer die Projekte mit Teams, Erfolg, Nutzern, desto eher wird sich auch Dokumentation finden,
aber die grundsätzlichen Probleme bleiben, lieber manche Detailebenen auslassen…,
bei Open Source mit eherenamtlichen Tüftlern immer ein Problem,
in kommerziellen Firmen sind dann eben die Rechnungen für Mini-Änderungen und sonstige hohe Entwicklungskosten verständlich
Wie gehen dann die Entwickler von Software ran? Ich meine, sie müssen ja bevor sie anfangen programmieren einmal eine grobe Architektur erstellen? Man wird ja wohl nicht einfach beginnen Klassen zu erstellen?
Nach meiner Recherche gibt es ja auch den Beruf des Softwarearchitekten? Gibt dieser dann nur vor welche Technologien und Sprachen eingesetzt werden oder macht der diesen ersten groben Entwurf?
Wenn du Eclipse verwenden kannst, hast du ja schon ziemlich gewonnen:
Wenn du ein source-Verzeichnis namens de/example/model/core hast, und da eine Datei namens DefaultModel.java drinliegt, dann weißt du, dass sich darin eine Klasse DefaultModel befindet, die zum package de.example.model.core gehört.
STRG+Klick auf eine Klasse, Method und Variable, und er hüpft direkt da hin, wo sie deklariert bzw. definiert wird. WICHTIG: Ein Klick auf den „Pfeil nach links“ oben in der Toolbar, oder „ALT+NachLinks“, und er hüpft wieder da hin zurück, wo man vorher war!
Rechtsklick auf einen Klassennamen, und im Menü „Quick Type Hierarchy“ auswählen (oder STRG+T), und man sieht sofort die Vererbungshierarchie der Klasse.
Rechtsklick auf eine Methode, und im Menü „Quick Type Hierarchy“ auswählen (oder STRG+T), und man sieht sofort die Vererbungsstruktur der Methode
Rechtsklick auf eine Klasse, Methode oder Variable, und im Menü „References->Workspace“ auswählen (oder alternativ STRG+SHIFT+G), und man bekommt alle Referenzen aufgelistet, in einer übersichtlichen, aufklappbaren Baumstruktur, die wiederum durchsucht und editiert werden kann
Rechtsklick auf eine Methode, und im Menü „Open Call Hierarchy“ (oder STRG+ALT+H), und man bekommt einen dynamischen, aufklapparen Baum, mit der Information, WER WO diese Methode aufruft (und die aufrufende Methode, und wiederum deren Aufrufer…)
Und wenn du jetzt denkst „Das ist doch normal“, „Das ist doch selbsverständlich“, oder „Das hilft mir auch nicht weiter“, dann nur der Hinweis: Versuch’ dir mal vorzustellen, wie es ist, sich in ein Projekt mit >10000 Zeilen Code einzuarbeiten, bei dem das alles NICHT gegeben ist (z.B. ein C+±Projekt, mit Visual Studio).
Dass Code üblicherweise nicht kommentiert wird, ist nochmal ein eigenes Problem. Aber wie ThreadPool schon sagte: Die Dokumentation bezieht sich auf verschiedene Ebenen. Der Bereich von Methoden bis hin zu Klassen und Packages ist bei Java mit den JavaDoc-Kommentaren schön abgedeckt. Das Browsen dadurch kann schon einen guten Überblick bringen, FALLS derjenige, der das ganze geschrieben hat, kein ignoranter Id!ot war Wert auf Kommentare gelegt hat ( ).
Für „übergeordnete“, konzeptuelle Dokumentation kann ein Diagramm hilfreich sein, aber das ist selten. „Gute“ Diagramme zu machen ist extrem schwierig. Es nützt nichts, für alle Klassen ein Kästchen zu malen und ein paar Pfeile dazwischen. Die Frage, wie ein Diagramm aussehen muss (damit es „gut“ ist), hängt davon ab, WER damit WEM genau WELCHE Information vermitteln will.
Das perfekte Diagramm läge in jedem Fall zwischen
„So high-Level-abstrakt, dass man keine Informationen daraus ziehen kann“ und
„So detailliert und feingranular, dass es unübersichtlich wird (und man auch gleich den Code lesen könnte)“.
Und ich behaupte: Dazwischen ist meistens kein Platz!
Oder um auf dein Beispiel mit UML zurückzukommen:
Wenn man sich mal das erstbeste Klassendiagramm von Wikipedia ansieht:
Dann stellen sich viele Fragen. Z.B. auch wer dieses Diagramm wann mit welchem Tool erstellt hat. (Wenn du mal in der Realität [SUP]TM[/SUP] mit einem Projekt zu tun hattest, wo dein Vorgänger das tolle Tool „MyDiagramEditor“ verwendet hat, dass es nur auf MacOS gibt, und das 500€ kostet, und für das keine Lizenz mehr existiert, weißt du, was ich meine). Dann die (auch schon angesprochene) Frage, ob es noch dem aktuellen Codestand entspricht. (Die Antwort darauf ist einfach und immer gleich: Nein), oder wer es aktualisiert, wenn sich etwas ändert (und, so offensichtlich es erscheinen mag: Dazu muss derjenige auch wissen, dass dieses Diagramm existiert!)
Die wichtigste Frage ist aber, im oben angedeuteten Sinn: WER soll WELCHE Informationen daraus ziehen?
Mein Gegenvorschlag wäre
interface Konto {
String getBezeichnung();
GeldBetrag getSaldo();
void einzahlen(GeldBetrag betrag);
Kunde getZeichnungsberechtigter();
}
interface Kunde { }
interface Privatkunde extends Kunde {
String getVorname();
String getNachname();
Adresse getPostAdresse();
}
interface Geschäftskunde extends Kunde {
String getFirmenname();
Adresse getDomizilAdresse();
}
Ja. Da stecken alle Informationen drin. Übersichtlich. Verbindlich (das IST echter Quellcode, der compiliert!). Leicht verständlich. (Ob es dem Diagramm entspricht, weiß ich nicht genau, diese „1…*“-Beschriftungen an den Pfeilen werfe ich immer durcheinander - bei einem Kunde vs. List<Kunde> ist mir das noch nie passiert (!)).
Und vor allem: Das ganze ist leicht änderbar! Wenn jetzt zum Konto noch ein String getIBAN() dazukommt, und es noch einen Selbstständiger extends Kunde geben soll, dann habe ich das in diese Zeilen schneller eingefügt, als selbst der größte Diagramm-Experte sein Visio aufgemacht hat…
[quote=Marco13]Das perfekte Diagramm läge in jedem Fall zwischen
„So high-Level-abstrakt, dass man keine Informationen daraus ziehen kann“ und
„So detailliert und feingranular, dass es unübersichtlich wird (und man auch gleich den Code lesen könnte)“.
Und ich behaupte: Dazwischen ist meistens kein Platz![/quote]
für das Dazwischen gibt es Unterkapitel in der Doku mit Details zu bestimmten Bereichen
nur aus Klassen kann man nichts auslesen, die 4 Interface in deinem Beispiel findet man in der Realität nicht in Interface-Form,
und nicht an einer Stelle, sondern zwischen zig anderen aktuell irrelevanten Klassen weit verteilt im Code, also gar nicht
der harte Weg geht auch immer irgendwie,
aber falls schön, bräuchte es separate Doku, ob in Bildern oder Textform (oder Film usw.), das ist übliche Hin und Her in allen Bereichen der Medienwelt,
dass mal jemand Doku in einer Programmiersprache geschrieben hat wäre mir eher neu
(außer eben die halb-automatische geschenkte, JavaDoc, keine Arbeit)
durchaus möglich,
ein echter Architekt malt vielleicht auch erst Designs bevor das Gesamthaus und Hintergrund-Wichtigkeiten wie Statik dazukommt
Nach meiner Recherche gibt es ja auch den Beruf des Softwarearchitekten? Gibt dieser dann nur vor welche Technologien und Sprachen eingesetzt werden oder macht der diesen ersten groben Entwurf?
Software läßt sich im Detail nur selten vorher entwerfen, denke ich,
da gibt es keine Konstanten wie sichtbare Wände, Schwerkraft, alles übereinander gebaut
(paar bekannte Standards sind vorhanden, ja, oben eine GUI, unten eine DB, aber das sind keine besonderen Infos, keine relevanten schöpferischen Anteile,
beim Haus geht man auch von Dach + Keller/ Fundament aus)
andersrum gibt es in Software aber auch nichts einmal gebautes für ewig unter anderen Schichten verstecktes,
was entweder nach Zahlen funktioniert und Leben anvertraut oder nicht,
jeder Baustein ist immer vollständig sichtbar und auch austauschbar, jede Etage von 10 übereinander kann unterschiedlich breit sein,
kein Verschleiß, keine Last
Im meinem Projekten wurde UML auch nur zur Dokumentation der groben Struktur der Software und einiger Ausgewählter zentraler Punkte genutzt. Eben solche Sachen, die sich selten bis gar nicht ändern und die sich graphisch leichter kommunizieren lassen.
Ein vollständiges Klassendiagramm ist illusorisch. Das kann (wie bereits gesagt) nie aktuell sein und darüber hinaus ist es immer unübersichtlich! Mein aktuelles Projekt hat rund 3000 Klassen. Auf was für einer Papiergröße soll man das den drucken, damit man die Schrift noch lesen kann? Und was könnte man dann daraus noch ablesen?
Dann kommt es darauf an, wie sehr man von so einem Diagramm erwartet, dass es „standalone“ ist. Wenn durch das Diagramm ein mentales Modell suggeriert werden soll, das erst durch Text gefüllt werden kann, dann mag das zutreffen. Aber nochmal: Es kommt stark darauf an, WEM dort WAS vermittelt werden soll. Meine Aussage (auf die du dich jetzt beziehst) bezog sich in erster Linie auf Klassen/Strukturdiagramme. Es gibt andere Diagramme, die sehr hilfreich sein können. Im speziellen z.B. Sequenzdiagramm – Wikipedia , denn der zeitliche Ablauf von Prozessen ist etwas, was nur schwer (mit vertretbarem Aufwand) durch Rumbrowsen im Code nachvollzogen werden kann.
Ich denke schon, dass es… erstrebenswert wäre, in irgendeiner Applikation, die (auf das Beispiel bezogen) irgendwas mit Kunden, Konten, Geldbeträgen und Adressen macht, interfaces Kunde, Konto, Geldbetrag und Adresse in einem package zu haben, und nach Möglichkeit auch nur diese Interfaces in dem Package (ggf. noch die Implementierungen dazu), also irgendwas, was kohärent und konsistent zusammengehörige Klassen als solche kenntlich macht.
Natürlich könnte man da jetzt beliebig weiterdenken und philosophieren, ob „Customer“ nicht vielleicht „weiter oben“ hingehört, und die restlichen Klassen in einem Unterpackage wie „…customer.finance“ liegen sollten, neben dem es auch noch „…customer.sales“ usw gibt, aber das sind die Entscheidungen, die nicht auf dieses Minibeispiel anwendbar sind, sondern eher eine Frage der übergeordneten Gesamtarchitektur - was dazu führt:
Ich denke, da wird gelegentlich noch explizit unterschieden zwischen „Software Design“, „Software Architecture“ und „Software Engineering“. Auch wenn ich mir weder die Fähigkeit zur genauen Defitinion dieser Begriffe anmaßen, noch die Diskussion in Richtung einer Ausdifferenzierung dieser Begriffe lenken will, denke ich, dass man auf den Hausbau bezogen (etwas plakativ, vielleicht aber) schon unterscheiden könnte zwischen
Dem Designer, der freigeistig-kreativ geschwungene Linien malt und sagt: „So soll das Haus aussehen“
Dem Architekten, der diesen Entwurf auf Millimeterpapier zeichnet, und sagt, wo die Küche hinkommen und Abflussrohre verlaufen könnten
Dem Bauingenieur, der sagt, welcher Teil aus Alu oder Stahlbeton sein muss, damit das ganze nicht zusammenkracht
Bob, dem Baumeister, der dann am Ende die Drecksarbeit macht
Hausbau und Softwareentwicklung läßt sich in dieser Hinsicht gut vergleichen, weil man zu fast jedem Punkt auf der jeweils anderen Seite irgendein Analogon finden kann (Wenn man mal von solchen Details absieht, wie dass ein Ziel bei Softwareentwicklung z.B. sein könnte, leicht die Datenbankanbindung ändern zu können, während es beim Hausbau selten das Ziel gibt, das Haus auch über einem anderen Keller aufstellen zu können …)
@Marco13 ich finde die Versteifung auf Klassendiagramme nicht so hilfreich wenn nach der Architekturdokumentation gefragt wurde. Sich in Eclipse durch die Klassen zu wühlen wenn man die grundsätzliche Architektur erfassen möchte ist dann ungefähr so wie wenn ich gleich mit einem Mikroskop deine Zellen betrachte und mich erst sehr weit entfernen muss um dich als Mensch wahrzunehmen. Zu Beginn ist es viel nützlicher zu wissen das du Arme, Beine, Oberkörper und einen Kopf besitzt.
[OT][QUOTE=Marco13][…]Die Frage, wie ein Diagramm aussehen muss (damit es “gut” ist), hängt davon ab, WER damit WEM genau WELCHE Information vermitteln will.
Das perfekte Diagramm läge in jedem Fall zwischen
“So high-Level-abstrakt, dass man keine Informationen daraus ziehen kann” und
“So detailliert und feingranular, dass es unübersichtlich wird (und man auch gleich den Code lesen könnte)”.
Und ich behaupte: Dazwischen ist meistens kein Platz! […]
[/QUOTE]
Weshalb sollte es dazwischen keinen Platz geben? Es ist doch ohne weiteres möglich einem Stück Software/System als Diagramm eine Tiefe zu zuschreiben, ich muss nicht alles auf ein Blatt klatschen. D.h. mit jeder weiteren Ebene wird es detaillierter, so kann sich von der groben zur feinen Ansicht vor und zurück gearbeitet werden. Das ist ein natürliches Vorgehen vorallem im Bereich von Datenauswertungswerkzeugen und wird meist als “drill-down” bezeichnet. Das ist also eine Frage des Toolings.
Viel wichtiger ist aber wie beschreibe ich die Abbildung Architektur -> Code um dann später dieses Ding in ebendiesen Ebenen aus dem Code automatisch abzuleiten zu können um immer die aktuelle Architekturdokumentation überprüfen zu können ohne das sich dann eben ein armer Arsch den ganzen Tag hinsetzen muss um den Kram in Visio nachzupflegen. [/OT]
@ThreadPool : Vermutlich hat sich das überschnitten: Ich hatte im letzten post dann schon erwähnt, dass es auch andere Diagramme gibt, und Browsen im Code nicht immer die Lösung ist. Aber ursprünglich war ja ganz konkret nach einem (UML) Klassendiagramm gefragt worden.
Dem Gedanken der Hierarchie kann ich nur voll zustimmen (und den hatte ich ja auch schon in der ersten Antwort aufgegriffen). Wie viel (und welche) Diagramme (orthogonal zu “eklärendem Text”!) dann noch nötig, hilfreich oder praktikabel sind, ist die entscheidende Frage. Aber konkret dafür…
[QUOTE=ThreadPool]
Viel wichtiger ist aber wie beschreibe ich die Abbildung Architektur -> Code um dann später dieses Ding in ebendiesen Ebenen aus dem Code automatisch abzuleiten zu können um immer die aktuelle Architekturdokumentation überprüfen zu können[/QUOTE]
ist mir keine geeignete Lösung bekannt.
sehr erstrebenswert, mir aber noch nicht begegnet, wobei ich freilich nicht viel anschaue
und gleichzeitig wäre das dann auch eine wenig komplexe Vorstellung einer Applikation, die kaum eine Doku braucht,
wichtig wird es bei hunderten Klassen, die alle irgendwie wichtig sind, nicht gleichzeitig, aber irgendwann doch,
da gibt es auch viele Gruppen wie ‚Kunden, Konten, Geldbeträgen und Adressen‘, überlappend,
die können nicht jeweils in eigenen packages sauber darliegen,
besonders nicht wenn es kein Superprogrammierer war oder später gezielt optimal aufgeräumt wurde, also im Normalfall
Mein damaliger Ausbilder beim Unternehmen meinte “Jeder Entwickler der behauptet er könnte ohne Flußdiagramme arbeiten, lügt!”, vielleicht hatte er auch irgendwen anderes zitiert, ist ein bisschen her.
Damals konnte ich noch alles im Kopf aber wenn man älter wird, wird es schwerer, genauso wie Memory. Seitdem folge ich dem alten Rat und mache zu jedem Code der geschrieben oder implementiert wird Diagramme und es ist einfach um ein tausendfaches einfacher und übersichtlicher. Wie ein Stadtplan.
Zumindest bei der Planung ist das von der Bedeutung um sich zu orientieren, Ressourcen zu verteilen, schnell Projekte zu wechseln.
Nur eine Software lebt, häufg trifft man auf Bugs und Problme oder falsche Designentscheidungen die die Anforderungen nicht erfüllen könnten. Dann muss das Projekt weiter geschrieben werden, ummodelliert, immer wieder Sicherheitslücken geschlossen werden und am Ende wird alles optimiert und “optimieren” bedeutet den ganzen schönen OOP Java Code den man geschrieben hat zu etwas unleserlichem magischen Code zu machen den keiner versteht aber funktioniert.
Die Diagramme die ganze Projektzeit über auf dem laufenden zu halten ist eher weniger eine Option auch wenn es zumindest bis vor der Optimierungsphase sinnvoll wäre aber Faulheit, Zeit und Geld haben dann doch die Oberhand und meistens reichen die anfänglichen Diagramme noch aus um zumindest die Grundstruktur zu verstehen.
ich bin kein Freund des klassischen UMLs, wie man es in der Uni oder in der Ausbildung lernt (jdf zu meinen Zeiten). Sie versteifen sich zu sehr auf Details und lassen den Sinn, Zusammenhang des gesamten verschleiert.
Ein Klassendiagramm hilft nicht beim Verstehen einer Architektur, es ist umständlich und platzverschwendend.
In einem Architekturdokument sollte man auf eine mehr abstrakten Ebene das System modellieren und nicht Detailimplementierungen niederschreiben. Die Problematik die damit kommt wurde hier schon geschrieben.
Wie gesagt, ich bin und werde nie Freund des Klassendiagramms. Behavior oder Interaction Diagramme können im Einzelfall hilfreich sein (nicht für die Architektur).
Keine Ahnung obs nur ich bin, aber mir stand jedes Klassendiagramm komplett entgegen agiler Entwicklung und v.a. TDD.
[quote=bygones]Keine Ahnung obs nur ich bin, aber mir stand jedes Klassendiagramm komplett entgegen agiler Entwicklung und v.a. TDD.[/quote]Vor allen führt dass schnell zu “mighty classes” weil man ja das Diagramm ändern müsste, wenn man Funktionalität in eine eigene Klasse auslagerte…