Gescheit UML nutzen?



  • Hi,

    Bestimmt tritt jetzt einigen die Empörung ins Gesicht, dass ich diese Frage im C++-Forum stelle.

    Aber mir geht es genau darum: Wie kann ich UML nutzbringend einsetzen, um meine C++-Programme/Architekturen chicer zu gestalten? Ich stoße dabei nämlich auf vielerlei Probleme:

    1. Analyseklassendiagramme, wo man also nur die Beziehungen von Klasse A zu B hat, finde ich halbwegs vernünftig und damit kann ich auch was anfangen. Man kann sich überlegen, von wo nach wo man Beziehungen hat und welche Klassen man braucht. Blöd ist natürlich, dass man in C++ eigentlich gar nicht immer alles in Klassen packen sollte, das lässt sich nicht so toll abbilden.

    2. Entwurfsklassendiagramme mit Methoden und Attributen finde ich dann fast schon nutzlos. Ich meine, wenn man größere Projekte planen möchte oder Klassen bastelt, läuft das bei mir immer darauf hinaus, dass ich für die Implementierung später dann doch wieder alles umwerfe.

    Ich meine, man kann ja was vordenken; aber liege ich damit falsch, dass sich oft erst beim Programmieren herausstellt, ob eine Vererbung oder eine Komposition besser ist? Denn wozu soll man sich dann so viel Mühe mit UML machen?

    Meine Frage rührt vom Studium her. Privat nutze ich UML nämlich selten. Aber wie machen das die großen Architekten (ohne irgendwelche zu kennen)? Wissen die einfach durch ihre riesige Erfahrung bereits im Vorfeld bei jeder Klasse, was am Besten ist und macht es daher für die Sinn, alles vorauszuplanen. Schaffen die es dann, wirklich ein Konzept zu bauen, wo man dann lustig programmiert und wirklich alles aufgeht?

    Also ich kann nicht anders als grob vordenken und den Rest einfach coden und dann sehen "ach mist, muss alles umstrukturieren" -_-. Hat jemand Tipps, wie ich mich zielgerichtet verbessern kann außer einfach nur "coden, coden, coden"?

    Irgendwie misssagt mir die Angewohnheit beim Softwaredesign alles komplett mit tausend Diagrammen auszumodellieren, eh man wirklich Mal in die Tasten hauen kann. Wirkt für mich manchmal mehr wie "überplant"...

    Freue mich über hilfreiche Kommentare!

    Ach und ich weiß, dass die Fragestellung sehr offen ist. Wenn ihr das unangebracht findet... keine Ahnung, ich wollt so ein wenig eine Diskussion anregen. Wenn das hier nicht hingehört und ihr ein besseres Unterforum habt, verschiebt den Thread bitte einfach. 🙂



  • Also erstmal besteht UML nicht nur aus Klassendiagrammen. Es gibt da noch solche Sachen wie Use-Cases, Sequenzen, Aktivitäten, Zustände usw.
    Es geht i.d.R. nicht darum, bestehenden C++-Code in irgendwelche Klassendiagramme zu pressen. Das ist meist reichlich sinnfrei. Man benutzt UML eigentlich schon, bevor irgendwelcher Code geschrieben wird. Mit Szenarion und Use-Cases gehts los, dann kann man mal anfangen, eine statische und eine dynamische Analyse zu machen. Wenn man es so rum macht, ist UML eigentlich ganz hilfreich.
    Außerdem: Wenn man es doch benutzt, um den Code in Bilder zu pressen, dann sollte man davon absehen, jedes Attribut und jede Methode in die Klassenboxen zu schreiben halte es einfach und dokumentiere das, was zum Verständnis nötig ist.



  • Hallo,

    Okay, da sind wohl einige Dinge aus meinem OP falsch hervorgegangen.

    Mir ist schon bewusst, dass man zunächst Use-Case-Diagramme bastelt, dann evtl. Aktivitätsdiagramme einbaut und schließlich halt zu den Klassendiagrammen und später evtl. zu Sequenzdiagrammen kommt.

    Mein Problem ist, dass ich basierend auf Klassendiagrammen nachher meistens komplett anderen Code bastele, der ganz andere Klassen implementiert. Und wenn Methoden und Attribute im UML gepflegt sind, schmeiß ich das meistens auch wieder alles um. Mehr noch: Meistens muss ich erstmal Methoden genauer ausprogrammieren, um zu wissen, ob ich irgendwelche Abhängigkeiten habe und es daher sinnvoll ist, die Architektur anders zu gestalten.

    Kurz und gut: Klassendiagramme führen bei mir zu viel Arbeit und viel Hirnschmalz, wobei das letztendlich an dem, was ich programmieren werde, komplett vorbei läuft. Und daraus leitet sich für mich ein Gefühl des Zweifels über die Sinnhaftigkeit solcher Diagramme aus.

    Jetzt frage ich mich zum Einen halt, wo ich mich verbessern kann, damit ich das sinnvoll nutzen kann, oder, inwieweit das überhaupt sinnvoll ist.

    Ich möchte nochmal betonen, dass es mir dabei speziell um Klassendiagramme geht.



  • Meine Erfahrung ist:
    Für die fachliche Analyse und Dokumentation der Abläufe eignen sich UML Diagramme ganz gut. Das schließt das Kompontendesign mit seinen Schnittstellen ein. Unterhalb davon, also auf Klassenebene, ist man besser dran, direkt den Code zu schreiben und dann per Reengineering bei Bedarf wieder Klassendiagramme zu erzeugen.

    Einfacher Benchmark: Messe die Zeit, wie lange es dauert, eine template-Klasse mit allen Methoden und Membern in einem UML Tool zu beschreiben und dann, wie lange es dauert, das im Header zu tippen und dann ins UML Tool zu laden.

    Sollte jemand kommen und Dir weiß machen wollen, dass per MDA (Model driven Architecture) man den Code doch aus den Diagrammen erzeugen kann, frage nach einem konkreten Beleg. Da gibt es nämlich deutlich mehr Behauptungen als Belege. Ich habe es noch NIE so funktioneren gesehen, dass man a) Zeit gespart hat und b) den generierten Code nicht noch manuell bearbeiten musste



  • Deine Probleme sind genau die, die die diversen agilen Entwicklungsprozesse lösen wollen. Beim klassichen Vorgehen nach Art des Wasserfallmodels (...Design...->Codierung->Test...) hängt man entweder krampfhaft an der vom Architekten vorgegebenen Architektur und codiert nur Blödsinn oder das ursprüngliche Design und die Implementierung gehen mit der Zeit immer weiter auseinander, wodurch die Dokumentation auch wieder für den Papierkorb ist.
    Bei agilen Prozessen reduziert man zunächst mal jede Form von zusätzlicher Dokumentation auf ein Minimum (ein paar Skizzen mit Zettel und Stift), denn man geht davon aus, dass sich das Zeug sowieso wieder ändert. Außerdem entwirft und implementiert man immer nur das gerade nötigste. Designer und Programmierer gehen während der gesamten Entwicklungsphase Hand in Hand oder sind noch besser in einer Person vereint. Man arbeitet immer in Iterationen und übeprüft ständig ob das Modell noch sinnvoll ist. Wenn nicht, dann wirds eben geändert. Alter Zettel in den Müll, neuer gemalt.
    Und was sich nicht als Klassendiagramm darstellen lässt wird eben nicht als Klassendiagramm notiert, sondern Sequenzdiagramm oder auch mal einfach ein paar Zeilen Text, wenn einem das hilft. Am meisten und effktivsten dokumentiert man die Implementierung noch mit gut geschriebenen Unit Tests, denn die sind immer aktuell.



  • Eisflamme schrieb:

    Aber wie machen das die großen Architekten (ohne irgendwelche zu kennen)? Wissen die einfach durch ihre riesige Erfahrung bereits im Vorfeld bei jeder Klasse, was am Besten ist und macht es daher für die Sinn, alles vorauszuplanen. Schaffen die es dann, wirklich ein Konzept zu bauen, wo man dann lustig programmiert und wirklich alles aufgeht?

    Nein. Die "großen Architekten" entwerfen große Architekturen. Die gehen nicht so weit ins Detail, dass jede einzelne Klasse, Methode, Relation gleich mit in den Entwurf gezimmert wird.
    Ein kleines Programm mit ~10.000 Zeilen Code braucht noch keine groß vorgeplante Architektur, da reicht ein kleiner Spickzettel oder ein Grobentwurf im Kopf.
    Wenn die Codezeilen in die Millionen gehen, brauchts eine gut durchdachte Architektur, die sagt, wie die einzelen Komponenten der Anwendung(en) zueinander stehen, miteinander kommunizieren usw. Da steht dann aber nicht drin, wie eine einzelne Klasse auszusehen hat. Was in der großen Architektur ein einzeln beschriebenes Element ist, kann durchaus aus hundert(en) Klassen bestehen. Einzelne Elemente der "großen" Architektur können auch wieder von Architekten beschrieben werden - teilweise in mehreren Ebenen.
    Die Architektur auf kleiner und kleinster Ebene nennt sich dann irgendwann Komponenten- und Klassendesign und wird eher vom Entwickler als vom Architekten gemacht - und auch nicht mehr intensiv dokumentiert, weils erstens zu flüchtig ist und zweitens durch den Code schon ausreichend dokumentiert sein sollte.



  • Okay, da sind ja jetzt wirklich Mal einige sehr interessante Dinge angesprochen wurden.

    Also Unit-Tests nutze ich irgendwie privat überhaupt nicht, auch wenn ich davon gehört hab. Ich meine, es ist zwar kein Beweis, wenn mein Programm funktioniert, dass es auch für alle möglichen Eingaben oder so funktioniert, aber mir reicht mein bloßes Testen durchs Ausführen irgendwie. boost bietet auch so eine Testumgebung, hatte ich gesehen, wie wird denn da irgend eine Art von Dokumentation mit eingebunden? Bastelt man die Doku nicht einfach dadurch, dass man vor Methoden oder so /* bla */ macht und dann später irgend ein Tool drüber laufen lässt wie bei JavaDoc oder so?

    Agile Ansätze finde ich gar nicht so ganz dumm. Das wird zum Teil ja auch schon eingesetzt. Aber Nachteile davon gibt es ja auch, oder? Benutzt das jemand von euch in der Firma oder so, habt ihr damit Erfahrungen?

    Und was pumuckl sagt, ist dann ja eher wieder Wasserfallmodell, oder? Ich meine, bei einer riesen Architektur dann in die einzelnen "Unterarchitekturen" zu gehen und darauf basierend irgendwo Mal was auf einer Oberfläche anzuzeigen, wirkt für mich ziemlich schwierig. Welche Diagramme benutzt man dann bei so Riesenarchitekturen eigentlich? Da gibt es doch sicher auch viel Erfahrungsschätze, was "gut durchdacht" eigentlich heißt, oder? Finde ich dazu irgendwelche Onlinetutorials oder auch Bücher?



  • Eisflamme schrieb:

    Und was pumuckl sagt, ist dann ja eher wieder Wasserfallmodell, oder? ... Da gibt es doch sicher auch viel Erfahrungsschätze, was "gut durchdacht" eigentlich heißt, oder? Finde ich dazu irgendwelche Onlinetutorials oder auch Bücher?

    Als Diskussionsbeitrag dazu:

    http://magazin.c-plusplus.net/artikel/Microsoft tech ed 2010 in Berlin - Tag 3 (ScrumSlashUse Cases)

    Der Abschnitt "ARC208 - Architecture in Agile Projects – How to do it right".



  • Du meinst Boost Test, das ich auch verwende. Ich schreibe inzwischen fast alles außer kleiner Prototypen und schnellen Tests testgetrieben, d.h. Test gleichzeitig mit der Implementierung schreiben oder sogar davor. Die Dokumentation, die Unit Tests erzeugen ist der Testcode selber. Man gibt Testfunktionen außergewöhnlich lange und beschreibende Namen nach dem Schema ZuTestendeMethode_ZustandWährendDesTests_ErwartetesVerhalten . Schon daran kann man erkennen, wie sich Klassen verhalten. Im weiteren Testcode sieht man wie Klassen verwendet werden, mit welchen anderen Schnittstellen sie zusammenarbeiten und wie jede einzelne Kleinigkeit funktioniert. Und da der Testcode immer ausgeführt wird und immer funktioniert ist man sich sicher, dass diese Form der Dokumentation 100%ig aktuell ist.
    Die andere Form der Dokumentation über Quellcodekommentare (Das C++ Tool ist hier doxygen) ist auch eine nette Sache, hat aber den Nachteil, dass sie über Kommentare generiert wird, die auch mal falsche Sachen erzählen können.

    Zu den Architekturen in agilen Prozessen. Bei größeren Projekten wird es auch in einem agilen Prozess eine Phase geben, die vor dem regulären Iterationszyklus eine grundlegende Architektur festlegt. Wie schon gesagt, läuft sowas nicht auf Klassenbasis sondern ist viel höher angesiedelt. Änderungen in dieser Architektur sind so grundlegend, dass sie nicht durch einfache Refactorings durchgeführt werden. D.h. dass diese Architektur wohl durchdacht sein muss und sich nicht ändern sollte. Hat sie sich nicht bewert, fängt man lieber von vorne an.


Anmelden zum Antworten