Softwaredesign in C++ im Vergleich zu Softwaredesign in Java/C#



  • volkard schrieb:

    B4ndit schrieb:

    Das waren die schrecklichsten Monate in meinem IT-Leben die ich hatte. Wenn ein kleiner Ablauf auf zwanzig Klassen verteilt ist, ist das nicht mehr schön.

    Man zerlegt nicht für die Wiederverwendung, sondern um den Überblick zu behalten.

    Sorry, an sich wirkst du ja fitt, aber es ist peinlich, was für einen Schwachsinn du manchmal für bare Münze verkaufst.
    Natürlich ist die Zerlegung eine ganz essentielle Methode, um Wiederverwendung zu erreichen.



  • Die Wiederwendbarkeit fällt aber nur als Abfallprodukt dabei raus.



  • Falsch!
    In C# ist es zum Beispiel üblich, gewisse Klassen aus den einzelnen Schichten einer Software herauszuziehen, um sie dann in einem WCF-Dienst auf beiden Seiten gemeinsam verwenden zu können. Das hat nichts mit Übersicht zu tun sondern man möchte schlicht erreichen, dass Änderungen an Klassen der Domäne sofort auf beiden Seiten der Kommunikation greifen.

    Das ist ein Beispiel von vielen.



  • Schon mal einen WCF-Dienst in C++ gesehen? Was gefaellt dir nicht an der Antwort:

    weil es unterschiedliche Sprachen sind, unterschiedliche Ausdrucksmittel bereitstellen und unterschiedliche Einsatzgebiete haben



  • jaaaanein schrieb:

    softwaredesign schrieb:

    ich habe neulich ein Posting hier gelesen (leider ist mir der Link entfallen...), in dem gesagt wurde, dass sich der Softwareentwurf in C++ von dem in rein objektorientierten Sprachen wie C# (Java (fast rein objektorientiert)) unterscheiden würde. ...

    ...und ich glaube haben die wenigsten von denen haben schon an großen C++ Projekten gearbeitet.

    Reichen dir berufliche Projekterfahrungen von über 10 Jahren in der C++ Entwicklung (plus etwas Erfahrung in den eben genannten anderen beiden Sprachen)?

    In C++ wird tatsächlich anders entwickelt. Es handelt sich um unterschiedliche Sprachen mit unterschiedlichen Möglichkeiten und Paradigmen. Der wesentlichste Unterschied ist das Sprachen wie C# und Java Reflection unterstützen, zudem basieren die grundlegenden Bibliotheken schon auf gänzlich anderen Prinzipien.

    Tiefe Klassenhierarchien sind nach meiner Ansicht aber in jeder Sprache ein Fehldesign (und machen Änderungen extrem schwer*). Komposition ist nicht selten eine bessere Alternative zu Aggregation.

    * Was inzwischen so jeder hier auf die harte Tour gelernt hat... (Wir haben an einer Stelle eine sehr tiefe Hierarchie, durch die Änderungen inzwischen fast unmöglich geworden sind; in Teilen habe ich die tiefe Hierarchie inzwischen durch mehrere flache Hierarchien ausgetauscht um überhaupt Änderungen vornehmen zu können).

    Zudem sind die C++ Templates wesentlich mächtiger als beispielsweise die C# Generics, und auch der fehlende GC wirkt sich auch auf die Art und Weise aus wie man in C++ entwickelt.

    Die Meinung zu IoC teile ich nicht, auch wenn ich glaube das IoC in der Form wie dies in C# und Java möglich ist, nur in bestimmten Grenzen machbar ist (u.a. wegen der fehlenden Reflection). Das heißt aber nicht das IoC gänzlich unmöglich wäre - selbst wenn ich dies in C++ Projekten noch nicht angetroffen habe (liegt vielleicht auch daran das die meisten C++ Projekte an denen ich bislang mitgearbeitet habe, ihren Ursprung im letzten Jahrhundert hatten).



  • softwaredesign schrieb:

    Natürlich ist die Zerlegung eine ganz essentielle Methode, um Wiederverwendung zu erreichen.

    Der gerne genannte Aspekt der Wiederverwendung hat sich in der Praxis als kaum umsetzbar herausgestellt (War ursprünglich einer der gerne genannten Hauptvorteile von OOP, heutzutage sind selbst reine Fachbuchautoren inzwischen teilweise bei der Praxis angelangt...).

    Ich habe nur ganz selten erlebt das man wirklich etwas Wiederverwerten konnte. Der Vorteil von OOP in der Praxis liegt fast ausschließlich in der Schaffung verständlicher kleiner Codeeinheiten. Die Wiederverwendung ist nur in seltenen Fällen gegeben (Da jeder Anwendungsfall in der Regel einen ganz anderen Detaillierungsgrad benötigt).



  • Kann ich nicht nachvollziehen. Ich sorge täglich für Wiederverwendbarkeit in meiner Arbeit.

    Zum Beispiel habe ich vor einigen Monaten eine Klasse geschrieben, welche gewisse Gruppendefinitionen aus einer beliebigen Datenquelle heraus ausliest, die den Gruppen zugewiesenen Entitäten analysiert und nach gewissen Kennzahlen, welche in der Gruppe stecken und hierarchisch verschmolzen werden müssen, modifiziert.

    Diese Erfordernis haben wir auf Basis verschiedener Datenquellen mit verschiedenen Kriterien.

    Was spricht nun dagegen, den Provider für die Datenquelle zu abstrahieren, ebenso das Auslesen und Bewerten der Kennzahlen?
    Diese Abhängigkeiten gebe ich eben der Klasse im Konstruktor mit.

    Und schon kann ich den Algorithmus überall verwenden.
    Sowas mache ich täglich, ist doch nichts besonderes? Welche Fachbuchautoren sollen das denn sein, welche die Wiederverwendbarkeit bezweifeln?



  • softwaredesign schrieb:

    Und schon kann ich den Algorithmus überall verwenden.
    Sowas mache ich täglich, ist doch nichts besonderes? Welche Fachbuchautoren sollen das denn sein, welche die Wiederverwendbarkeit bezweifeln?

    Du darfst dich nochmal melden wenn du diese Komponenten wirklich irgendwo wiederverwendet hast. Kann interessiert keinen.



  • Ja habe ich. Und das mache ich in vielen Bereichen.
    Im Prinzip ist das doch nichts anderes, was auch viele Frameworks tun und auch in einigen Design Patterns beschrieben wird (zB Builder).
    Gemeinsame Schnittmenge von Funktionalitäten identifizieren, Besonderheiten abstrahieren und auslagern.

    Ich verstehe nicht, warum das etwas besonderes ist. Ich kenne das auch aus der täglichen Arbeit meiner Kollegen.



  • softwaredesign schrieb:

    Kann ich nicht nachvollziehen. Ich sorge täglich für Wiederverwendbarkeit in meiner Arbeit.

    Manches lässt sich Wiederverwenden, aber nach meiner Erfahrung ist dies insgesamt der kleinste Teil. Spätestens wenn konkrete Daten ins Spiel kommen, wird dies stark eingeschränkt. Bei typischen Businessanwendungen tendiert die Wiederverwendbarkeit gegen 0 (Heißt nicht das sie 0 beträgt).

    Man kann den Grad der Wiederverwendbarkeit erhöhen, wenn man gleichzeitig die Komplexität erhöht. Um eine Komponente wiederverwendbar zu machen, muss diese in der Regel stärker abstrahiert werden, als es im konkreten Projekt nötig (und häufig auch sinnvoll) ist. Wenn ich absehen kann das ein bestimmter Aspekt wirklich an mehreren Stellen nötig ist, mache ich dies auch - das ist aber nur selten wirklich der Fall.

    Wenn man gleichzeitig auch andere Aspekte wie TDD und IoC berücksichtigt, die ohnehin eine höhere Abstraktion erfordern, ist der Anteil sicherlich höher. Doch ich kenne kaum Projekte die TDD betreiben (ins Besondere bei C++ Projekten; selbst wenn es spätestens bei langlebigen Projekten durchaus sinnvoll wäre), und wo diese Abstraktion nicht die Entwicklungszeit unnötig erhöhen würde.

    In zumindest meiner Praxis hat OOP nur wenig Wiederverwertbarkeit bedeutet. Nur die grundlegenden Bereiche (etwa auf dem Abstraktionsgrad der Standardbibliothek) waren für andere Projekte geeignet.

    Buchautoren nenne ich keine*, ich lese sehr viel und mir ist in den letzten 5 Jahren ein Sinneswandel bei den Aussagen zur Wiederverwendbarkeit aufgefallen. Einst als einer der primären Hauptgründe für OOP dargestellt, wird es inzwischen eher am Rande und mit Einschränkungen präsentiert. Ähnliches gilt für die Meinung im Netz zu selbigen Thema.

    * Dazu ist die von mir konsumierte Buchzahl einfach zu hoch, und der Aufwand zum Suchen der Textpassagen zu aufwendig.



  • Hallo asc,

    danke für dein relativierendes Posting.
    Wir betreiben halt hauptsächlich C# Entwicklung. Da haben wir eine Unit-Test-Abdeckung von 70-80% bei kleineren Projekten (~5000 bis 10.000 LOC) und zwischen 30% und 50% bei größeren Projekten (Prozentzahlen maschinell ermittelt mit Visual Studio Test Coverage Analyzer).
    Der Code ist relativ abstrakt gehalten und hier können wir relativ viel wiederverwenden.

    Ich gebe aber zu, dass es fast immer einen Trade-Off zwischen Wiederverwendbarkeit und einfacher Implementierung gibt. Das ist tatsächlich von Fall zu Fall abzuschätzen.



  • asc schrieb:

    Man kann den Grad der Wiederverwendbarkeit erhöhen, wenn man gleichzeitig die Komplexität erhöht. Um eine Komponente wiederverwendbar zu machen, muss diese in der Regel stärker abstrahiert werden, als es im konkreten Projekt nötig (und häufig auch sinnvoll) ist.

    Du sagst also, dass es im Prinzip gar nicht wirklich notwendig ist, diesem Wiederverwendbarkeits-Stil zu folgen?
    Dass es also nur ein Goodie ist, aber man in der Praxis viel direkter und problembezogener implementiert?



  • Manches lässt sich Wiederverwenden, aber nach meiner Erfahrung ist dies insgesamt der kleinste Teil. Spätestens wenn konkrete Daten ins Spiel kommen, wird dies stark eingeschränkt. Bei typischen Businessanwendungen tendiert die Wiederverwendbarkeit gegen 0 (Heißt nicht das sie 0 beträgt).

    Vor solchen Äußerungen habe ich richtig schiss... 😞

    Ich habe es schon erlebt dass solche Äußerungen zu einem Copy-Paste-Clone-Modify Vorgehensmodell mündete, s.d. der ein und selbe Fehler in X Projekten gefixt werden musste anstatt an einer zentralen Stelle. Nun schwiren halt so einige doppelte Definitionen in der Projektmappe rum...

    Kann man an solchen Projekten wirklich nicht genug abstrahieren bzw. parametrisieren als dass man immer diesen anwendungsspezifischen Code schreiben könnte? 😕



  • Sone schrieb:

    Du sagst also, dass es im Prinzip gar nicht wirklich notwendig ist, diesem Wiederverwendbarkeits-Stil zu folgen?
    Dass es also nur ein Goodie ist, aber man in der Praxis viel direkter und problembezogener implementiert?

    Ich sage das in der Praxis dies in der Regel noch nicht einmal ein "Goodie", sondern ein Hindernis ist. Wenn man nicht gerade aus anderen Gründen (wie TDD/IoC etc.) ohnehin eine hohe Abstraktion hat kostet es mehr als es nützt. Dies bedeutet gleichzeitig das es in der Regel kaum Wiederverwendbarkeit im Praxiseinsatz gibt.

    softwaredesign schrieb:

    danke für dein relativierendes Posting.
    Wir betreiben halt hauptsächlich C# Entwicklung.

    In C# wird eine andere Form der Entwicklung betrieben, dies ist auch der Sprache geschuldet, die am Design ungeachtet aller Theorie doch entscheidenden Einfluss nimmt.

    In C# greift man wesentlich eher zu Unit-Tests, diese wiederum haben massiven Einfluss auf das Design. Gleichzeitig ergänzt sich IoC und Unit-Tests durch die Abstraktion, so das man hier häufig beides findet oder zumindest das Design sich gegenseitig begünstigt.



  • softwaredesign schrieb:

    Falsch!
    In C# ist es zum Beispiel üblich, gewisse Klassen aus den einzelnen Schichten einer Software herauszuziehen, um sie dann in einem WCF-Dienst auf beiden Seiten gemeinsam verwenden zu können. Das hat nichts mit Übersicht zu tun sondern man möchte schlicht erreichen, dass Änderungen an Klassen der Domäne sofort auf beiden Seiten der Kommunikation greifen.

    Das ist ein Beispiel von vielen.

    Hört sich aus ein wenig Abstand so an, als würdest Du normalerweise Gott-Klassen bauen und sie nur ganz selten mal schweren Herzens ein Bißchen zerlegen, weil ein Framework Dich dazu zwingt.



  • Wieviel sich wiederverwerten läßt, hängt auch vom Unternehmen ab. Wenn es tagein tagaus Verwaltungssoftware für Golfclubs trauspustet, läßt sich naturgemäß recht viel wiederverwerten.



  • Bitte ein Bit schrieb:

    Kann man an solchen Projekten wirklich nicht genug abstrahieren bzw. parametrisieren als dass man immer diesen anwendungsspezifischen Code schreiben könnte? 😕

    Die Frage ist: Was ist das Projektziel, und wie sehen die Vorgaben aus. Ich habe kaum Projekte erlebt, in denen zu den Vorgaben Maßnahmen gehörten, die das Abstrahieren begünstigen (wie TDD oder IoC die selbiges gar erfordern) und damit auch die "Kosten" aufgewogen haben.

    Abstraktion kostet aber nicht nur Zeit, sondern erhöht neben gewonnenen Freiheiten auch den Komplexitätsgrad einer Anwendung. Dies macht die Einarbeitung meist aufwendiger und treibt auch die kosten hoch. In einigen Fällen werden die Kosten mit der Zeit aufgefangen und können sogar sinken (gerade in langlebigen Projekten mit mehreren Kunden bei denen sich einzelne Detailabläufe unterscheiden, hier rentieren sich auch Unit-Tests am meisten).

    Daher: Selten, zumindest wenn man möglichst stark auf das Ziel hin arbeiten soll. Selbst bei recht ähnlichen Projekten unterscheidet sich der benötigte Detaillierungsgrad meist erheblich, und die Abstraktion ist gleichzeitig nicht erwünscht.



  • asc schrieb:

    Abstraktion kostet aber nicht nur Zeit, sondern erhöht neben gewonnenen Freiheiten auch den Komplexitätsgrad einer Anwendung.

    Kommt auf die Art der Abstraktion an.

    Eine Anwendung, die ich gesehen habe, unterscheidet plattformabhängigen Code mit #ifdefs (bei 5 supporteten Plattformen) und das jedesmal auf tiefster Ebene im Code. Etwas Abstraktion in Form einer Library hätte hier nicht geschadet.

    Auch in bezug auf Kapselung ist Abstraktion ganz gut. Richtig abstrahiert reicht mir eine Codestelle um sie zu verstehen. Falsch abstrahiert muss ich mir die 200 Includes durchlesen bevor ich weiss, was da überhaupt passiert.

    Das ist ein Unterschied zwischen C#/Java und C++: In C# ist eine tiefe Klassenhierarchie die Krone der Abstraktion (10 Level ist in WPF so der Standard), in C++ ist es eine freistehende Funktion, idealerweise ein Funktions-Template.



  • asc schrieb:

    Abstraktion kostet aber nicht nur Zeit, sondern erhöht neben gewonnenen Freiheiten auch den Komplexitätsgrad einer Anwendung.

    Wenn die Abstraktion die Komplexität erhöht, dann hat man was falsch gemacht. Abstraktion dient dazu, die Komplexität zu reduzieren.

    In der Praxis sehe ich tatsächlich viel schlecht gemachte Abstraktion, die dazu führt, dass man den Code nicht mehr versteht, da er zu komplex ist. Das bedeutet aber nicht, dass man es auch gut machen kann.

    Wenn ich eine relativ komplexe Schnittstelle habe und diese abstrahiere, um sie einfacher bedienbar zu machen, dann reduziert das die Komplexität.



  • volkard schrieb:

    Wieviel sich wiederverwerten läßt, hängt auch vom Unternehmen ab. Wenn es tagein tagaus Verwaltungssoftware für Golfclubs trauspustet, läßt sich naturgemäß recht viel wiederverwerten.

    (Logistikbranche.)

    Wie immer gehst du auf nichts fachlich großartig ein sondern verbreitest recht spöttisch weiterhin irgendwelche Pauschalisierungen. Es scheint, als könntest du aus der eigenen Weltanschauung nur schwer ausbrechen und reagierst dementsprechend spottend oder belächelnd, wenn du mit etwas konfrontiert wirst, was du nicht kennst oder noch nicht verwendet hast...


Anmelden zum Antworten