Codingstil: Wie sieht euer Projekt-Design aus?

Übersicht Sonstiges Smalltalk

Neue Antwort erstellen

Fetze

Betreff: Codingstil: Wie sieht euer Projekt-Design aus?

BeitragSo, Dez 20, 2009 13:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi Leute.

Ich stelle bei mir mit wachsender Erfahrung im Codedesign größerer Projekte eine zunehmende Unfähigkeit fest, kleine Projekte einfach mal eben "quick'n'dirty" zusammenzuhacken. Es ist weniger eine konkrete Unfähigkeit als mehr die Tatsache, dass ich mich sehr am Riemen reißen muss, um nicht unmengen von overengineereten Klassenkonstrukten zu produzieren. Die Schwierigkeit besteht darin, einem Projekt eine angemessene Designkomplexität im Inneren zuzuordnen und sich an diese auch zu halten.

Beispiele für geringe Designkomplexität:
--> Ein paar globale Programmfunktionen für MainLoop, Hauptmenü, Ladevorgang, etc.
--> Wenn nötig, ein oder zwei Klassen für Objekte im Spiel
--> Spielercode, etc. direkt im Hauptprogramm

Beispiele für hohe Komplexität:
--> Keine vorgegebenen Klassen zur Bearbeitung von Einzelfunktionen des Programms sondern ein dynamisches Task-System
--> Kein manuelles Einladen des Contents, sondern ein ContentProvider, der alle vorhandenen Resourcen erfasst und bei Bedarf einlädt und herausgibt
--> Komplexe Vererbungshierarchie von Spielobjekten à la IPositionable --> GameObject --> ControllableObject --> Ship
--> Automatisierte Serialisierung, beispielsweise durch Aufspaltung jedes Objekts in "Spielobjekt" und "Datenobjekt" wobei das Datenobjekt rein primitive Datentypen enthält und Teil des Spielobjekts ist.
--> Blueprinting-System für Massenproduktion von Objekten bestimmter Typen (zB. Raumschifftypen)
--> Auslagerung aller Contentdaten in externe Dateien.
--> etc.

Wie handhabt ihr das? Habt ihr für euch klare Design-Indizien gefunden, die euch sagen "Junge, das ist jetzt aber sehr overengineered"? Habt ihr Taktiken entwickelt, die euch davon abhalten, euch zu viele Gedanken über Codekomponenten zu machen, die das im Rahmen des Projekts überhaupt nicht verdient haben?
 

konstantin

BeitragSo, Dez 20, 2009 13:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Bei mir schlaegt sich das eigentlich eher in der Wahl der Programmiersprache nieder. Wenn ich 'quick-n-dirty' was zusammen kloppen moechte, lande ich meist irgendwo bei BB oder Perl, da mach ich mir dann nur selten Gedanken ueber das eigentliche Design - am Ende kommt eh nur Code-Wurstbrei raus. Wink

Ansonsten erfordern grosse Projekte meist auch die dazu passende Programmiersprache, und ich persoenlich habe die Erfahrung gemacht, dass man zum Beispiel fuer ein Projekt in C zwangslaeufig vernuenftige Strukturen benoetigt, sonst steht man nach ein paar Tagen ziemlich im Regen.

Akribisches Layout ist aber meiner Meinung nach eher was fuer von vornherein gross angelegte Projekte, bei denen man eventuell auch mit vielen anderen zusammen arbeitet. Fuer den heimgebrauch reicht es ja, wenn man den Code nach ein paar Wochen noch selbst versteht - und die Performance stimmt.
 

n-Halbleiter

BeitragSo, Dez 20, 2009 13:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Fetze, ziemlich genau diese Indizien habe ich bei mir auch festgestellt. Wenn man größere Projekte angeht, wird geplant. Und dieses Overengineering, wie du es beschreibst, ist eines der Produkte des Planens, denke ich. Für kleine Projekte ist die Wartbarkeit erstmal egal, da man im Nachhinein vermutlich sowieso nichts ändert, ansonsten ist die Wart- und Austauschbarkeit der Komponenten ja essentiell...

Gedanken über das Design musste ich mir z.B. bei Ploing nicht machen, jedoch bei meinem Core schon. Hier sehe ich auch den Kontrast von "quick'n'dirty" zu geplantem Design, der sich in ebenjenen Kriterien für hohe bzw. niedrige Komplexität niederschlägt.

Wenn ich ein kleines Spiel zusammenschustere, dann verfalle ich meist in ein planloses Verhalten: Ich schreibe eine Komponente in mein (meist einziges (!)) Sourcefile, teste, debugge wenn es notwendig ist und mache mich an eine neue Komponente. Wenn ich dann im Nachhinein eine Komponente modifizieren möchte, dann läuft dies häufig darauf hinaus, dass ich viel Source neuschreiben muss... Es ist eine gewachsene Struktur, bei großen Projekten ist es dann geplant. Dies sieht man auf den ersten Blick im Source, zumindest war das bisher bei mir immer so. Die gewachsene Struktur hat den Vorteil, dass sie schnell(er) gecodet ist als die geplante, allerdings ist - wie ja oben schon angemerkt - die Wartbarkeit des Codes deutlich geringer.
mfg, Calvin
Maschine: Intel Core2 Duo E6750, 4GB DDR2-Ram, ATI Radeon HD4850, Win 7 x64 und Ubuntu 12.04 64-Bit
Ploing!
Blog

"Die Seele einer jeden Ordnung ist ein großer Papierkorb." - Kurt Tucholsky (09.01.1890 - 21.12.1935)

ZaP

BeitragSo, Dez 20, 2009 14:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Kommt bei mir auf die Sprache an, die ich benutze... BB ist meistens sehr schlampig strukturiert, alles andere ist hingegen meist ganz sauber und übersichtlich (und vorallem auskommentiert) Dabei achte ich idr stark darauf, dass alles uniform und aufgeräumt ist, z.B. ganz oben natürlich Includes und Header, Systemglobale, usw. und nach jedem Funktionsdeckel eine Leerzeile (wenn keine { ), und solche Dinge.
Starfare: Worklog, Website (download)

Nicdel

BeitragSo, Dez 20, 2009 14:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Bei mir liegts auch an der Programmiersprache. Wenn ich schnell was machen will, dann mit BB und unordentlich. Für größere Projekte nehme ich dann BMax, damit kann man einfach schöner programmieren Smile
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7

Triton

BeitragSo, Dez 20, 2009 14:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich fange an, vollende die ersten 80% innerhalb kürzester Zeit, brauche für das Bugfixing der nächsten 10% doppelt so lange und für jedes folgende Prozentchen nochmal doppelt so lange.

Klingt witzig, ist aber eigentlich traurig, weils wahr ist Rolling Eyes

Bei meinem Aktuellen Projekt (der ultimativen Stringrechenbibliothek) steh ich immerhin bei 99% und da
versuche ich alles so einfach wie möglich zu halten.

D.h. einfache Gliederung in eine Includedatei in der jede Rechenfunktion einfach eine Function darstellt,
nur Arrays und einfache Variablen. Das ist vorallem für den Speed von enormer Bedeutung.
Dann noch den Code ordentlich einrücken, vor und nach Functions ein paar Leerzeilen und dann sieht das schon ganz gut aus und kann trotzdem viel.

Ich habe die Erfahrung in diesem Projekt gemacht, dass der komplexere, vermeintlich bessere Algorithmus
oft die Flexibilität mit Geschwindigkeit erkauft.

90% der Zeit die ich in diese Stringrechenbibliothek investiert habe, hatten mit der vereinfachung und der
erhöhung der Geschwindikeit zu tun.
Coding: silizium-net.de | Portfolio: Triton.ch.vu

Silver_Knee

BeitragSo, Dez 20, 2009 14:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Also ich hab inzwischen glaub ich die ganze bandbreite an Projektmanagement gesehen.

Der erste cnRS-Code von Evolver war komplett für ein Raumschiff ausgelegt. Es hat alles funktioniert aber es war ultra fix. Ein 2. Raumschiff und das komplette system musste neu geschrieben werden.

Der 2. cnRS-Code von mir war dann schon strukturiert. Types für jede Kleinigkeit, Kampf gegen undynamische Arrays, ohne auf die idee der Banks zu kommen. trotzdem war alles noch relativ hardcoded und unübersichtlich. Der code in 1000enden dateien aufgesplittet, nur damit es professionell aussieht hat mich umgebracht.

Aktuell arbeiten Timbo und ich an der 3. Generation. Thema schwarzer bildschirm. mehr als 300 zeilen und was sieht man: schwarzer bildschirm und im debuglog steht connection established. Dafür diesmal strukturiert ins kleinste detail. Das Konzept umfasst mehrere Paint-Grafiken und ich hab so langsam das gefühl es könnte was werden auch wenn man immernoch schwarzen bildschirm hat.

Fetze

BeitragSo, Dez 20, 2009 14:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Ich habe die Erfahrung in diesem Projekt gemacht, dass der komplexere, vermeintlich bessere Algorithmus
oft die Flexibilität mit Geschwindigkeit erkauft.

Ja, die Erfahrung habe ich auch gemacht; wenn es um performancekritische Utility-Funktionen geht, taste ich mich zwar mit schön durchdachten Algorithmen heran... aber verzichte bei der darauf folgenden Codeoptimierung vollständig auf Design. Hier ist es am Ende relativ egal, wie das Codedesign aussieht, da der Code sich ja in einer abgeschlossenen und zumeist extrem kleinen Komponente befindet; Erweiterbarkeit spielt da oft einfach keine Rolle, Geschwindigkeit aber schon.

Wenn es um größere Projekte geht, ist der performanceseitige Verwaltungsoverhead für Codedesignkram (zB. wenn man Manager für verschiedene Objekttypen anlegt oder ein Task-System einbaut) oft minimal, wenn man dabei den ohnehin vorhandenen Zeitaufwand zur Berechnung eines Frames im Auge behält. Ein Designkonzept, das sich aber an einer performancekritischen Stelle befindet (zB. im Inneren einer allgemeinen GameObject-Klasse), muss dann doch erhöhten Anforderungen genügen. Verlangsamt es den Code zu sehr, ist es schlicht nicht praktikabel, ergo: Raus damit!

Ein Beispiel: Wenn ein GameObject zwecks Serialisierungsvereinfachung all seine primitiven Daten(typen) in einem eingekapselten Description-Objekt abspeichert, muss der Zugriff auf diese schnell genug vonstatten gehen. Würde man das Beispielsweise durch ein Dictionary<string,object> realisieren, wäre der performance overhead viel zu groß und das Konzept damit wertlos. Durch direkten Zugriff des GameObjects auf die Member eines als struct angelegten Description-Objects (ohne Umweg über Properties oder Getter-Funktionen) ist der Overhead hingegen nicht vorhanden, das Designkonzept genügt in dem Fall also seinen erhöhten Anforderungen.
 

n-Halbleiter

BeitragSo, Dez 20, 2009 15:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Genau, die sicher finalen Teile können auch schonmal etwas unschöner aussehen, wenn sie dafür schön Performance und alles bieten. Wink
mfg, Calvin
Maschine: Intel Core2 Duo E6750, 4GB DDR2-Ram, ATI Radeon HD4850, Win 7 x64 und Ubuntu 12.04 64-Bit
Ploing!
Blog

"Die Seele einer jeden Ordnung ist ein großer Papierkorb." - Kurt Tucholsky (09.01.1890 - 21.12.1935)

ComNik

BeitragSo, Dez 20, 2009 18:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Stichwort Verwaltungsoverhead.

Das ist für mich das beste Mittel mich nicht in Vererbung und zu vielen Klassen zu verlieren.
Zum Beispiel habe ich für mein aktuelles ziemlich großes Spieleprojekt eine sehr komplexe KI designt die praktisch unendlich erweiterbar ist... Ich stürze mich dann immer tiefer in "geniale" Ideen und denk mir dann an einem Punkt "Oh Verdammt das werden aber viele Klassen Confused , lieber das und das rausnehmen!"

Aber ansonsten gerne viele Klassen und viel Design. Kleine schnelle Tests werden bei mir automatisch sehr "dirty" weil ich es nicht abwarten kann Ergebnisse zu sehen (SEHEN nicht FÜHLEN) Rolling Eyes ...

lg
ComNik
WIP: Vorx.Engine

Jolinah

BeitragSo, Dez 20, 2009 20:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Das geht wohl jedem ähnlich Smile Aber wenn die Geschwindigkeit nicht so eine Rolle spielt, kann es meistens nicht schaden. Der Code wird dadurch besser erweiter- und wartbar. Ein Nachteil ist sicher dass man so viel länger braucht um was fertig zu stellen.

Ein Grund dafür ist bei mir, dass ich das Designen einfach zu gerne mache. Hier muss man sich wohl einfach zusammenreissen und sich dazu überwinden auch mal wieder "unschönen" Code zu schreiben Wink

mpmxyz

BeitragSo, Dez 20, 2009 22:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Abgesehen von meinen frühen Anfängen kann man meinen Großprojektstil in zwei Phasen einteilen:

ohne OOP-Ahnungen:

Das Projekt ist langsam zusammen mit meiner Programmiererfahrung angewachsen.
Es herrschte eine gewisse Zeit lang kein großer Plan.
Als ich welche hatte, waren sie eher selten aufgeschrieben.
Relativ schnell war ich mir allerdings sicher, dass das Spiel variabel werden soll.
Damit kam eine Neuerung: Ich fing an, zumindest "Standards" zu protokollieren, da ich für Objektinformationen Banks nutzte - sie schienen damals schneller als Types zu sein - und ich mir für deren Informationen Offsets und Datentypen merken musste.
Doch auch das wurde schnell zu ineffizient und ich fang an, die Offsets in nach einem gewissen System erstellten Konstanten zu speichern.
Das Projekt wurde langsam strukturierter und es gab endlich eine Art To-Do-Liste.
Trotzdem starb dieses Projekt.
Das lag zum Einen daran, dass ich mir immer noch die Datentypen der in Banks abgespeicherten Daten merken musste und die langen Konstanten für die Offsets ziemlich umständlich waren, zum Anderen aber daran, dass das Projekt immer noch aus allen möglichen Programmierstilen bestand.
Gegen den Aufwand der Banks habe ich einen Precompiler geschrieben, der ziemlich Hardgecodet ist und einige Coderedundanzen enthält.
Die für diesen Precompiler notwendigen Inis und meine ersten OOP-Ahnungen - eigentlich war OOP für mich immer noch ziemlich unbekannt - sorgten dafür, dass ich mein Projekt noch einmal anfing.

mit OOP-Ahnungen:

Als erstes kamen die Inis.
Diese waren eine sehr detaillierte To-Do-Liste und halfen mir sehr, einen ordentlichen Stil zu halten und gewisse Standardabläufe durchzuplanen.
In relativ kurzer Zeit habe ich 26 Code-Dateien mit insgesamt 162 KiB bzw. grob geschätzten 5000 Zeilen Code fertiggestellt, der das war, was er sein sollte: eine Leistungsfähige und flexible Grafikengine.

Seit dem Anfang dieses Schuljahres war dann aber meine Freizeit wieder eingeschränkter und ich hatte mich auf ein Nebenprojekt konzentriert, welches ich erst später in meinem Hauptprojekt hätte verwenden können.
Während dieser Zeit kam aber die OOP-Erleuchtung; ich hatte mir in der Schule OOP in Java angeeignet und dieses dann später noch einmal 'richtig' gelernt.
Auch, wenn ich B3D verwendete, hatte ich versucht, meinen Programmierstil möglichst objektorientiert zu gestalten.
Die Banks sah ich langsam als Objekte, einige Funktionen konnte ich mir gut als Objektmethoden vorstellen und ich hatte schon einige "gefakte Vererbungen" genutzt.
Nun habe ich BlitzMax getestet und mein Codingstil ist weiter in Richtung OOP gerutscht.

Aber für die Zukunft muss ich mir noch überlegen, wie es weitergeht.

mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer
 

BIG BUG

BeitragMo, Dez 21, 2009 2:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Ein Grund dafür ist bei mir, dass ich das Designen einfach zu gerne mache. Hier muss man sich wohl einfach zusammenreissen und sich dazu überwinden auch mal wieder "unschönen" Code zu schreiben Wink

Jo, den richtigen Zwischenweg zu finden ist manchmal gar nicht so leicht. Ein tiefgründiges Design ist auch nicht unbedingt übersichtlicher/leichter wartbar, z.B. ist ein LoadImage leichter zu verstehen als ein Ressourcenmanager.
Letztendlich hängt viel davon ab, wie komplex ein Softwareprodukt am Ende sein soll.
Termine sind natürlich ein weiterer Punkt, wobei ein sauberes Grunddesign nicht unter Termindruck leiden darf. Kleinere unabhängige Dinge können notfalls auch "hingeschmiert" werden.

Ich denke dies ist insgesamt ein Punkt wo Erfahrung eine große Rolle spielt. Und es freut einen schon wenn man Jahre später noch etwas implementieren möchte/muss und das ursprüngliche Design dies dann tatsächlich einfach macht.
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final)

ozzi789

BeitragMo, Dez 21, 2009 9:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Also wenn ich mal nur kurz code, dann wie bei den Meisten ziemlich ungeplant und einfach drauflos.
Seit ich Programmieren (C#) als Schulfach habe, mache ich sogar Struktogramme bei grösseren Projekten, der Ablauf

-Idee
-Mögliche Probleme finden und lösen (anhand des Struktogramms, meistens lass ich mir vor dem Einschlafen alles durch den Kopf gehn)
-Anfang Coden
-Schauen ob man sich ans Struktogramm hält, falls nicht, entscheiden ob man einen Fehler gemacht hat und dann entweder den Code oder das SG verbessern

Und das wiederholt sich solange bis es fertig ist.

Allgemein arbeite ich sehr gerne mit Types.. habe mir auch angewöhnt sozusagen nichts mehr in die Hauptschleife zu packen als funktions aufrufe und zmb Bilder laden usw in eine Include, viel schöner so Smile
0x2B || ! 0x2B
C# | C++13 | Java 7 | PHP 5

Arrangemonk

BeitragMo, Dez 21, 2009 13:53
Antworten mit Zitat
Benutzer-Profile anzeigen
interfaces, implementierende klassen, alles ziemlich abstakt gehalten
aber ich mach ja auch keine spiele
ingeneur

Markus2

BeitragFr, Dez 25, 2009 18:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich konzentriere mich auf einzelne Funktionen das die perfekt sind und das machen was sie sollen und
auch zurück geben ob sie das getan haben was sie sollten .
Je kürzer je besser aber auch gleichzeitig das man alles gut versteht .
Wenn man alles ordentlich macht spart man sich später eine menge Arbeit und Fehlersuche .
Ein Baum wächst langsam , es macht keinen Sinn direkt alles auf einmal anzufangen .
Und man muß in der Lage sein immer das ganze Programm zu verstehen (im groben) ,
den Ablauf um Kopf laufen zu lassen , zu simulieren , voraussagen zu machen .
Wenn man eine Aufgabe hat zoomt man in die Komplexität rein , konzentriert sich auf dieses Umfeld ,
zoomt wieder raus und wieder wo anders rein .
Wenn man lange nicht am Programm gearbeitet hat ist es von Vorteil sich einen Ablaufplan zu machen,
also wann wo welche Funktion benutzt wird untereinander schreiben .

Jamagin

BeitragFr, Dez 25, 2009 18:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich mache mir bei meinen Projekten immer zuerst ein Konzept, ein Schema (Ablaufplan oder Flußdiagramm) wie auch immer das heißen mag und ich habe mir von Beginn an angeeignet sauber zu programmieren. Ich kommentiere fast alles, damit ich auch nach längerer Codeabwesenheit wieder schnell ins Programm finde.

Nach und nach wird der Code optimiert, zusammengefasst und Teile davon wieder in den Müll geworfen. Letztendlich hab ich dann ein sauber, gut durchstrukturiertes Programm. Das da natürlich viel Zeit drauf geht ist klar, aber wenn ich schnell was hinwurstel und es nimmt irgendwann Form an oder es artet sich doch zu etwas größeren, dann hat man noch mehr Zeitverlust.

Nichts geht über ein klar gegliedertes Designdokument, wo alles festgehalten wird. Aber jeder macht das sowieso auf seine Art. Ich fahre ganz gut damit, das Hauptprogramm oder die Mainloop halte ich so kurz wie möglich und da kommen ausschließlich nur Funktionsaufrufe hin. So bin ich sehr flexibel. Auch vermeide ich Goto und Gosub's wo es nur geht!

lg. Jamagin Cool
Bevor du etwas neues beginnst, erledige das alte

Neue Antwort erstellen


Übersicht Sonstiges Smalltalk

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group