Komplexität

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Antworten
dronus
Establishment
Beiträge: 114
Registriert: 11.01.2010, 01:53

Komplexität

Beitrag von dronus »

Was haltet ihr von Komplexität?

Ich glaub das Reduzierung von Komplexität eine dringende Sache ist, die man sehr vielen Dingen vorzuziehen kann. Ist hier vielleicht etwas fehl am Platz, weil ihr vermutlich dem Problem sowieso mehr Aufmerksamkeit schenkt als in anderern Sparten, aber ich programmiere Querbeet (3d Engine bis Onlineshops :shock: ) und habe den Eindruck dass ich dafür mal Werbung machen muss. Was ich so beobachte:

* Irgendein Konzept wird ausgerufen, und massenhaft Leute die davon gelesen haben machen Software damit, die ohne das "Wissen" mit einem Bruchteil des Codes auskommen würde. Die Pattern dienen immerhin der "Flexibilität", "Modularität", "Testbarkeit" oder "Zusammenarbeit" und dazu werden sie teilweise sicher auch nützlich sein (MVC, IoC, abstrakte Factorys, Kapselung etc.).

* Programme die schon im Markt sind bekommen mit jeder Version ein paar Funktionen dazu. Entfernt wird fast nie eine, dass würde ja auffallen und jemand vermisst sie. Irgendwann ist das Programm so vollgeballert das jeder Benutzer latent genervt ist, und er freut sich über ein neues, geiles, schnelles eines anderen Herstellers. Er merkt kaum oder garnicht dass ein Haufen bekannter Funktionen jetzt weg ist.

* Wenn man bemerkt dass man mehrere ähnliche Vorgänge im Code hat, abstrahiert man oft und schafft ein gemeinsames Stück Code dafür. Das Gefühl dabei ist meist sehr gut.. Wenn einige der Vorgänge später unnütz werden, führt das aber meist nicht dazu, dass auch das gemeinsame Stück Code wieder zerlegt und spezialisiert wird.

* Das Beherrschen von Komplexität gibt natürlich ein geiles Gefühl...

So entsteht Komplexität in fantastischen Ausmaßen. Mein Problem damit: Wird es zu komplex dann verstehe ich nicht mehr was genau passiert. Jede Zeile die ich schreibe, bringt mich dann der Lösung nur noch wahrscheinlich näher. Ich muss das laufende Programm testen, und dies als Messlatte für meine Änderungen verwenden. Wenn die Zeile in ihrer Umgebung plausibel klingt, aber trotzdem nicht tut was man hoffte, will man den Code "nicht erwartungskonform" nennen. Damit behauptet man aber, dass Teile des Codes normalerweise brauchbar dokumentieren, wo und wie sie im Gesamten wirken. Das ist zwar wünschenswert, aber immer grob möglich. Eine Funktion kann man nennen wie man will, was wirklich raus kommt bestimmt immer noch der Computer. Ich habe große Probleme damit, eine Codezeile zu schreiben ohne im Kopf Klarheit darüber zu haben, was durch diese Änderung geschieht.

Was denkt ihr?
Benutzeravatar
Krishty
Establishment
Beiträge: 8265
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Komplexität

Beitrag von Krishty »

Ich kann zwar auf keinen Fall behaupten, dass mri solche Probleme fremd wären, aber das war mich nie mehr als eine Randerscheinung (Motivation ist mein Nemesis):

Ich habe Code noch nie nach bestimmten Patterns entwickelt (alles, was ich je darber gelernt habe, war nach der nöchsten Prüfung wieder vergessen und meist erfahre ich erst hinterher, dass es mehr oder midner zufällig ein Pattern gibt, was beschreibt, was mein Code macht) und ich würde wirklcih niemals darauf kommen, ein bestimmtes Pattern als ANforderung für ein Programm zu spezifiziern.

Wenn mein Programm dann funktioneirt, refactore (wie heißt das Werb? Lingualimperialismus ftw!) ich üblicherweise nochmal alles, entferne alle überflüssigen Komponenten und feile es auf minimalen Umfang bei maximaler Dokumentation runter.

Dann wäre da noch das Zauberwort Abstraktion: Ich muss nicht wissen, wie die FUnktionen/Interfaces intern arbeiten, die ich aufrufe. Damit bleibt die Komplexität über die Entwicklungzeit eines Programms immer etwa gleich groß, nämloich genau gleich der Kompelxität der Funktion/Klasse, an der man gerade arbeitet. Ist natürlcih ein bisschen überspitzt, aber darauf läuft es dann doch hinaus. Ich fionde immer in ein, zwei Stunden den Einstieg in uralte Baustellen, acuh, wenn ich da Monate nicht dran war. Ob ich dann dem Code noch arbeoten will oder alles refactore übera4rbeite weil ich nichts mehr hasse als meine Programmeirstil von letztem Jahr, ist eine andere Sache.
Eine Funktion kann man nennen wie man will, was wirklich raus kommt bestimmt immer noch der Computer.
Genau das sehe ich als dein Problem … ich schriebe keine Funktion, keine Variable, ja wirklich GARNICHTS hin bevor ich mir nicht einen NAmen überlegt habe, der das auf präziseste ARt und Weise beschreibt.

Naja, meine Art zu programmieren ist zwar unkonventiell und unberechenbar und so weiter, aber das ist eben meine MEinung, und die wolltes tdu ja hören ;)

Btw, bist du so ein pattern-und-Spezifikation-auswähl-und-nach-exaktem-Plan-losprogrammier…er? Ich kenen das von der Uni, das sind auch immer alles Java-Entwickler. Konnte ich mich erhrlich gesagt nie mit anfreunden.

Achja, Metaprogrammierung kann acuh eine enorme Vereinfachung des Programms bedeuten, zm Preis einer ebenso enormen Komplexitötssteigerung der Syntax: Z.B. wenn man durch Templates den Wertebereich udn die Dimension jeder Variable seines Programms durchrechenen und bestätigen lässt. IN YOUR FACE, JAVA! ;)

P.S: Nichts für uNgut mit Java und so. Hast ja eingies Vollbracht, sehe ich im Vrostellungsbereich und so.
Gruß, Ky
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Komplexität

Beitrag von kimmi »

Gegen die ausufernde Komplexität haben sich einige bewährt bewährt. Gerade in Bezug auf Lesbarkeit, Komplexität und Funktionsumfang hat Krishty ja schon einiges sehr Richtiges gesagt. Eine ganz gute Zusammenfassung zu dem Themenbereich findet man auch hier:
http://www.clean-code-developer.de/

Im Allgemeinen kann ich dem Trend hin zu immer komplexeren Programmpaketen / Frameworks ebenfalls bestätigen. Und es gibt auch Gegenströmungen wie zum Beispiel die Firma Apple, die dem Wildwuchs von vorn herein versucht zu bändigen ( Gegenteil war bis Windows 7 mal MS ). Ich versuche mittlerweile, nachdem ich auch schon oft in die "Mein Framework soll alles können"-Falle getappt bin, einfach nur das einzubauen, was der Benutzer gerade als Minimum braucht. Das allein herauszukriegen, ist aber relativ schwer.
Muß ich dabei an Legacy-Code ran, versuche ich, den etwas aufzupolieren, um ihn qualitativ zu verbessern. Und dann zwinge ich mich, damit aufzuhören. Weil auch im Refactoring kann man sich verrennen.
Und der beste Test gegen zu komplexe Programme ist immer noch der Benutzer: Ist er mit meiner Oberfläche überfordert? Wenn ja, habe ich Mist gebaut und muß zurück an den Werktisch, daran herumfeilen, bis es was taugt :).

Gruß Kimmi
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4262
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Komplexität

Beitrag von Chromanoid »

mmh ich glaube man muss sich einfach damit abfinden, dass es in größeren software projekten einfach schnell so komplex wird, dass man sich immer nur einen teil des ganzen vornehmen kann. genauso wie bei großen fabriken kennt man dann eben normalerweise nicht jede maschine/funktion. daher ist dokumentation, spezifikation und einheitlicher stil so wichtig. aus solchen gründen liebe ich die "natürliche" paketstruktur von java, c# usw. die organisation des quelltextes ist so wesentlich leichter und selbst wenn verschiedene leute ähnliche funktionalitäten programmieren und man davon erst mal nichts mitbekommt, kann man das zeug hinter her in einem höhergelegenen paket zusammenschmelzen, generalisierungen bilden usw.
wegen steigender komplexität der programme ist es eben auch sinnvoll mit unit-tests zu arbeiten, test-management-software einzusetzen, einen bug tracker zu benutzen, peer reviews zu betreiben, versionsverwaltungssoftware einzusetzen usw.
dronus hat geschrieben:Programme die schon im Markt sind bekommen mit jeder Version ein paar Funktionen dazu. Entfernt wird fast nie eine, dass würde ja auffallen und jemand vermisst sie. Irgendwann ist das Programm so vollgeballert das jeder Benutzer latent genervt ist, und er freut sich über ein neues, geiles, schnelles eines anderen Herstellers. Er merkt kaum oder garnicht dass ein Haufen bekannter Funktionen jetzt weg ist.
das würde ich nicht unterschreiben. es gibt viele programme die eigentlich einfach nur von version zu version wachsen und trotzdem marktführer sind: z.B: MS Office, Adobe Photoshop, MS Windows... Sicher gibt es zwischendrin immer wieder Ableger u.Ä. für spezielle Zielgruppen, aber für die war das Urprogramm dann meistens auch schon nicht gedacht...
dronus
Establishment
Beiträge: 114
Registriert: 11.01.2010, 01:53

Re: Komplexität

Beitrag von dronus »

Krishty hat geschrieben:
Eine Funktion kann man nennen wie man will, was wirklich raus kommt bestimmt immer noch der Computer.
Genau das sehe ich als dein Problem … ich schriebe keine Funktion, keine Variable, ja wirklich GARNICHTS hin bevor ich mir nicht einen NAmen überlegt habe, der das auf präziseste ARt und Weise beschreibt.
Genau da hakts ja leider..
ich müsste funktionen "loadTexturePixelsAndResizePixelsBilinearIfATIGPUTurnsOutNonPowerOfTwoSupporting" oder "getBitmapSizeAndMaybeFreezeForSomeSecondsIfStaticStructureIsNotInitialized" nennen :-(

Jede nicht völlig primitive Funktion kommt ja in der Regel mit einem Berg an Seiteneffekten daher, selbst wenn es nur ihr Speicherbedarf und ihre Laufzeit ist, in Spielen auch nicht unwichtig...

Krishty hat geschrieben: Btw, bist du so ein pattern-und-Spezifikation-auswähl-und-nach-exaktem-Plan-losprogrammier…er? Ich kenen das von der Uni, das sind auch immer alles Java-Entwickler. Konnte ich mich erhrlich gesagt nie mit anfreunden.
Nein, ganz im Gegenteil. Es ist eher andersherum, wenn ich Leuten zeige wie ich etwas geschickt finde, sagen die manchmal "Achso, MVC..", danach wusste ich wie man nennt was ich gemacht hab. Darum geht es mir ja grad in diesem Thread, dass man davon loskommt...

Chromanoid hat geschrieben:wegen steigender komplexität der programme ist es eben auch sinnvoll mit unit-tests zu arbeiten, test-management-software einzusetzen, einen bug tracker zu benutzen, peer reviews zu betreiben, versionsverwaltungssoftware einzusetzen usw.
Das sehe ich genauso.
Bloß leider baut man dann Frameworks, die besonders gut für Unit-Tests sind... und so muss der Coder muss viele Dinge in einer komplexeren Art machen, damit später ein Unit-Test funktioniert. Beispiel IoC, das wird besonders damit beworben dass man einfach Testen kann (mit Mockups und so).
Wenn man aber beschreiben will, was in einer IoC Anwendung so passieren kann, kommt zu der Sprachreferenz und API Referenz der verwendeten Sprachen auch noch Semantik des Frameworks und Konfigurationssprachen dazu... und das Gehirn explodiert. Selbst Kuschelteddy-IDEs kapitulieren dann schnell... einen Haufen Java-Sourcecode kann man mit Eclipse brutal umbauen lassen, aber wenn erstmal XML Files Konfiguration Javascript Matsch dazuwischenklebt geht garnichts mehr.

Frameworks sind oft geil, weil man mit wenigen Codezeilen eine Demo-Applikation hinzaubert. Wenn man aber selber tausende Codezeilen schreibt, finde ich sollte man lieber selber der Herr im Haus sein. Ich möchte dann lieber eine API, die mir ihre Dienste anbietet, als ein Framework, bei dem ich meine tausende Codezeilen immer vor dem Hintergrund eines Framework-Konzeptes, Stils, und evtl. sogar Einschränkungen schreiben muss. Bei den meine Klassen oder Callbacks irgendwo im Codedschungel instanziiert und aufgerufen werden, ohne dass ich beim Coden genau weiss ob das Wetter dort heiss oder kalt, nass oder trocken ist.

Solange ein "Modul" (was auch immer das ist) genau tut was man erwartet, und das genau das ist was ich brauche, frage ich auch nicht nach seinem Inhalt.
Das Modul was ich in wenigen Zeilen einbinden und verwenden kann ziehe ich natürlich einem anderen vor, bei dem ich für die selbe Funktion noch einigen Code ergänzen muss, weil es nicht so viel kann.
Tut es aber nicht was ich erwarte, was dann? Dann bin ich plötzlich froh, wenn das "Modul" wenig kann, und ich deshalb zehn Codezeilen selbst schreiben musste, dafür im Modul Hundert statt Tausend Codezeilen vorfinde.

Ich muss zugeben dass noch nicht an Großprojekten gleichberechtigt mitgearbeitet habe. Ich hab aber das Gefühl das eine Codemengenreduktion um den Faktor 2 ein derartigen Verständnisschub bringt, dass man sich eine Menge kooperative Zusammenarbeit dafür aufbürden kann. Wenn dann ein Modul nicht ganz so generisch wie notwendig ist, muss eben dessen Entwickler angepiekt werden. Und Faktor 2 ist absolut lächerlich. Ich hab hier grad den Sourcecode von Magento, einem Onlineshop, dessen Funktionsumfang man sich in ein paar Tagen durcharbeiten kann. Wenn ich alle 3rdParty-Frameworks die benutzt werden weglasse, bleiben 15.962.158 vom Hersteller getippte Zeichen über. Dass kann doch nicht gesund sein...
Benutzeravatar
Lord Delvin
Establishment
Beiträge: 581
Registriert: 05.07.2003, 11:17

Re: Komplexität

Beitrag von Lord Delvin »

Eigentlich hab ich wenig Lust was zu dem Thema zu sagen(man kämpft ja im Prinzip gegen das Halteproblem und da wird man immer an irgendwelche Grenzen stoßen, wobeis momentan eher das eigene Gedächtnis ist), aber weils vielleicht den ein oder anderen weiter bringt:

Ich hab die Erfarung gemacht, dass man seinen Code wesentlich übersichtlicher macht, wenn man Methodenverträge verwendet, also im Simpelsten Fall pre und post conditions. Am besten aber noch mit irgendwas, das eine aussage über die verwendeten und vor allem veränderten Variablen aussagt.

Dann muss man sich bei jeder Funktion nämlich nurnoch den Kontrakt ansehen und weis, was sie macht:)

Nur schade, dass es keine (mir bekannte verbreitete) Sprache gibt, die das nativ fordert. So in etwa wie Java + JML und man bekommt ne warning, wenn irgendwas keinen JML Ausdruck vorne dran hat.
XML/JSON/EMF in schnell: OGSS
Keine Lust mehr auf C++? Versuche Tyr: Get & Get started
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4262
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Komplexität

Beitrag von Chromanoid »

dronus hat geschrieben:ich müsste funktionen "loadTexturePixelsAndResizePixelsBilinear" oder "getBitmapSizeAndMaybeFreezeForSomeSecondsIfStaticStructureIsNotInitialized" nennen :-(
fände ich jetzt´nicht so schlimm :) besser langer name als unverständnis. Schließlich benutzt man eine IDE die einem dann die jew. Funktionsnamen in einer ansehnlichen Weise mit Dokumentation dazu präsentiert ^^. Warum nennst du die Funktion nicht so und packst nen (java)doc drüber? Eclipse und Netbeans zeigen doch JavaDoc im Code Completion Fenster an...:
/**
* ATI GPU -> turns out non power of two supporting
*/
loadTexturePixelsAndResizePixelsBilinear()...
dronus hat geschrieben:Frameworks sind oft geil, weil man mit wenigen Codezeilen eine Demo-Applikation hinzaubert. Wenn man aber selber tausende Codezeilen schreibt, finde ich sollte man lieber selber der Herr im Haus sein. Ich möchte dann lieber eine API, die mir ihre Dienste anbietet, als ein Framework, bei dem ich meine tausende Codezeilen immer vor dem Hintergrund eines Framework-Konzeptes, Stils, und evtl. sogar Einschränkungen schreiben muss. Bei den meine Klassen oder Callbacks irgendwo im Codedschungel instanziiert und aufgerufen werden, ohne dass ich beim Coden genau weiss ob das Wetter dort heiss oder kalt, nass oder trocken ist.
mmh also ich finde es besser mit einer großen etablierten Plattform, wie der Netbeans-, Eclipse-, JavaEE- etc. Plattform zu arbeiten, als mich in irgendein selbst ausgedachtes Zeug von ein paar Leuten, die auch nocht unter Zeitdruck standen, einzuarbeiten.
Das Problem bei langfristiger Softwareentwicklung ist ja nicht das Neuschreiben, sondern das Weiterentwickeln. Und genau so eine Vorliebe, wie du sie beschreibst, wird dann zum Problem:
Man richtet sich zwar gerne nach den eigenen Ideen und Ansätzen, aber wenn man sich dann in uralte ungepflegte undokumentierte Software-Architekturen einarbeiten muss, dann wünscht man sich schnell ein gutes fest definiertes Rahmenwerk her. Auch eigene intern entwickelte Frameworks kommen selten an die Durchdachtheit und Gepflegtheit eines großen professionellen Frameworks ran. Manchmal hat man Glück und das intern entwickelte Framework ist konsistent und von hoher Qualität, aber noch lieber hätte man doch, wenn man auf ein Framework trifft, das man schon aus anderen Projekten kennt.
Der Einsatz vorgefertigter Frameworks macht natürlich nur Sinn, wenn eine vorherige Evaluation ergeben hat, dass es die beste Option ist. Und ich glaube, dass bei generellen Frameworks für allgemeine Desktop-/Web-Anwendungen eigentlich in jeder Sprache gute Frameworks existieren...
dronus hat geschrieben:Wenn man aber beschreiben will, was in einer IoC Anwendung so passieren kann, kommt zu der Sprachreferenz und API Referenz der verwendeten Sprachen auch noch Semantik des Frameworks und Konfigurationssprachen dazu... und das Gehirn explodiert. Selbst Kuschelteddy-IDEs kapitulieren dann schnell... einen Haufen Java-Sourcecode kann man mit Eclipse brutal umbauen lassen, aber wenn erstmal XML Files Konfiguration Javascript Matsch dazuwischenklebt geht garnichts mehr.
Naja XML-Files sollte man eben am besten mit XML Schemas organisieren und das Einlesen mit generierten Klassen erledigen lassen. Für das Sprachmischmasch und so gibt es ja dann auch noch Standards wie JSON usw. :)
dronus hat geschrieben:Solange ein "Modul" (was auch immer das ist) genau tut was man erwartet, und das genau das ist was ich brauche, frage ich auch nicht nach seinem Inhalt.
Das Modul was ich in wenigen Zeilen einbinden und verwenden kann ziehe ich natürlich einem anderen vor, bei dem ich für die selbe Funktion noch einigen Code ergänzen muss, weil es nicht so viel kann.
Tut es aber nicht was ich erwarte, was dann? Dann bin ich plötzlich froh, wenn das "Modul" wenig kann, und ich deshalb zehn Codezeilen selbst schreiben musste, dafür im Modul Hundert statt Tausend Codezeilen vorfinde.
<EDIT>Für sowas gibt es ja meistens Schnittstellen und unterschiedlich ausgebaute vorgefertigte Modul-Klassen... hab erst jetzt gecheckt was du meinst... :) ja da muss man immer abwägen ^^</EDIT>
dronus hat geschrieben:Wenn ich alle 3rdParty-Frameworks die benutzt werden weglasse, bleiben 15.962.158 vom Hersteller getippte Zeichen über. Dass kann doch nicht gesund sein...
Hätte man sich von Anfang an auf ein gutes Web-Framework geeinigt usw. wäre das sicherlich weniger. Aber bei historisch gewachsenen Systemen, die schon lange existieren, ist das leider meistens nicht der Fall (mag auch daran liegen, dass gute standards erst mit der zeit entstehen).

Ich verstehe schon wenn man sich nicht gerne in die engen Reitstiefel eines Frameworks zwängen lassen möchte, aber dafür ist (bei einem guten Framework) langfristig saubere Entwicklung gewährleistet...

Naja soweit meine Meinung :).

PS: Wenn du viel so wichtige Hinweise wie das mit der ATI GPU im Code hast, könntest du dir ggf. ein eigenes JavaDoc-Tag erstellen, das dann vielleicht aus

Code: Alles auswählen

/**
* @attention ATI GPU -> turns out non power of two supporting
*/
loadTexturePixelsAndResizePixelsBilinear()...
folgendes im Code Completion Fenster/JavaDoc macht:
loadTexturePixelsAndResizePixelsBilinear()
ATTENTION!: ATI GPU -> turns out non power of two supporting
dronus
Establishment
Beiträge: 114
Registriert: 11.01.2010, 01:53

Re: Komplexität

Beitrag von dronus »

Lord Delvin hat geschrieben: Dann muss man sich bei jeder Funktion nämlich nurnoch den Kontrakt ansehen und weis, was sie macht:)
Bestimmt manchmal mehr Beschreibung als der Funktionskörper selber :-)
Lord Delvin hat geschrieben: Nur schade, dass es keine (mir bekannte verbreitete) Sprache gibt, die das nativ fordert. So in etwa wie Java + JML und man bekommt ne warning, wenn irgendwas keinen JML Ausdruck vorne dran hat.
Ja.. nur hindert niemand mich daran (natürlich unabsichtlich...) sich drinnen daran zu halten, was Name + Beschreibung behaupten.


Da fällt mir ein simples Beispiel ein, angenommen ich hab zwei Klassen Objekt1 und Objekt2, der Code beider liegt in meiner Hand. Jetzt eine Zeile:

Code: Alles auswählen

objekt1.wert=objekt2.wert;
vs.

Code: Alles auswählen

objekt1.setWert(objekt2.getWert());
Schon hier finde ich es extrem schwer zu entscheiden, womit ich besser daran bin.
Klar ist: Sollte irgendwann objekt2 gar kein Feld 'wert' mehr haben, aber etwas anderes woraus wert zu berechnen ist, wäre ich mit der get-Methode gut bedient gewesen. Anderseits kann ich sie, sofern aller Code meiner ist, mit Refactoring relativ "mechanisch" nachrüsten (evtl. sogar automatisch). Dasselbe gilt für die set-Methode, wenn es später einmal zu aktualisierenden Zustand in Objekt1 gibt.
Doch jetzt kommt der Haken: getWert() kann weit mehr, als nur den Wert zurückgeben. In einem der harmlosesten Fälle lazy evaluation:

Code: Alles auswählen

class Objekt2{
  Wert meinWert=null;
  public Wert getWert(){
     if (meinWert==null) meinWert=new Wert(this);
     return meinWert;
  }
} 
Ab diesem Moment habe ich ein Feld meinWert, dass als Seiteneffekt der Auswertung von get bestückt ist. Außerdem eventuell hohe Speicherreservierung und Laufzeit beim ersten Aufruf von getWert(). Vielleicht schmeisst new Wert eine Exception... Ich muss also beim Aufruf von

Code: Alles auswählen

objekt1.setWert(objekt2.getWert());
mit eriner Menge Effekte rechnen, wogegen ich

Code: Alles auswählen

objekt1.wert=objekt2.wert;
ansehen kann das fast nichts passiert.

C# Properties sind in dem Zusammenhang interessant, sie machen das Refactoring unnötig wenn man doch getter/setter braucht, aber überladen '=' zu einer komplexen Blackbox-Operation. Als ich ich Properties sah fand ich die Idee erstmal super, aber nach diesem Überlegungen würde ich sie nicht benutzen.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4262
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Komplexität

Beitrag von Chromanoid »

dronus hat geschrieben:C# Properties sind in dem Zusammenhang interessant, sie machen das Refactoring unnötig wenn man doch getter/setter braucht, aber überladen '=' zu einer komplexen Blackbox-Operation. Als ich ich Properties sah fand ich die Idee erstmal super, aber nach diesem Überlegungen würde ich sie nicht benutzen.
Sehe ich genauso. Beim expliziten Aufruf von Gettern und Settern weiß man wenigstens, dass da mehr hinterstecken kann. Natürlich kann man auch Properties entsprechend dokumentieren, aber ich finde als Programmierer denkt man da zu schnell einfach nur an Zuweisungen allein schon aus mathematischer Gewöhnung heraus.
Benutzeravatar
Krishty
Establishment
Beiträge: 8265
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Komplexität

Beitrag von Krishty »

Uff, eigentlich wollte ich garnicht in den Thread einsteigen und jetzt habe ich zuwenig Zeit, alles zu lesen. Darum sorry, falls ich was Redundantes schreibe.
dronus hat geschrieben:Genau da hakts ja leider..
ich müsste funktionen "loadTexturePixelsAndResizePixelsBilinearIfATIGPUTurnsOutNonPowerOfTwoSupporting" oder "getBitmapSizeAndMaybeFreezeForSomeSecondsIfStaticStructureIsNotInitialized" nennen :-(
Die Erste hieße vielleicht besser ProvideTexels_ComeWhatMay() ;) Zum Zweiten: 99 % der statischen Strukturen kann man bei der Konstruktion des Programms initialisieren … ein so komplexes Dateisystem, dass das Laden der Ausmaße einer beliebigen Bitmap Sekunden dauert, kann ich mir gar nicht vorstellen ó.Ô
dronus hat geschrieben:Jede nicht völlig primitive Funktion kommt ja in der Regel mit einem Berg an Seiteneffekten daher, selbst wenn es nur ihr Speicherbedarf und ihre Laufzeit ist, in Spielen auch nicht unwichtig...
Teile und Herrsche bedeutet doch, es so lange runterzubrechen, bis möglichst alles völlig primitiv ist (momentan sind bei mir z.B. 3/4 der Funktionen mit dem Tag „Trivial.“ vermerkt). Natürlich kannst du komplexe Berechnungen z.B. zu Populationsentwicklungen nicht auf ein paar Zeilen zusammenkürzen, klar – aber die reinen Berechnungen dazu haben üblicherweise keine SeiteneffekteWirkungen. Entscheidungen aufgrund dieser Berechnungen müssen davon unbedingt getrennt in anderen Funktionen getroffen werden, und diese lassen sich normalerweise sehr gut aufbrechen.

Im Beispiel oben würde ich auch sagen, dass das Laden der Texel in eine komplett andere Ebene der Programmhierarchie gehört als das Stretchen auf Po2-Ausmaße … wenn sich der Datei-Loader damit beschäftigen muss, was für Fähigkeiten die verbaute Grafikkarte hat (anstatt einfach nur ein Rohbild an den Renderer weiterzugeben, der es sich zurecht legt, falls er das muss), dann sind da Abstraktion und Kapselung grundsätzlich verletzt und dass die Funktionen wuchern, ist zu erwarten. Was soll der Loader denn noch alles machen? Bildschirmauflösung und Leveldesign analysieren, um zu berechnen, ob die Textur überhaupt jemals in der Auflösung sichtbar ist, in der sie auf der Platte vorliegt, und sie bei Bedarf verkleinern?

In Verbindung hiermit
dronus hat geschrieben:Doch jetzt kommt der Haken: getWert() kann weit mehr, als nur den Wert zurückgeben.
wollte ich schon immer mal fragen: Hat Java eigentlich kein Äquivalent zur const-Correctness? (final-Correctness?) Die ist in C++ zwar keine Garantie, aber immerhin ein Hinweis, dass eine Funktion keine Wirkungen auf die Parameter oder ihr Objekt hat und zwingt einen nebenbei in strenge Kapselung. Auf der Liste unterschätzter Sprachfeatures ist die bei mir ziemlich weit oben …

Edit:
http://en.wikipedia.org/wiki/Const-correctness#final_in_Java hat geschrieben:There is no way to declare that you will not modify the object pointed to by a reference through that reference in Java. Thus there are also no const methods. Const-correctness cannot be enforced in Java, although by use of interfaces and defining a read-only interface to your class and passing this around, you have a means to ensure that you can pass your objects around the system in a way they cannot be modified.
Das Fehlen des Features an sich empfinde ich ja nicht als schlimm … aber dass es auf dieser unaussprechlichen strictly-Pass-by-Value-Sache fußt, lässt mich sofort die schneeweiße Hasskappe aufsetzen. Bin ich blind, blöd, arrogant, 40-30-50 von allen dreien oder waren andere Sprachen wirklich so schlecht, dass es eine solche Totgeburt so weit schaffte?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Alexander Kornrumpf
Moderator
Beiträge: 2117
Registriert: 25.02.2009, 13:37

Re: Komplexität

Beitrag von Alexander Kornrumpf »

Das Fehlen des Features an sich empfinde ich ja nicht als schlimm … aber dass es auf dieser unaussprechlichen strictly-Pass-by-Value-Sache fußt, lässt mich sofort die schneeweiße Hasskappe aufsetzen.
Bei mir war es eher umgekehrt. Ich habe das Feature schon vermisst, als ich mit C# anfing, bin dann auch auf die Lösung mit dem read-only-interface gekommen und fand diese dann auch in Ordnung. Die Verfahren sind meiner Meinung nach durchaus vergleichbar.

Statt eine Methode const zu deklarieren schreibst du sie in das Interface.
Statt ein const Typ zu verwenden verwendest du ein IReadOnlyTyp.
Du kannst Typ überall verwenden wo du auch IReadOnlyTyp verwenden kannst.
Umgekehrt geht es nicht aber man kann das (vermutlich) auch casten (const-cast vs. downcast).

Löst bei mir jetzt keine großen Emotionen aus.
dronus
Establishment
Beiträge: 114
Registriert: 11.01.2010, 01:53

Re: Komplexität

Beitrag von dronus »

const.. hab ich auch vermisst, allerdings verhindert das weder

Code: Alles auswählen

objekt.setWert(neuerWert);
noch

Code: Alles auswählen

objekt.getSubobjekt().einWert=neuerWert;
oder?

Mit einem Interface kann man immerhin behaupten .setWert() nicht zu benutzen. Ich selber denke bei jeder Funktion die ich grad nicht von innen kenne "traue niemand."

Letztendlich würd ich mir eine Sprache wünschen die noch weniger kann. Natürlich kann ich selber entscheiden, welche Features ich benutze, aber andere können das leider auch :-) und deren Code will man ja auch mal lesen... ausserdem ist man ja bequem und was da ist wird irgendwann benutzt. Mir fällt grad keine Mainstream-Sprache ein die weniger kann bzw. komplex ist als Java. Ohne OO.. Pascal oder C vielleicht?

Ein paar Beispiele für unangenehme Komplexität bei Java:
* Methoden sind immer was bei C++ 'virtual' heisst, schön. Mehrfach definierte Felder werden dagegen vom Referenztyp abhängig zugegriffen. Da sag ich lieber dem Compiler versteckte Felder als Fehler zu melden.
* Ich weiss nicht so recht ob das Erlauben mehrere Methoden die sich nicht durch den Namen, aber durch die Signatur unterscheiden gut ist. Ich benutze das selber viel. Andererseits hilft einem da die IDE beim raffen, im reinen Texteditor ist man schonmal am rätseln was man jetzt eigentlich aufruft. Außer nötiger Kreativität beim Benamen hätte man ohne keinen Nachteil, oder hab ich das zu kurz gedacht?
* In den Libs findet sich viel Framework dass man durch Ableiten belebt. Klassisch UI-Panels, die man durch überladen von Paint-Methoden bemalt. Ich fände Listener da viel besser, weil man damit nicht in einem Mienenfeld von Hunderten vorhandener Methoden und Felder programmiert. Natürlich kann mich sich sowas in wenigen Zeilen schreiben..

Gefallen würde mir:
* Ich frag mich warum Konstruktoren nicht durch einen Modifier gekennzeichnet werden, so dass man ihnen beliebige Namen geben kann.
* Ich fände es sehr gut, wenn es zum Überladen einen Pflicht-Modifier gäbe. 'override public int tuWas(){...}' fänd ich gut. Das macht im aktuellen Codefile klar was Sache ist.
* Vielleicht wär es sogar gut wenn man alle im Codefile zugegriffenen Felder ausdrücklich erben müsste, z.b.

Code: Alles auswählen

class Basis{
   int zahl; 
}

class Erweiterung extends Basis{

   inherited int zahl;

   void erhieheZahl(){
      zahl++;  //Fehler, wenn man 'zahl' nicht 'geerbt' hätte
   }
}
Was meint ihr?
Benutzeravatar
Krishty
Establishment
Beiträge: 8265
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Komplexität

Beitrag von Krishty »

Alexander Kornrumpf hat geschrieben:Statt eine Methode const zu deklarieren schreibst du sie in das Interface.
Natürlich musst du aber erstmal das Interface schreiben, und so werden aus einer Klasse schon zwei. Dann hat man die Hälfte doppelt, lobet die Wartbarkeit. Nicht, dass ich die Lösung generell ablehnen würde … ich habe sowas in einzelnen Fällen auch schon in C++ gemacht (manchmal muss man ja nicht nur zwischen const und non-const unterscheiden, sondern auch verschiedenen Klienten unterschiedliche Interfaces derselben Klasse liefern) … aber für alles erscheint mir das zuviel Aufwand, zumal die meisten ja eh const-faul sind. Aber okay, ich habe zuwenig mit C# und Java gearbeitet, um das einschätzen zu können.
dronus hat geschrieben:const.. hab ich auch vermisst, allerdings verhindert das weder

Code: Alles auswählen

objekt.setWert(neuerWert);
noch

Code: Alles auswählen

objekt.getSubobjekt().einWert=neuerWert;
oder?
Doch … den ersten Fall sowieso, weil setWert() nicht aufgerufen werden könnte, falls objekt const deklariert ist und setWert() nicht. Den zweiten auch, denn getSubobjekt() würde, wenn const deklariert, auch eine Referenz zu einem const-Subobjekt zurückgeben (sonst könnte man z.B. einzelne Elemente eines Containers modifizieren, obwohl der Container selber const deklariert ist). Der Vollständigkeit halber: Natürlich nur, wenn man keinen Schweinkram mit const_cast und mutable macht, während man Subobjekt::operator = () const überlädt. Darüber, was verändert werden kann, hast du immer 99,9 %ige Kontrolle.
dronus hat geschrieben:Ohne OO.. Pascal oder C vielleicht?
C kann tatsächlich „weniger“, aber nur, weil es keine Klassen hat, heißt das nicht, dass man dort nicht objektorientiert arbeiten könnte. Objektorientierung ist letzten Endes auch nur eine Methode, die Sprache anzuwenden und kein Sprachfeature. Außerdem kannst du mir glauben, dass es mit C alles werden würde, aber nicht einfacher.
dronus hat geschrieben:* Ich weiss nicht so recht ob das Erlauben mehrere Methoden die sich nicht durch den Namen, aber durch die Signatur unterscheiden gut ist.
Wäre das nicht drin, wäre generische Programmierung mit Java noch kniffliger, als sie eh schon ist.
dronus hat geschrieben:* In den Libs findet sich viel Framework dass man durch Ableiten belebt.
Libs sind ja eigentlich kein Sprachfeature … die Programmierer werden gute Gründe gehabt haben, es so zu machen – und falls nicht, kann man sich sicher eine andere Lib suchen. Solche Entscheidungen sind immer sehr heikel, ich denke, dass da was hintersteckt.
dronus hat geschrieben:* Ich frag mich warum Konstruktoren nicht durch einen Modifier gekennzeichnet werden, so dass man ihnen beliebige Namen geben kann.
Such mal nach dem Named Constructor Idiom, das müsste sich 1:1 von C++ auf Java übertragen lassen.
dronus hat geschrieben:* Vielleicht wär es sogar gut wenn man alle im Codefile zugegriffenen Felder ausdrücklich erben müsste
In C++ muss man in der Basisklasse angeben, was man vererbbar machen möchte und in der erbenden Klasse, was man davon tatsächlich auch erben will. Zwar nicht für einzelne Variablen, aber mehr als Gruppen braucht man auch nicht. Wie es in Java läuft und ob sie das Feature überhaupt übernommen haben, kA.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Alexander Kornrumpf
Moderator
Beiträge: 2117
Registriert: 25.02.2009, 13:37

Re: Komplexität

Beitrag von Alexander Kornrumpf »

Dann hat man die Hälfte doppelt, lobet die Wartbarkeit.
Jaain. Es ist schon mehr Schreibarbeit (ist das ein Argument?) Aber der Fall dass man das Interface ändert und die Klasse versehentlich nicht kann nicht vorkommen weil das einen Compilerfehler wirft. Ich sag ja auch nicht dass das mit den Interfaces toll ist, aber es erfüllt seinen Zweck einigermaßen.

Slightly related:
Prinzipiell finde ich den Verzicht auf echte Mehrfachvererbung zugunsten von Interfaces übrigens richtig.
dronus
Establishment
Beiträge: 114
Registriert: 11.01.2010, 01:53

Re: Komplexität

Beitrag von dronus »

Krishty hat geschrieben:
dronus hat geschrieben:const.. hab ich auch vermisst, allerdings verhindert das weder

Code: Alles auswählen

objekt.setWert(neuerWert);
noch

Code: Alles auswählen

objekt.getSubobjekt().einWert=neuerWert;
oder?
Doch … den ersten Fall sowieso, weil setWert() nicht aufgerufen werden könnte, falls objekt const deklariert ist und setWert() nicht. Den zweiten auch, denn getSubobjekt() würde, wenn const deklariert, auch eine Referenz zu einem const-Subobjekt zurückgeben (sonst könnte man z.B. einzelne Elemente eines Containers modifizieren, obwohl der Container selber const deklariert ist). Der Vollständigkeit halber: Natürlich nur, wenn man keinen Schweinkram mit const_cast und mutable macht, während man Subobjekt::operator = () const überlädt. Darüber, was verändert werden kann, hast du immer 99,9 %ige Kontrolle.
D.h. in C++ kann ich eine Methode so deklarieren, dass sie weder das Objekt selbst noch irgendwie referenziertes verändern darf?
Das hab ich nicht früher nicht gewusst.
Krishty hat geschrieben: Such mal nach dem Named Constructor Idiom, das müsste sich 1:1 von C++ auf Java übertragen lassen.
Stimmt, da hätt man auch drauf kommen können..

Naja für Sprachdetails gibts jetzt einen neuen Thread :-)

Ich frag mich immer noch ob man generelle Vorschläge machen kann welche Prinzipien Komplexität schaffen oder Eindämmen.
Klar ist dass ich nicht Democoder-Bitknautscher Code schreiben will. Aber ich glaube dass Reduktion der Codemenge sehr viel Wert ist. Wenn ich aber nichts von Pattern halte muss ich irgendwo eine Grenze ziehen. Wenn man etwas geschickt berechnet, kann man vielleicht aus temporären Variable noch weitere Informationen rauspulen. Dann hat man leider keine Tupel bei der Funktionsrückgabe, und schon hat man eine Funktion mit mehreren Seiteneffekten. Das fühlt sich auch schlecht an.. Manchmal lagert man dann den gemeinsamen Teil in eine weitere Funktion aus, aber ich finde feine Zerteilung garnicht so gut.
Wenn man zersplitterten Code liest, muss man ständig im Text rumscrollen oder gar Files browsen, das kostet Konzentration. Oder man wird faul und begnügt sich mit dem Lesen des Funktionsaufrufs. Dann ist man wieder beim Thema "gute Namen", und davon halte ich nichts. Ich bin auch für gute Namen, aber "Der Name ist Schall und Rauch" und sagt eben nicht was eine Funktion tut, nur was sich der Autor dachte, dass sie tut.
Alexander Kornrumpf
Moderator
Beiträge: 2117
Registriert: 25.02.2009, 13:37

Re: Komplexität

Beitrag von Alexander Kornrumpf »

D.h. in C++ kann ich eine Methode so deklarieren, dass sie weder das Objekt selbst noch irgendwie referenziertes verändern darf?
Das hab ich nicht früher nicht gewusst.
Was zu beachten ist, dass eine konstante Methode natürlich auch nur konstante Referenzen zurück geben darf. Zu meiner Schande muss ich gestehen, dass ich nicht weiß ob der C++ Compiler das erzwingt. In Java / C# muss man das jedenfalls selbst designen, also irgendwie so:

Code: Alles auswählen

interface ISomeReadOnlyClass
{
     ISomeOtherReadOnlyClass getObject();
}
EDIT:

Gerade wegen 15 Min Leerlauf den Thread nochmal gelesen und das gefunden:
Ich fände es sehr gut, wenn es zum Überladen einen Pflicht-Modifier gäbe. 'override public int tuWas(){...}' fänd ich gut. Das macht im aktuellen Codefile klar was Sache ist.
Ist in C# so. Find ich auch super. Und die automatische Codevervollständigung interpretiert das keyword "override" auch korrekt. Das ist fast das beste daran.
Benutzeravatar
Krishty
Establishment
Beiträge: 8265
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Komplexität

Beitrag von Krishty »

Alexander Kornrumpf hat geschrieben:Was zu beachten ist, dass eine konstante Methode natürlich auch nur konstante Referenzen zurück geben darf. Zu meiner Schande muss ich gestehen, dass ich nicht weiß ob der C++ Compiler das erzwingt.
Aus Sicht einer const-Funktion ist jedes Member des Objekts, zu dem die Funktion gehört, ebenfalls const. Gibst du also von einer const-Funktion aus eine Referenz auf ein Member zurück, erzwingt der Compiler, dass diese ebenfalls const ist.

Btw sollte man const besser mit „unveränderlich“ übersetzen als mit „konstant“.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Alexander Kornrumpf
Moderator
Beiträge: 2117
Registriert: 25.02.2009, 13:37

Re: Komplexität

Beitrag von Alexander Kornrumpf »

Ok, das wäre also ein echter Nachteil an der Interface-Lösung.
Benutzeravatar
Krishty
Establishment
Beiträge: 8265
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Komplexität

Beitrag von Krishty »

Antworte nich so schnell, ich war noch nicht fertig ;)
Ist in C# so. Find ich auch super. Und die automatische Codevervollständigung interpretiert das keyword "override" auch korrekt. Das ist fast das beste daran.
Im nächsten C++-Standard ist sowas Ähnliches drin, allerdings nur mit hässlicher Syntax.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Komplexität

Beitrag von Aramis »

Zu C++0A(,B,C?) wäre noch zu erwähnen, dass der neue Standard die potentielle Komplexität von C++ an jeder nur denkbaren Stelle um 1 bis 2 Größenordnungen aufbläht ... C++ wird immer mehr zum Moloch ... mächtig, aber weder schön noch elegant. Eine so komplexe und aus verschiedensten Paradigmen zusammengeflickte Sprache ist meines Erachtens ungeeignet um das Problem der wachsenden Programmkomplexität anzugehen. C++ kann alles, kann OO in jeder nur denkbaren Nuance umsetzen, fordert immense Erfahrung und Selbstdisziplin -- letzteres ist zum Scheitern verurteilt (auch wenn natürlich jeder von sich behaupten würde, sich im Griff zu haben :-)).

Um genau zu sein nehmen sich C++0x und Perl gegenseitig nicht mehr viel was die Unlesbarkeit angeht, vorausgesetzt man nutzt alle Sprachfeatures aus.


Das ist kein Pladoyer gegen C++ - ich liebe die Sprache, ähnlich wie Krishty. Aber man muss einfach realistisch sein: es gibt keinen Markt für C++ außerhalb des Performance und System-Sektors (wo, vermute ich, C langsam verdrängt werden wird). C++ ist ungeeignet die Komplexität von Software zu verringern.
dronus
Establishment
Beiträge: 114
Registriert: 11.01.2010, 01:53

Re: Komplexität

Beitrag von dronus »

Alexander Kornrumpf hat geschrieben:
Ich fände es sehr gut, wenn es zum Überladen einen Pflicht-Modifier gäbe. 'override public int tuWas(){...}' fänd ich gut. Das macht im aktuellen Codefile klar was Sache ist.
Ist in C# so. Find ich auch super. Und die automatische Codevervollständigung interpretiert das keyword "override" auch korrekt. Das ist fast das beste daran.
Ok, dass geht in Java auch hab ich grad gesehen, ist halt nur nicht "von Natur aus" so, man muss es dem Compiler sagen. Eclipse berücksichtigt das ebenfalls.
Benutzeravatar
Krishty
Establishment
Beiträge: 8265
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Komplexität

Beitrag von Krishty »

Aramis hat geschrieben: C++ ist ungeeignet die Komplexität von Software zu verringern.
Das ist falsch. Zum einen sagt die Komplexität der Syntax nichts über die Komplexität oder Einfachheit der Programme aus, die man damit schreiben kann. Zum anderen ist es theoretisch geeignet, nur praktisch tut es eben kaum jemand … und nur, weil es in C++ einfacher ist als in Java, einfache Programme komplex darzustellen, ist es nicht automatisch schwerer, komplexe Programme einfach darzustellen (siehe const-vs-read-only-Interface, „wirk darauf nicht ein!“ => Syntaxkomplexität vs zusätzliche Schnittstelle => Programmkomplexität).

Eine interessante Frage in diesem Zusammenhang ist: Wären alle APIs/Frameworks auf aktuellem Stand (würden keine Zeiger verwenden, dafür aber Referenzen und Exceptions, wären vollkommen typsicher und const-correct, RAII-orientiert etc), wäre das das Ende für den C-mit-Klassen-Stil?

Ich bin durchaus dieser Meinung, denn wenn niemand mehr Zeiger benötigt und sich stattdessen zuerst mit Containern auseinandersetzen muss, wird er auch letztere bevorzugen. Aber wenn man mit APIs wie im OpenGL-Beispiel des anderen Threads hantieren muss ist klar, dass das ohne ausreichende Erfahrung mit sauberem Code über kurz oder lang in die Hose geht.

Mit der ganzen C-Unterstützung ist das eh so eine Sache – in C++ sind „böse“ Dinge wie reinterpret_cast bewusst so entworfen, dass sie mehr Tipparbeit erfordern, hässlich aussehen und darum vom Programmierer als nicht lohnenswert eingestuft werden sollten. Aber dann benutzt man eben einen C-Cast, der ist kürzer zu tippen und obendrauf nochmal um den Faktor 1000 unsicherer. Das ist, what really grinds my gears und was du wohl auch mit der Selbstdisziplin meinst.

Naja, der IOCCC wird ja auch in C ausgetragen, da liegt die Wurzel des Übels ;) Ich würde fast wetten, dass der Ellipsen-Operator („...“) für die Hälfte der Sicherheitslücken des letzten Jahrtausends verantwortlich ist.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Komplexität

Beitrag von kimmi »

Aramis hat geschrieben:C++ ist ungeeignet die Komplexität von Software zu verringern.
Das war auch nie der Anspruch von C++. Mit C++ kann man Probleme lösen, die in anderen Sprachen nur schwer zu adressieren sind. Und man muß C++ dafür beherrschen und das dauert. Genau aus diesem Grund bau ich mir gerade einen Editor mit .NET, der C++-Dlls benutzt. Man sollte die Sprache verwenden, die das Problem am besten löst und nicht auf der einen wahren Sprache beharren :-).
Ich habe mal an einem Programm in F77 mitgearbeitet, welches mehrere Mio. Lines of Code hatte und nicht mal da konnte man mal wirklich sagen, daß das schiefgegangen ist. Man kann die Komplexität mit dem richtigen Design und einer guten Architektur verringern, und das funktioniert sprachunabhängig. Eine Sprache allein wird keine Komplexität verringern. Auch in Python kann man Mist bauen, genauso wie in Java, C++, C, lisp, D oder Erlang.

Gruß Kimmi
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Komplexität

Beitrag von Aramis »

Man sollte die Sprache verwenden, die das Problem am besten löst und nicht auf der einen wahren Sprache beharren
Vollständige Zustimmung.
Eine Sprache allein wird keine Komplexität verringern.
Nicht durch ihre pure Existenz, klar. Aber sie trägt dazu bei indem sie entsprechende Hilfsmittel anbietet, und alles tut um einen Missbrauch ihrer selbst zu verhindern. Wenn ich die Programmierer erziehen muss, bestimmte Dinge *nicht* zu tun, kann ich diese Regeln auch gleich fest in der verwendeten Sprache verankern. Inwieweit das (z.B. in Java) auf Kosten der Effektivität, `Mächtigkeit´ und universellen Verwendbarkeit gehen muss, ist eine ganz andere Frage.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Komplexität

Beitrag von kimmi »

Das ist halt die Frage, in welche Richtung die Sprache designed wurde. C++ wurde schon immer als Multiparadigmen-Sprache entworfen und das merkt man :). Und man kann damit leicht sehr komplexen und fehlerhaften Unsinn bauen. Es war halt im Entwurf nie vorgesehen, dem Anwender Einschränkungen aufzuerlegen, da der Herr Stroustroup genau diese in seinem Entwurf vermeiden wollte ( wegen eines Projektes, welches er sonst nicht hätte ausführen können ).
Hat man eine solche Aufgabenstellung, muss man sich halt manchmal dem Schrecken von komplexen C++-Projekten stellen und zusehen, daß man nicht untergeht ( und es sind schon viele untergegangen ).
Anders formuliert: ertrinkt man in wachsener Komplexität, findet man im Sprachumfang von C++ 1000 verschiedene Varianten, sich neues Wasser zu besorgen ;).

Gruß Kimmi
dronus
Establishment
Beiträge: 114
Registriert: 11.01.2010, 01:53

Re: Komplexität

Beitrag von dronus »

Aramis hat geschrieben:
Eine Sprache allein wird keine Komplexität verringern.
Nicht durch ihre pure Existenz, klar. Aber sie trägt dazu bei indem sie entsprechende Hilfsmittel anbietet, und alles tut um einen Missbrauch ihrer selbst zu verhindern. Wenn ich die Programmierer erziehen muss, bestimmte Dinge *nicht* zu tun, kann ich diese Regeln auch gleich fest in der verwendeten Sprache verankern. Inwieweit das (z.B. in Java) auf Kosten der Effektivität, `Mächtigkeit´ und universellen Verwendbarkeit gehen muss, ist eine ganz andere Frage.
Viele Leute haben es dringend nötig dass man ihnen Hilfmittel anbietet, und noch viel wichtiger Übelmittel wegnimmt :-]

Der große Vorteil von "verankerten Regeln" in der Sprache kommt dann, wenn ich Code von anderen lese oder benutze. Dann muss ich davon ausgehen dass sie ihre kreative Freiheit auch ausnutzen, und je weniger sie hatten, umso besser.
Für mich selber sind Regeln natürlich Scheisse :-) (mit Ausnahme von ein paar, die mit gutem Nerdgefühl umgehen würde und dann darunter leide.).

Ein einfaches Beispiel:
Es ist doch allgemein nützlich, wenn man alle Aufrufe einer Methode oder Zugriffe auf eine Variable im Code finden kann.

Da gibts in C++ säckeweise Mechanismen um das zu haarsträubend schwer zu machen..

In PHP wo Includes zur Laufzeit aufgelöst werden, gibt es unglaubliche Ideen, wie man die Includes aufsucht. Die menschliche Kreativität fasziniert mich da immer wieder, wenn ich nicht in der Lage bin durch Lesen des Codes herauszubekommen, wo eine aufgerufene Funktion überhaupt implementiert wurde. Es gab Situationen wo ich mit dem Debugger den Dateipfad des Codefiles ermitteln musste.........

Java-Code kann man auch ganz gut ohne große Scripte bauen, weil der Compiler automatisch rekursiv alle fehlenden Codefiles baut. Doch der Spielverderber lautet Reflection. Sobald Strings darüber entscheiden welche Klassen zu einem Programm gehören, ist das schöne Feature weg. Trotzdem benutze ich so etwas, aber ich ärgere mich immer ein bisschen nur für diesen speziellen Luxus einen weiteren besonderen "Mechanismus" in meinem Code zu verwenden.

Ich glaub Komplexität ist am besten durch Geduld und Ignorieren von Frameworks zu bekämpfen.
Antworten