Hallo, ich als Hobbyprogrammierer kann kleine Programme sehr gut ohne Planung programmieren. Das funktioniert aber bei großen Programmen nicht. Wie plane ich große Programme jetzt richtig? Gibt es etwas mit Erfolgsgarantie? Im Moment scheitern alle großen Programme an "Ver-Spaghetti-sierung". Ich bitte jeden darum, der schonmal ein großes Programm geschrieben hat, zu posten: - wie viele Zeilen hat das Programm? - welche Sprache? - wie wurde das Programm geplant? - wurde der Plan eingehalten? - ... Ich möchte gerne auch große Programme schreiben können! (über 1000 Zeilen) Gruß, Feadi
ad 1) ca. 1.8 Millionen ad 2) C++ ad 3) vor 20 Jahren. Die Entwickler haben darüber geredet welche Subsysteme es geben soll, welche Aufgaben diese haben und wie die Teile zusammenarbeiten sollen (Schnittstellen). ad 4) Im grossen und ganzen ja. Natürlich hat es im Lauf der Zeit Änderungen gegeben. Neue Dinge an die vorher keiner gedacht hat, sind dazugekommen. Andere Dinge haben nicht so funktioniert wie angedacht und es mussten neue Konzepte überlegt und ausprobiert werden. Es kamen Erweiterungen dazu. Das GUI wurde zwischendurch 2 mal modernisiert, etc. Aber die Grundbasis ist heute im Wesentlichen immer noch dieselbe. > Gibt es etwas mit Erfolgsgarantie? Nein. Na ja. Stimmt nicht ganz. Klar kann man die Spezifikation so detailiert schreiben, dass das Pgm dann auch 100% genau diese Spez einhält. Nur: Niemand garantiert, dass die Spez. nicht in sich widersprüchlich ist und 2.tens kann sich ausser dem DoD und den Luftfahrtfirmen und vielleicht noch JPL keine normale Softwarefirma den Aufwand leisten. Grauzonen gibt es in jedem Projekt. Mir ist auch noch kein Projekt untergekommen in dem sich nicht während der Entwicklung die Anfoderungen noch etwas ändern. Sollte nicht so sein, ist aber so in der Praxis. > Im Moment scheitern alle großen Programme an > "Ver-Spaghetti-sierung". Dagegen hilft nur * modularer Aufbau * konsequente Aufgabenteilung der Module * Disziplin * Disziplin * Disziplin
Hallo An dieser Stelle würde mich auch noch interessieren, wie man so grosse Projekte sinnvoll testen kann. (Sowohl Prinzipien, als auch konkrete Verfahren) Gruss Michael
Das allerwichtigste ist sauber zu definieren: Was soll eigentlich umgesetzt werden. Im professionellen Bereich wird so etwas in der Regel durch ein "Pflichtenheft" realisiert. Häufig ist es jedoch trotzdem so, dass sich Anforderungen während der Programmierung, oder nach Fertigstellung ändern. Gerade im Bereich der kaufmännischen Software ist dies "normal". Für diese Probleme heisst das Zauberwort meiner Erfahrung nach : Modularisierung. Gerade wenn Projekte größer werden ist dies mit "Spagetticode" nicht mehr zu handhaben. Deshalb muss man sich überlegen: Was gehört funktionell zusammen? Ein wichtiges Werkzeug zur Kapselung ist die objektorientierte Programmierung. Vereinfacht kann man sagen, dass diese Art der Programmierung der Arbeitsweise des Gehirns recht nahe kommt. Wenn man eine Schachtel Zigaretten von a nach b transportieren will, ist es nicht relevant um welche Marke es sich handelt. Auch die Anzahl der Zigaretten ist unwichtig. Man muss in diesen Moment auch nicht wissen, wie eine einzelne Zigarette entnommen werden kann. Es wird nur das Objekt "Zigarettenschachtel" bewegt. Das nennt man Abstraktion. Alles was mit der Schachtel zu tun hat, wird zusammengefasst und kann im Code als eine Einheit benutzt werden. Änderungen an der Schachtel werden nur im Modul vorgenommen, der restliche Code bleibt davon weitestgehend unbeindruckt. Den Spass der Abstraktion kann man noch weiter treiben, mit der sogenannten "Service orientierten Architektur". Beispiel: Eine Firma will ihre interne Software umbauen. Modularisieren wir wieder: Was wird sich niemals ändern? Eine Firma hat Kunden. Die müssen angelegt, gespeicher, bearbeitet und gelöscht werden. Abgelegt werden die Daten in einer Datenbank. Alle diese Funktionen schreibt man nun so, dass sie unabhängig von allen anderen Softwarefunktionen (zB. Lieferanten) funktionieren und fügt sie in einem sogenannten "Service" zusammen. Häufig erhält dieser nun noch eine Webschnittstelle per "SOAP". Über diese kann man die komplette Funktionalität in fast jeder beliebigen Programmiersprache wieder einbinden (über das Internet theoretisch überall auf der Welt) und mit anderen Services zusammenfügen (zB. Bestellungen). Bei disziplinierter Umsetzung einer solchen Strategie ist jede Anforderungsänderung durch das "Lego-artige" zusammensetzen gut handhabbar. (Prominente Anwender von Webservices sind zB. ebay, google, amazon, fedex etc. Komplette Ebay funktionen können zB. nach registrierung bei ebay in eigener Software genutzt werden.) Kurz noch zu Softwaretests: Es gibt zahlreiche Frameworks mit denen sich mehr oder weniger komfortable Unit-Tests bauen lassen. Im Prinzip schreibt man für jedes Stück Code unmittelbar eine Testroutine. So wächst neben der Software auch der komplette Softwaretest. Damit erreicht man das nach jeder kleinen Änderung automatisiert der KOMPLETTE Anwendungstest in wenigen Sekunden durchlaufen werden kann. Fehler sind so viel einfacher zu finden. Wikipedia liefert zu allen Stichpunkten sehr gute Einstiegspunkte. Hoffe ich hab mich nicht zu umständlich ausgedrückt und es war ein bisschen hilfreich. Gruß oimelx
@Oimelx Das Beispiel mit der Zigarettenschachtel ist genial. So gut hat mir das auch noch keiner erklärt, wie das mit den Objekten verhält. Als alter Basic-Fan hatte ich immer meine Schwierigkeiten, den Sinn solchen Vorgehens zu erkennen. Gruß Sigma N.
Sigma N. wrote: Als alter Basic-Fan hatte ich immer meine Schwierigkeiten, den Sinn solchen Vorgehens zu erkennen. das machste früher oder später automatisch. auch mit sprachen, die nicht direkt oo unterstützen ;)
> An dieser Stelle würde mich auch noch interessieren, wie man so grosse > Projekte sinnvoll testen kann. (Sowohl Prinzipien, als auch konkrete > Verfahren) Ganz konkret. Das System mit dem ich die letzten 20 Jahre verbracht habe, war eine Art CAD System. Ein Modul davon ist klarerweise der Graphikkern. Seine Aufgabe ist es die komplette Graphikstruktur zu halten und zu verwalten. Eine Szenerie besteht aus einem Objekt. Ein Objekt kann ein einzelnes graphisches Objekt oder eine Gruppe von anderen Objekten sein. Dadurch spannt sich, ausgehend von der Szenerie als Wurzel, ein kompletter Baum von Objekten auf, wobei in den Endknoten graphische Objeke sitzen und die Baumebenen dazwischen eine Hierarchie bilden. Graphische Objekte wiederrum bestehen aus einer Sammlung von Primitiven. Jedes Primitiv besteht aus Punkten, die zu Kanten zusammengeasst werden, welche wiederrum in Schleifen organisiert sind die wiederum Flächen bilden. In dieser Struktur können auch Querverweise existieren, wenn ein Objekt seine räumliche Position an die Position eines anderen Objektes koppelt, oder zb. ein dynamisches Mass sich bei einer Größenänderung eines anderen Objektes verändern muss. Teil der DLL, die sich um die komplette Datenstruktur kümmert ist ein Prüfmodul, dass die komplette Datenstruktur auf Fehler untersucht. Dort wird abgeprüft, ob Pointer noch auf gültigen Speicher verweisen, ob die Hierarchieverkettung gültig ist (Vorwärts - Rückwärtsverkettung) und noch viele andere Dinge. In einem Debug-Build wird vor jeder Operation, die irgend etwas in der Datenstruktur verändert, diese Prüfroutine aufgerufen. Danach wird die Operation durchgeführt und nachdem diese ab- geschlossen ist, wird wieder geprüft ob die Datenstruktur noch in Ordnung ist. Durch diese ständige Prüfung läuft zwar das Pgm 3 mal so langsam wie die Auslieferversion, dafür ist aber seit Jahren kein Showstopper in den Funktionen dieses Moduls vorgekommen. Falls tatsächlich mal ein Fehler in einer neu hinzugekommenen Funktionalität war, so haben ihn die Prüfroutinen gefunden. Wenn es tatsächlich mal Fehler unentdeckt bis zur Testmannschaft geschafft haben, so wird als erstes die Prüfroutine erweitert bis dieser Fehler zuverlässig detektiert werden kann. Erst dann wird der Fehler korrigiert. Ich bin mir sehr sicher, dass zur Zeit kein wirklich schwerwiegender Fehler in diesem Modul enthalten ist, der zb. einen Absturz verursachen würde. Leichtere Fehler werden wahrscheinlich noch drinnen sein, geschätzt aber sicher weniger als 50 oder 60.
Ist das nicht öde, 2 Dekaden mit ein und demselben Projekt zu verbringen? - oder habe ich das was falsch verstanden ? Ansonsten Danke für die interessanten Infos zum modularen Testen.
> Ist das nicht öde, 2 Dekaden mit ein und demselben Projekt zu > verbringen? - oder habe ich das was falsch verstanden ? Absolut nicht. Ganz im Gegenteil. Das Projekt bleibt ja nicht stehen, sondern entwickelt sich weiter. Und mit jeder Ergänzung stösst man die Tür für weitere Entwicklungsrichtungen auf. Es ist fast wie ein Kind, das du von seiner Geburt weg in seiner Entwicklung verfolgst und aktiv begleitest. Und klar: natürlich gibt es Durststrecken, die fad sind. Aber dann kommt wieder ein Moment, der das alles aufwiegt: Wenn das Pgm Dinge kann, die du (und dein Kunde) nie für möglich gehalten hättest. Und ja: natürlich gibt es in jedem Programm Code-Stellen die einfach 'nicht stimmen'. Ich kann das schlecht beschreiben, aber der Code in einigen Bereichen sieht einfach falsch aus. Das ist mehr ein Gefühl in der Bauchgegend; wie bei einem Bild, bei dem die Farbkomposition irgendwie falsch zu sein scheint. Und irgendwann gehst du's dann an und arbeitest an dem Teil. Durch die Modularisierung geht das auch relativ gut. Das Modul hat seine Schnittstellen nach aussen, die du nach Möglichkeit gleich lässt. Aber intern bleibt kein Stein auf dem anderen. Und plötzlich lichtet sich die Dunkelheit. Eins passt zum anderen, und dann stehst du mit einer neuen Struktur da, die einfach nur schön ist. An solchen Tagen (oder Wochen) gehst du dann abends mit einem Lächeln nach Hause.
Hallo, ich habe hier ein Zitat aus http://www.mikrocontroller.net/articles/Diskussion:USB_Oszilloskop : "Im Nachhinein ist es naturgemäß immer schwer Änderungen einfließen zu lassen, wenn das nicht bei der Planung bedacht wurde." Trifft das wirklich zu, oder plant man da nicht richtig? Ich hätte gerne noch ein Beispiel zur Modularisierung vom Programmen in C++. Gruß, Feadi
Das Thema interessiert mich auch, kennt jemand ein gutes Buch indem anhand eines Projektes das ganze exemplarisch exerziert wird? Am besten wäre natürlich c/c++. Hab bisher noch kein Programmierbuch gefunden das das anhand eines Beispiels macht... alle Programmierbücher enden wenn die Syntax erklärt wurde
> Ich hätte gerne noch ein Beispiel zur Modularisierung vom Programmen > in C++. Also bei objektorientierter Programmierung. Dort sind Objekte im wesentlichen deine Module. Eine gute Methode für einen ersten Entwurf ist zb. Geh deine Aufgabenstellung noch mal durch und achte darauf welche Hauptwörter drin vorkommen. Diese Hauptwörter sind erste Kandidatenm für die Objekte die du brauchen wirst. Wenn eines dieser Objekte komplex ist, dann überlege dir woraus sich dieses Objekt zusammensetzt. Die dabei benutzten Hauptwörter sind wiederum Kandidaten für Objekte. Ein Beispiel: Dein Freund und du wollen Schach spielen. Dazu schreibst du ein Pgm, dass euch dabei die Arbeit abnimmt. Es geht also nicht darum, dass das Pgm selbst Schach spielt sondern es soll nur die Züge entgegennehmen, eine Anzeige updaten, prüfen ob die Züge gültig sind, ev ein Protokoll ausdrucken, die Figuren bewegen. Kurz und gut: es soll das Schabrett simulieren. Also was haben wir: Brett das eigentliche Schachbrett Liste von Zügen die brauchen wir um das Protokoll drucken zu können einen Zug der auszuführende Zug. So ein Zug hat auch ein Eigenleben. Er besteht aus den Positionen von wo der Zug weggeht und wo der Zug hinführt. Ausserdem speichern wir noch welche Figur das war. Ergo haben wir noch Position Wie wird am Brett eine Position gekennzeichnet Figur Eine Auflistung aller möglichen Figuren Farbe Die Farbe der Figur Anzeige Dort wird der aktuelle Stand ausgegeben. Zugprüfer Das ist weniger offensichtlich aus der Beschreeibung von oben. Aber wenn wir einen Zug prüfen wollen, muss es auch eine Maschine geben, die dies tut. Spiel Dieses Objekt hält alles zusammen. Es nimmt Eingaben entgegen (könnte man auch in ein eigenes Objekt auslagern) und veranlasst, dass die Objekte zu arbeiten anfangen. Hab ich noch was vergessen? Möglich. Wir werden im Lauf der Zeit schon noch drauf kommen, was fehlt. OK. Welche Eigenschaften haben diese Einzelteile, woraus bestehen sie, welche Aufgaben haben sie? Brett: Das Brett ist eine Matrix. In jedem Schnittpunkt (also in jedem Feld) dieser Matrix kann eine Figur sein oder auch nicht. Was uns an dieser Stelle zb. überhaupt nicht interessiert ist, ist ob das Feld Weiss oder Schwarz ist. Für das Spiel an sich hat das überhaupt keine Bedeutung. Ob weiss oder schwarz ist etwas worum sich die Anzeige kümmern muss. Ansonsten muss das Brett nur einen Zug ausführen. Es tut dies indem die 'Figur' von einem Feld auf ein anderes Feld verschoben wird. Liste von Zügen: Dieses Teil hat administrativen Charakter. Ein Zug wird vom Benutzer über die Eingabe eingegeben und nach erfolgter Prüfung auf Gültigkeit der Zugliste übergeben. Die Zugliste speichert den Zug und veranlasst, dass er am Brett ausgeführt wird. Es mag aber auch spezielle Eingaben geben, die veranlassen, dass ein Zug zurückgenommen wird bzw. ein zurück- genommener Zug wieder ausgeführt wird. Dann läuft die Zugliste zu Höchstform auf: Sie kennt ja die vergangenen Züge und kann daher diese am Brett rückgängig machen. Natürlich manipuliert die Zugliste die Figuren am Brett nicht selbst. Wie kommt sie denn dazu. Aber die Zugliste kann das Brett anweisen einen Zug durchzuführen. Ein Zug: Das ist ein eher abstraktes Gebilde. Es ist eigentlich nur ein Datencontainer der aus 2 Positionen und einer Figur besteht. Die Bedeutung soll sein: Figur xy zieht von Feld ab nach Feld cd. Position: Wieder ein abstraktes Gebilde. Es speichert Brettkoordinaten und kann Auskunft darüber geben, ob die gespeicherte Brettkoordinate gültig ist. Figur: Eine einfache Auflistung, welche Figuren es gibt. Dazu kommt noch die Farbe der Figur Anzeige: Aufgabe der Anzeige ist es, das Brett und die Stellung der darauf befindlichen Figuren anzuzeigen. Dazu muss man der Anzeige natürlich das Brett zur Verfügung stellen. Zugprüfer: Aufgabe des Zugprüfers ist es, abzuklären ob ein bestimmter Zug in der momentanen Brettsituation möglich und gültig ist. Dazu braucht der Zugprüfer natürlich den zu untersuchenden Zug und das Brett (das ja die aktuelle Situation hält). Daraus folgt natürlich auch, dass es eine Möglichkeit geben muss, das Brett nach dem Inhalt von bestimmten Feldern zu befragen. Bleibt nur noch das Spiel. Seine Aufgabe ist es zb, die Benutzereingaben entgegenzunehmen, den Zug zusammen mit dem Brett dem Zugprüfer zu übergeben. Wenn der Zugprüfer sein ok gibt, dann wird der Zug der Zugliste übergeben, die ihn speichert. Danach wird besagter Zug dem Brett übergeben, das ihn ausführt und das geänderte Brett der Anzeige übergeben. Bei speziellen Eingaben (undo) wird die Zugliste um den letzten Zug befragt, der Zug auf rückgängig umgeformt und ebenfalls wieder dem Brett übergeben, dass dan brav den Zug rückgängig macht. Ha. Da haben wir schon den ersten Designfehler. Wenn ein Zug ausgeführt wird, dann kann es sein, dass eine Figur geschlagen wird. Diese Figur verlässt dann das Brett und taucht nicht mehr auf. Allerdings: Um den Zug rückgängig machen zu können, ist es daher notwendig, daß die geschlagene Figur beim Zug, in dem sie geschlagen wurde, zu speichern. Aber was solls. Fangen wir mal an: Wir haben ein Brett: class Brett { public: Figur Apply( Zug& zug ); Figur Piece( Position& pos ); void Init(); protected: Figur Inhalt[8][8]; }; Apply führt einen Zug aus und liefert die Figur die gschlagen wurde, wenn überhaupt. Piece liefert die Figur, die auf einem Feld steht. Init hingegen stellt die Figuren zum ersten mal auf. Also machen wir gleich mal weiter mit einer Position. Das ist leicht: class Position { public: Position( int z, int s ) : Zeile(z), Spalte(s) {} int Zeile; int Spalte; bool IsValid(); }; An dieser Stelle verlasse ich das Dogma ein klein wenig. Zeile und Spalte sind public Variablen. Eigentlich möchte man sowas nicht haben. Allerdings gibt es immer wieder solche Klassen, die eigentlich eher Datenhaltecharakter haben. Bei solchen Klassen verlasse ich auch schon mal das Dogma. To be continued ...
Was ist eine Figur? Nun eine Figur besteht aus 2 Informationen. Welcher Figurtyp und welche Farbe die Figur hat. enum FTyp = { Keine, Bauer, Turm, Laeufer, Springer, Dame, Koenig }; enum FFarbe = { weiss, schwarz }; class Figur { public: Figur( FTyp& t, FFarbe& f ) : Typ( t ), Farbe( f ) {} FTyp Typ; FFarbe Farbe; }; Damit ergibt sich aber auch sofort, wie ein Zug aussieht: class Zug { public: Zug( const Position& von, const Position& nach, Figur& f ); void WurdeGeschlagen( const Figur& f ); protected: Position Von; Position Nach; Figur ZugFigur; Figur Geschlagen; }; ..... Bitte erspar mir jetzt das weitere tippen. Das geht jetzt eine ganze Weile so dahin. Jede Klasse hat eine definierte Aufgabe. Jede Klasse kann sich dabei auch auf andere Klassen stützen. Zb. Wird die Ausgabefunktion der 'Anzeige' das Brett Feld für Feld durchgehen und die dort befindlichen Figuren abfragen. Je nach Figur wird dann die Ausgabe gemacht. zb. so void Anzeige::Show( const Brett& Aktuell ) { for( int Zeile = 0; Zeile < 8; ++Zeile ) for( int Spalte = 0; Spalte < 8; ++ Spalte ) { ShowFigur( Brett.Piece( Position( Zeile, Spalte ) ) ); } cout << endl; } } void Anzeige::ShowFigur( const Figur& f ) { if( Figur.Typ != Keine ) { if( Figur.Farbe == schwarz ) ShowFigurBlack( f ); else ShowFigurWhite( f ); } else cout << " "; } void Anzeige::ShowFigurBlack( const Figur& f ) { char Symbols[] = " btlsdk"; cout << Symbols[ f ]; } void Anzeige::ShowFigurWhite( const Figur& f ) { char Symbols[] = " BTLSDK"; cout << Symbols[ f ]; } Jede Funktion für sich ist trivial und leicht zu durchschauen. Und doch bilden sie ein Geflecht, so dass sie in der Spiel Klasse leicht zu verwenden ist: class Spiel { ... protected: Brett m_Brett; Anzeige m_Anzeige; Zugliste m_Zuege; Zugchecker m_Checker; }; bool Spiel::Do( const Position& von, const Position& nach ) { Figur wer = m_Brett.Piece( von ); Zug* pZug = new Zug( von, nach, wer ); if( m_Checker.IsValid( pZug ) ) { Figur Geschlagen = m_Brett.Apply( pZug ); pZug->Geschlagen = Geschlagen; m_Zuege.Add( pZug ); } else { delete pZug; return false; } m_Anzeige.Show( m_Brett ); return true; } Auch diese Funktion ist im Grunde schon selbsterklärend. Sie ist kurz genug um überschaubar zu bleiben und beim Durchlesen der Funktion offenbart sich relativ schnell was diese Funktion macht und wie sie es macht. Wichtig: Für verschíedene Dinge, macht sich die Funktion nicht selbst die Hände schmutzig, sondern delegiert. Die Abfrage welche Figur an der von-Position sitzt, die überlässt sie dem Brett. Ob ein Zug gültig ist oder nicht, das will diese Funktion vom Zugprüfer wissen. Diese Funktion führt auch den Zug nicht selbst aus; das wird wiederum an das Brett delegiert. Und schliesslich die Anzeige: Die wird wiederum an das Anzeige Objekt abgetreten. Möchte ich eine andere Form der Anzeige haben, sei es ein schönes graphisches Display oder vielleicht überhaupt ein reales Schachbrett an dem ein Roboter echte Figuren verschiebt: Dafür zuständig ist das Anzeige Objekt. Das kann ich jederzeit gegen ein anderes tauschen. Das kümmert zb. den Zugprüfer oder die Zugliste überhaupt nicht. Daher kann auch eine Änderung im Anzeigeobjekt die Zugprüfung nicht beeinflussen bzw. mir dort einen Fehler hineinhauen.
> Aber die Zugliste kann das Brett anweisen einen > Zug durchzuführen. Das ist überhaupt auch einer der Knackpunkte in der Progammierung. Bei jedem Ding, jeder Aktion die durchgeführt werden soll, muss man sich fragen, ob der Programmteil (das Modul, das Objekt) überhaupt dafür zuständig ist. In dem Zusammenhang ist eine 'Beamtenmentalität' (nicht abwertend gemeint) von Vorteil: "Das fällt nicht in meinen Aufgabenbereich, dazu gibt es einen der dafür zuständig ist." Wenn du also ein Auto simulierst und auf Knopfdruck soll das Simulierte Seitenfenster aufgehen, so führt nicht das Auto diese Aktion aus. Das Auto nimmt nur vom Benutzer den Wunsch entgegen, dass das Fenster aufgehen soll. Aber es delegiert sofort: Da es sich um das Fahrerfenster handelt, wird der Wunsch sofort an das Subobjekt 'Fahrertür', das ein Mitglied des Autos ist, weitergerecht. Auch die Tür veranlasst nicht direkt, dass sich der Servomotor in Bewegung setzt. Die Tür delegiert sofort an das Subsystem 'Fenster', welches wiederrum diesen Wunsch an den Servomotor weiterreicht, der dann endlich, je nach Öffnen oder Schliessen entscheidet in welche Richtung er sich drhen soll und ob die Endlage schon erreicht ist. Was sich auch bewährt hat ist, die einzelnen Objekte als 'kleine Mitarbeiter' anzusehen und dementsprechend sind Funktionsaufrufe einfach Befehle an diese Objekte etwas zu tun. Das ist wie bei der Bundeswehr: Der Garnisonskommandant wendet sich an seinen Kompaniekommandaten, dass der Müllplatz gereinigt werden muss. Der Kompaniekommandant gibt diesen Befehl weiter an seinen Spiess: "Um 9 Uhr ist der Müllplatz zu reinigen". Der beauftragt seinen Schreiber das dazu nötige Werkzeug zu organsisieren. Mit diesem Werkzeug wartet der Spiess bis 8.45 Uhr und sucht sich dann vielleicht einen Zugskommandanten heraus, desen Zug die Aktion durchführen soll. Dem übergibt er das Werkzeug und den Befehl die Reinigung mit diesem Werkzeug durchzuführen. Der Zugskommandant seinerseits macht das natürlich nicht selbst, sondern holt sich wiederrum einen armen Teufel, der den Befehl erhält: Mit diesem Besen ist sofort der Müllplatz zu reinigen. Und erst der führt dann die eigentliche Aktion durch. In jeder Hierarchiestufe, die der Befehl von oben bis unten durchläuft, sind zusätzliche Informationen hinzu oder auch weggekommen. Der arme Teufel muss ein Uhr nicht ablesen können. Das Timing ist schon ein paar Ebenen weiter oben gemacht worden. Dafür hat sich der Garnisonskommandant nicht darum zu kümmern mit welchem Werkzeug der Befehl umgesetzt wird, das weiss wiederrum der Spiess-Schreiber.
Passt, wie ich finde, zum Thema und interessiert vielleicht den Einen oder Anderen: http://se-radio.net/ @oimelx > Häufig ist es jedoch trotzdem so, dass sich Anforderungen während der > Programmierung, oder nach Fertigstellung ändern. Gerade im Bereich der > kaufmännischen Software ist dies "normal". Das "kaufmännisch" ist da über, das kannst Du streichen. ;-))
@kbucheg: toll beschrieben... solltest vllt. ein Wiki dafuer hier auf der Seite eroeffnen ich hab mir das nicht alles durchgelesen... Aber die Frage mit dem "Wie teste ich das am besten" laesst sich ganz einfach mit dem neumodischen Begriff "extreme programming" beantworten. Dazu gibt es einige wikis. Sinn der ganzen Sache ist es fuer alles eine Testklasse zu schreiben ;)
Bei all euren sicherlich gut gemeinten Bespielen solltet ihr verstärkt darauf achten, nicht einfach das Beispiel den Erfordernissen der Explikation anzupassen, da iehr sonst Gefahr lauft, in komplett bizarren Szenrarien zu versinken: Das Auto mag vielleicht noch die übergeordnete Struktur für Fenster und Fensterheber darstellen und "Wünsche des Fahrers" entgegen nehmen, aber was soll man mit einem Beipiel anfangen, bei dem das Fenste Wünsche an den Heber weiterleitet? Das sehe ich z.B. genau umgekehrt: Der Heber ist die höhere Ordnung gegenüber der Scheibe - umfassende Struktur wäre die Türe! Wunschweiterleiter wäre auch nicht das Auto, sondern die Boardelektronik. Wenn, dann bitte sinniger.
> Wenn, dann bitte sinniger.
Der springende Punkt ist: Eine Objekthierarchie macht in einem
bestimmten Kontext Sinn. In einem anderen mag sie komplett
sinnlos sein. Dementsprechend gibt es kein "one size fits
all" Lösung.
Wenn es für deine Simulation Sinn macht, die Elektrik mitzu-
simulieren, dann sei es so. Für meine Simulation, die ich im
Kopf hatte, machte es keinen Sinn, also lies ich sie weg.
Hallo, > class Brett > { > public: > Figur Apply( Zug& zug ); > Figur Piece( Position& pos ); > void Init(); > > protected: > Figur Inhalt[8][8]; > }; Also Du hast ein 8 mal 8 Array mit Figuren, wobei eine Figur auch vom Typ "keine" sein kann. Das finde ich jetzt interessant, weil ich das anders gemacht hätte. Ich hätte gesagt dass eine Figur eine Position hat. Und im Brett hätte ich eine "std::list<Figur> Figuren;" deklariert. Vielleicht laufe ich, mit dieser Liste, in eine Sackgasse. Kannst Du mir sagen was die Vor- und Nachteile dieser beiden Möglichkeiten ist? Gruß, Feadi
War mehr so eine Bauchentscheidung. Bei der gewählten Aufgabenstellung ist das rechenintensivste sicherlich das Abklären ob ein Zug überhaupt möglich ist. Dazu müssen aber ständig Linien und Diagonalen am Brett abgeklärt werden. Daher möchte ich eine einfache Möglichkeit haben, dies auch zu tun. Und etwas einfacheres als das Spielfeld im Rechner durch ein 2D Array abzubilden, ist mir auf die Schnelle nicht eingefallen :-) (*) Würde man das mit einer Figurenliste machen, müsste man für jede Position jedesmal die Liste abklappern, ob es für eine gegebene Position eine Figur an dieser Position gibt. Im Vergleich dazu ist das ständige updaten der Matrix ein verschwindendes Problem. Die Fragestellung die in diesem Pgm die häufigere sein wird ist doch: An einer bestimmten Position: steht da eine Figur und wenn ja, welche? Die Frage, die deine Liste besser beantworten könnte, würde lauten: Wo steht eine bestimmte Figur? Nur, diese Fragestellung kommt in der gewählten Aufgabenstellung nicht vor.
>> Aber die Zugliste kann das Brett anweisen einen >> Zug durchzuführen. > Das ist überhaupt auch einer der Knackpunkte in der > Progammierung. Bei jedem Ding, jeder Aktion die durchgeführt > werden soll, muss man sich fragen, ob der Programmteil > (das Modul, das Objekt) überhaupt dafür zuständig ist. > In dem Zusammenhang ist eine 'Beamtenmentalität' > (nicht abwertend gemeint) von Vorteil: "Das fällt > nicht in meinen Aufgabenbereich, dazu gibt es einen > der dafür zuständig ist." Dazu vielleicht noch ein bischen 'Geheimdienstmentalität'? Also: "Wer muss das wissen?", "Wer braucht das nicht wissen?". Da fällt mir ein: Wenn ich sagen eine Figur hat eine Position, dann kennt die Figur ihre Position, aber ich glaube sie braucht das garnicht. Man könnte also sagen: Das Brett muss wissen wo welche Figur steht. Ich glaube diese Überlegungen gehen in die richtige Richtung, oder? Gruß, Feadi
> Ich glaube diese Überlegungen gehen in die richtige Richtung, oder? Absolut. > Da fällt mir ein: Wenn ich sagen eine Figur hat eine Position, dann > kennt die Figur ihre Position, aber ich glaube sie braucht das garnicht. > Man könnte also sagen: Das Brett muss wissen wo welche Figur steht. Grundsätzlich richtig. Das nenne ich mal das 'Datenbank-Prinzip': Speichere jede Information nur einmal. Allerdings wird dieses Prinzip zähneknirschend auch schon mal über Bord geworfen. Denn die Frage die sich als nächstes stellt, ist: Wie lange dauert es, bis das Brett eine bestimmte Figur auf dem Brett gefunden hat(*). Sieh also die Positionsangabe bei einer Figur als eine Art Cache an. Ja, ja, ich weiss schon: preamture optimization is the root of all evil :-) (*) Ist in der gewählten Aufgabenstellung sicherlich kein Thema. Aber eine schöne Begründung.
Mir helfen solche Sätze wie dieser hier sehr viel:
> 'Datenbank-Prinzip': Speichere jede Information nur einmal.
Ich fände es sehr schön, würden davon noch einige zusammenkommen.
Noch eine Frage: Wie macht man das Interface am besten, wenn ein Objekt
ein Ereigniss erzeugt, und ein anderes Objekt dieses Ereigniss behandeln
soll?
Ich kenne z.B. das hier:
1 | class maschine |
2 | {
|
3 | public:
|
4 | class handler |
5 | {
|
6 | public:
|
7 | virtual void ereigniss() = 0; |
8 | };
|
9 | |
10 | private:
|
11 | handler *h; |
12 | |
13 | public:
|
14 | void registerHandler( handler *x ) |
15 | {
|
16 | h = x; |
17 | }
|
18 | |
19 | void erzeugeEreigniss() |
20 | {
|
21 | h->ereigniss(); |
22 | }
|
23 | };
|
24 | |
25 | class EreignissSenke : public maschine::handler |
26 | {
|
27 | public:
|
28 | void ereigniss() |
29 | {
|
30 | // mach etwas...
|
31 | }
|
32 | };
|
Aber da muss es doch was besseres geben, oder? Gruß, Feadi
> Aber da muss es doch was besseres geben, oder?
Wenn ich da mal so schnell drüber schaue, dann ist
das doch das 'Observer Pattern'. In einer etwas
vereinfachten Form. Ein volles Observer-Pattern
würde beliebig viele Beobachter zulassen, aber
darum geht es nicht. Die Grundprinzipien eines
Observers sind alle da.
Was besseres: Nein, das wird tatsächlich so gemacht.
OK. Man könnte mit Basisklassen etwas auslagern, aber
hey: der Observer den du da hast, der ist doch noch
nicht kompliziert.
Wenn dich solche Dinge interessieren, dann empfehle
ich dir:
Design Patterns
Elements of Reusable Object-Oriented Software
Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides
Das Buch ist auch bekannt als "Gang of 4" oder kurz der "Go4".
Ich habe sehr lange überlegt, bis ich diesen Code da oben hatte. Hätte ich gewusst dass es ein Buch über sowas gibt... ;) Das Buch werde ich mir sofort kaufen, vielen Dank für den Tip. Gruß, Feadi
Also allgemein ist das IT-Management leider nicht in der Lage grundsätzliche Management Prinzipien umzusetzen (warum auch immer), als da wären: http://de.wikipedia.org/wiki/Lastenheft und daraus abgeleitet dann: http://de.wikipedia.org/wiki/Pflichtenheft Egal was für ein Projekt ansteht, es müssen vor allem auch Termine und Prüfkriterien definiert und eingehalten werden. Das ganze Thema hat nichts mit Programmierung oder Software-Design zu tun, sondern ausschließlcih mit Management. Das wird leider grundsätzlich übersehen :( Nehmne wir als Beispiel ein Verwaltungsprogramm für eine große Bibliothek. Das erstes was gemacht werden muß ist nicht mal schnell einen Prototypen in C++ zu entwickeln, sondern ganz im Gegenteil zu sehen wer wird später das System pflegen müssen und wie ist die aktuelle Arbeitsweise. Es nützt schließlich nix, wenn zwar eine superperformante parallel und objektorientierte Software in "Schlagmichtot" programmiert wurde, wenn die Personen die später damit umgehen müssen außen vor bleiben. Statt dessen ist es immer effizienter, die vorhandenen Strukturen zu analysieren und entsprechend nachzubauen. Dann verringert sich die Einarbeitungszeit der Leute die es benutzen müssen und wenn man intelligenterweise eine Abstraktionsebene einbaut, läßt sich das schnell ändern ;) Für die Verwaltung von größeren Software-Projekten hat sich CVS bewährt, eine Verwaltungssoftware, die Änderungen im Code verwaltet und pflegt. Wenn mehrere Leute an einem Projekt arbeiten ist es zudem sehr sinnvoll, jeder Person einen einzigen Part des Gesamtprojekts zuzuorden inklusive einem weiteren Part als Ersatz/Helfer. Z.B. eine Resource bearbeitet die Bedienoberfläche und ist gleichzeitig in die Schnittstelle zwischen Oberfläche und eigentlicher Bibliotheksverwaltung involviert. Eine andere Person übernimmt das Design der Datenbank für die Bibliothek und ist gleichzeitig in die Schnittstelle zwischen Verwaltungsprogramm und Datenbank involviert. usw. usw. usw. Vor allem muß immer darauf geachtet werden, das das Projekt passende Granularitäten aufweist, um klare Bezüge abgrenzen zu können. Das gilt sowohl für das Programm selbst, als auch für die Personen die es umsetzen. Ich hoffe mal es richtig erklärt zu haben ;)
Was ist das für eine Software an der man 20 Jahre Arbeitet. Wie heißt die?
> Was ist das für eine Software an der man 20 Jahre Arbeitet. > Wie heißt die? ...aktuell: "Vista" SCNR
Neugier wrote: > Was ist das für eine Software an der man 20 Jahre Arbeitet. > Wie heißt die? Die kriegst du so nicht zu kaufen:-) Es geht um einen Bereich, der sich 'Innenraum-Visualisierung' nennt. Los geht es mit der ganz einfachen Fragestellung: Wenn ich meinen Raum so und so einrichte, wie sieht nachher das Ergebnis aus. Also das was du auch von diversen, zur Zeit im Fernsehen in Mode gekommenen Heimwerkershows, kennst. Aber das Ganze geht ja dann weiter. Eine der Gretchenfragen lautet ja: Was kostet mich der ganze Spass? Eine andere: Wo kriege ich aktuelle firmenspezifische Daten her? Eine ganz andere Fragestellung lautet: Wenn ich komplizierte Teile aufbauen muss, muss ich dann wirklich alles ganz von alleine machen, oder kann mir der Rechner nicht dabei helfen. Ich zeige ihm wo mein WC und mein Waschbecken hin soll, und er konstruiert das Vorwand-Tragwerk ganz von alleine. Und zwar so, dass alles hält und ich trotzdem noch die richtige Neigung beim Fäkalrohr in der Wand habe. Dann hätte ich davon ganz gerne eine komplette Stückliste bis runter zur letzten Schraube und wenn der Rechner für den Monteur vor Ort noch ganz alleine eine Montageanleitung generieren könnte, wärs auch nicht schlecht. Oder: Ich möchte in meinen Innenraum eine Heizung einbauen. Welche Heizkörper brauche ich, wie sehen die Heizkreisläufe aus? Reicht die Heizleistung? Welche Teile muss ich in der Zentrale bestellen? Sind die lieferbar? Oder: In einer Produktionshalle liegen die Versorgungsstränge für Wasser, gas etc. normalerweise an der Decke. Die sind dort an Konsolen montiert. Nur: Wie müssen diese Konsolen dimensioniert werden? In welchen Manschetten muss ich die Rohre führen, so dass die Ausdehnung auch abgefangen werden kann? Am liebsten wäre mir, ich zeige dem Rechner nur wie ich die Konsole an die Wand schrauben möchte, wie mein Rohrbündel aussieht und um die ganze Befestigungstechnik, so dass das Zeugs nicht runter kommt und die Manschetten auch alle halten, soll sich der Rechner kümmern. Ach ja: Das Ganze soll natürlich voll parametriesiert sein, denn für Ergänzungen im Konsolen, Schrauben, Träger, Manschettensortiment will ich nicht immer den Entwickler benötigen. Und, und, und. Das Grundkonzept ist: Lego spielen im Rechner. Aus vorgefertigten 3D-Bausteinen (sagte ich schon, dass wir uns im 3D bewegen?) wird eine Szenerie zusammengestellt. Jetzt kann man eine Menge Spezialfunktionalität im Bereich Konstruktion unterbringen. Man kann aber auch eine Menge Spezialfunktionalität hinten dran setzen um spezeille Auswertungen zu fahren. Und das Ganze nach Möglichkeit so, dass auch Lieschen Müller mit der Software zurechtkommt. Und so gehen die Jahre ins Land.
Sind in eurer Anwendung auch Bibliotheksmodule Oder ist alles aus euer Entwicklung. Ich denke da so an Daten-Schnittstellen usw. Ich meine Ihr bewegt euch im Cadbereich und müsst wahrscheinlich Modellierwerkzeuge zur Verfügung stellen . Verwendet ihr auch sogenannte Cadkernel wie Parasolid oder andere?
Das meiste ist von uns. Modellierwerkzeuge haben wir vor einiger Zeit aufgegeben. Das lohnt nicht mehr. SolidEdge kannst du auch mit der besten Entwicklungsmannschaft preislich nicht schlagen. Geometriekern ist von mir (war von mir. Ich bin vor einem Jahr aus der Truppe ausgestiegen :-) Dementsprechend sind auch die Kern-Fileformate alle von uns. Der notwendigen Geometrie Import anderer Formate, wird dir dann sowieso vom Markt aufgezwungen. http://www.gascad.at
Kaum vorstellbar das da 1.8 Millionen Zeilen drinn stecken sollen. Ich habe eine Software geschrieben mit über 100000 Zeilen, auch im 3D Cadbereich (mit komplizierten Algorithmen). Hat 3 Jahre gedauert. Allerdings bin ich kein Objekt-Programmierer. Ich nutzte alles durcheinander von c bis c++. Standards oder ändere nette Sachen interessieren mich nicht. Ich dokumentiere meinen Programmcode nicht mal, keine Kommentare, nichts. Meine Arbeitsweise ist zugegebenermaßen sehr eigenwillig und auch nicht Teamfähig, da Niemand anders außer mir den Code wegen fehlender Dokumentation entschlüsseln kann. Ich nutzte auch kaum Test-Funktionen oder ähnliches. Trotzdem läuft meine Applikation absturzfrei. Das Einzige was ich konsequent durchziehe ist: das ich Pointer immer mit Null initialisiere und wann immer ich sie benutze auf Null teste, sofern es notwendig erscheint. Für den Außenstehende mag das alles wie Kaos aussehen, aber jeder Mensch programmiert so wie er denkt. Die Masse der Menschen brauchen die Objektorientierung um sich zurecht zu finden. Bei mir ist das genau umgekehrt. Was nicht heiß das ich Sie nicht nutze wenn es Sinn macht. Natürlich mache ich mir auch über die Programmstruktur Gedanken und weiß oft auch am Anfang ziemlich genau wie es sein muss. Meine persönliche Meinung ist , wenn ich konsequente Objektorientierung anwenden würde, wäre ich mindestens um den Faktor 2 langsamer. Ich hätte statt 3 6 Jahre gebraucht. Meine Kunden bekommen eine Anwendung die nicht schlechter und nicht besser ist wie eine Anwendung die konsequent mit Objektorientierung geschrieben ist.
> wenn ich konsequente Objektorientierung > anwenden würde, wäre ich mindestens um den Faktor 2 langsamer Das halt ich, mit Verlaub, für ein Gerücht.
Ohje, Code ohne Kommentar. Der Tot für jedes Projekt! Wenn mir jemand solche Software abliefert, wird sie aus Prinzip nicht abgenommen. Denn Was Passiert wenn Du ausfällst? Dann hätte ich Code den niemand weiter pflegen kann. Das bedeutet alles neu schreiben. Nein Danke!
"Das halt ich, mit Verlaub, für ein Gerücht." Das kann jeder halten wie er will, aber ich bin jedenfalls schon fertig wenn du noch deine Klassenstruktur planst. Objektorientierung ist für Rapidentwicklung nicht zu gebrauchen. Ein Fehler in der Anfangs-Planung und man muss alles umbauen. Objektorientierung wende ich da an wo es wirklich Sinn macht. Sonst kommt C-Stile zum Einsatz. Besonders bei zeitkritischen Funktionen verwende ich keine Objektorientierung. Man sagt „Objektorientierung ist unbedingt notwendig bei größeren Projekten“, das ist quatsch. Früher wurden auch große Projekte bewältig z.B. noch mit Assembler. Mann sollte sich nicht zu sehr an Schemata binden wenn man vorankommen will. Das ist eigentlich meine Kernaussage. "Wenn mir jemand solche Software abliefert, wird sie aus Prinzip nicht abgenommen. Denn Was Passiert wenn Du ausfällst?" Ja, ich sagte ja das ist kein Teamprojekt .Wenn ich ausfalle gibt auch die Software nicht mehr. Der Code wird auch nicht ausgeliefert . Der Kunde bekommt nur das Endprodukt . Ich behaupte mal das ich damit aber um den Faktor 3 schneller entwickle. Der Umstand das mein Code keine Kommentare hat bringt noch andere Vorteile mit sich. Das ist wie mit den Merkzettel, wenn man sich die Notiz aufgeschrieben hat, darf man sie vergessen. Ich bin daher gezwungen das Gedächniss ein wenig zu schulen.Wenn ich wissen will, was mein Code macht, muss ich mir das merken oder eben die Abläufe entschlüsseln. Insgesamt finde ich mich dadurch aber schneller zurecht. Man weiß sehr genau wo im Code sich was befindet und man merkt sich mit der Zeit auch die Funktionsweise der einzelnen Abläufe und Algorithmen.
Ich weiss. Ich dachte auch einmal, ich wäre der Grösste, weil ich ich die 30 oder 40-tausend Codezeilen auswendig konnte und von jedem beliebigen 5 Zeilen Fragement genau sagen konnte wo es herkommt und was es dort bewirkt. Da muessen wir alle durch :-) Irgendwann begreift es jeder, dass das Teure an Software weniger die Erstentwicklung ist, sondern die laufenden Änderungen und Ergänzungen und Änderungen die aufgrund von Ergänzungen notwendig sind.
Ich meinte aber nicht nur 40.000 ich meinte 100.000. Ich habe deinen Werdegang längst hinter mir . Bei mir geht Wartung,Ergänzungen überraschend schnell. Ist zumindest die Meinung meiner Kunden. Und teuer ist das bei mir schon gar nicht (weil das kostet mich keine Zeit).
Nur 100.000? Also ich habe 3 größere Programme mit je. 250.000 Zeilen unkommentiert geschrieben und alles im Kopf. Das machen meine Kollegen auch so, mit 100.000 brauchst du hier gar nicht anfangen
Neugier wrote:
> Ich habe deinen Werdegang längst hinter mir .
Guter Witz.
Es ist wohl eher so, dass ich das fröhliche Draufloshacken
schon längst aufgegeben habe. Für meine eigenen, privaten
Dinge, macht es noch Spass einfach draufloszutippen.
Im Büro herrschen allerdings andere Prioritäten.
Dumme Fehler, die beim Testen unentdeckt bleiben sind
einfach zu teuer, wenn sie erst mal an die Endkunden
ausgeliefert sind.
Ausserdem: Wer sagt, dass sich Rapid Prototyping und OO
beissen? Ganz im Gegenteil: OO ist ein hervorragendes
Werkzeug um damit Rapid Protoyping zu betreiben. Das
ist ja gerade der Witz an der Sache, dass die Klassenstruktur
nicht von vorne herein 100% richtig sein muss. Du brauchst
nur eine Arbeitsversion und genauso wie du im Lauf der Zeit
draufkommst, ob deine struct vernünftig sind, so stellt sich
auch bei OO im Lauf der Zeit heraus, ob die Klassenstruktur
vernünftig ist oder nicht. Ist man allerdings nur ein klein
wenig diszipliniert an die Sache rangegangen, so ist es ein
leichtes die Klassenstruktur zu ändern ohne dass gleich alles
zusammenbricht. Ein wesentlicher Vorteil: Man akzeptiert so
wesentlich seltener Krücken, nur weil man sonst quer durch den
Code eine Änderung durchziehen müsste. Bei OO ist die Änderung
eher in einem kleinen Codeteil gekapselt.
Mein derzeitiges Projekt (3er Team): -zur Zeit 2 Mio Zeilen -Programmiersprache ist Java -zur Planung komme ich noch -Der Zeitplan wird (bisher) eingehalten Planung: Es wurde definiert, was rauskommen soll. Dann wurde die Architektur definiert und gebaut (ein Transaktionsframework, ein Eventframework, Hibernate gabs zum Glück schon :-)). Dann wurden das Ergebnis der Analyse in UML-Diagrammen festgehalten, und das Design wurde hinzugefügt. Das Ganze dann mit Hilfe eines Generators in Quellcode transformiert. Diesen Quellcode erweitert, Generator angepasst, Design angepasst. Zur Zeit funktioniert das schon gut. Offiziell sind wir ein agiles Team, d.h. wir bauen alle 3 Wochen einen funktionierenden Prototypen und zeigen den den Anwendern. Die Änderungswünsche werden dann beim nächsten Prototypen berücksichtigt.
Hallo, das Buch ist angekommen. Es macht einen sehr guten Eindruck, vorallem Kapitel 2 weckt Interesse: "A Case Study: Designing a Document Editor". Gruß, Feadi
ich habe in python standalone application geschrieben mit sehr bescheidenen 3000 loc da allerdings abstraktionsgrad sehr viel höher als in C++ und noch viel höher als in C ist, kann man ziemlich viel an logik da reinpacken und entsprechend auch verwalten. ich finde grade python für prototyping ideal um die idee auszutesten, grundzüge eines algorithmuses ausprobieren etc man kann danach nicht die arhitektur 1 zu 1 übernehmen, weil nun mal OO sich unterscheidet, aber dafür plage ich mich erstmal nicht mit container, mit new/delete, mit regex und das entscheidende ist ... wenn man erkennt das die struktur so nicht ganz richtig ist .. wenn man information die ein objekt trägt woanders verlagern will, dann ist das meist in 10 zeilen gemacht ich hab die erfahrung gemacht, dass die logische struktur vom programm in C und C++ gut zum ausdruck gebracht werden kann, aber das lästige kleinkram wie stringoperationen, umkonvertierungen, regex viel zu viel raum beanspruchen und logische struktur letztendlich begraben können wenn man aber soweit ein funktionieredes konzept hat wird man besser zurecht kommen @neugier mir kann keiner erzählen dass dein adhoc programmiertes kode so leicht erweiterbar ist wie du es schilderst es würde ja voraussetzen, dass du alle zukünftigen änderungen kennst und in der einen oder anderen form darauf hinprogrammierst es kann viel zu schnell passieren, dass eine änderung dein ganzes konzept durcheinanderwirft das ist so wie mit algorithmen .. eine kleine nebenbedingung weglassen und schon haben wir NP schweres problem grüsse
Hallo Pythonprogrammierer, Mein Programm wird ständig erweitert .Probleme gibt es keine. Aber wenn du dir nichts erzählen lässt, dann mache ich das auch nicht. Wobei, für mich ist Pyhton-proggen bestenfalls "Rumscripten für Anfänger" .Als "Programmieren" bezeichne ich das nicht.
> Wobei, für mich ist Pyhton-proggen bestenfalls "Rumscripten für > Anfänger" .Als "Programmieren" bezeichne ich das nicht. Ach, da lachen ja die Hühner. Kannst du das vielleicht näher begründen ?
Ach spring doch nicht drauf an. Lass ihn einfach. Wer von sich denkt, dass er der Größte ist, weil er hunderttausend LOC im Kopf hat und deswegen nicht kommentiert, dessen Horizont hört einfach am eigenen Tellerrand auf. Wer nicht soweit denkt, dass morgen jemand anderes auf diesen Code starren können müsste, wird früher oder später eine Bauchlandung machen. Garantiert.
Aber schau doch, ich bin nicht der Einziege der das so macht. Und ob ich früher oder später eine "Bauchlandung" mache, dass bleibt wohl ein Wusch deiner Phantasie. Wenn du zu denen gehörst,die ihre 3 Zeilen Pythoncode dokumentieren müssen, dann kannst du das eh nicht verstehen.
Es geht ja auch nicht gegen dich und die Probleme wirst auch nachweislich nicht du bekommen, sondern ein potentieller Nachfolger, denen es einen Heidenspass machen wird durch deinen Code zu wühlen. Insofern war meine obige Behauptung natürlich Quatsch. Dein Arbeit-/Auftraggeber wird damit langfristig besondere Freude habe oder willst du dich unabdingbar machen. Auch ein Plan, muss man sagen. Mach was du willst. Ich würde mich bei deinen Programmen aber einigen der Vorredner anschliessen und diese kategorisch ablehnen.
@Neugier warum wehrst du dich denn so verzweifelt gegen Struktur und Dokumentation? Schlussendlich klingt bei deiner Argumentation für mich da nur durch, daß du ein heilloser Chaot bist, der sich irgendwie durchs (Programmier) Leben wurschtelt. In der Selbstbetrachtung (Selbsteinschätzung) sehen Dinge immer besser aus als in der Fremdbetrachtung. Deine Argumente klingen ähnlich wie die von (alkohol-, nikotin-, ess-, drogen-) süchtigen, die haben auch alle möglichen schadenfeinigen Gründe bei Hand, zu erklären, warum ihr Verhalten "doch gar nicht so schlimm ist". Sie erkennen es einfach nicht, weil sie in ihrem eigenen Erfahrungshorizont gefangen sind und da ähnlich wie aus einem schwarzen Loch aus dem Ereignisshorizont und ihren gewohnten Verhaltensweisen gar nicht heraus kommen (wollen). Manchmal ist der Weg das Ziel. Oder um es hier auf Programmiererei abzubilden: Der Algorithmus (die Grundidee) (d)eines Programms steckt in der Dokumentation und Verfahrensbeschreibung, und nicht im "if" oder "brnz" Statement.
Das hat ja Ausmaße angenommen lol Also jede "gute" Programmiersprache bietet passende Strukturen für Fehlerbehandlung und wenn's ein ASSERT Skript ist ! In JAVA und C++ sind die Exceptions zu bevorzugen, die dann jeweils mit dem gutem try ausprobiert werden. In "gewachsenen" Programmen muß man leider zu unschönen Mitteln wir explizite Abfragen vor jeder Änderung greifen :( Also z.B.
1 | int irgendeinevariable; // steht irgendwo in irgend einem Header |
2 | |
3 | void tuewas(int eingabevariable) |
4 | {
|
5 | if(eingabevariable == NULL || irgendeinevariable == NULL) |
6 | return; |
7 | |
8 | // Rechne irgendwas mit den Vars aus
|
9 | |
10 | }
|
Der Vorteil von objektorientierter Programmierung liegt in der einfachen Erweiterbarkeit des bereits laufenden Codes, denn ich muß ja nicht's umschreiben, sondern kann einfach das Objekt erben und erweitern. Auch was Threadprogrammierung betrifft haben einzelne Objekte gewisse Vorteile gegenüber z.B. C-Funktionen. Und eine ordentliche Dokumentation sollte von Anfang an in der Planung mit drin sein ! Damit sind nicht nur sinnvolle Namensgebungen innerhalb des Programms und erklärende Kommentare gemeint, sondern eine komplette Beschreibung außerhalb des Programmkontextes. Eben ein Pflichtenheft, welches aus dem Lastenheft hervorgehen sollte. JAVA bietet was die Dokumentation und verknüpfung des Source-Codes angeht ein mächtiges Werkzeug. Allerdings macht eine Übersicht der einzelnen Objekte mit Funkitonen und Abhängigkeiten eine erklärende Dokumentation, die auch für NICHT-Programmierer lesbar und verstehbar ist NICHT unnötig ! Das verstehen die meisten Leute in der IT-Planung und vor allem die Programmierer nicht. Ein von Anfang an gut durchgeplantes Softwareprojekt hat schon Schnittstellendefinitionen und Ausstiegspunkte definiert, bevor die erste Zeile Programm geschrieben wurde. Quickhacks neigen dazu schnell unübersichtlich zu werden und enden dann in Frickelwerk, das niemand mehr wirklich verstehen kann und wo sich unbemerkt Race-Conditions oder schlimmeres einschleichen, die dann Dinge bewirken die sich niemand erklären kann ! Das habe ich gerade bei meinem kleinen Hobbyprojekt bemerkt, das ich einfach inne Tonne trete und mit Planung von vorne anfangen werde ! Das hat klein angefangen und wurde dann kontinuierlich erweitert, bis es irgendwann einfach geklemmt hat und ich beim besten Willen nicht feststellen konnte wo und warum :( Und was Skriptsprachen angeht, so sind die den compilierten Sprachen kaum "unterlegen" ! Gutes Beispiel ist PHP ;) Damit läßt sich sogar objektorientiert arbeiten und es wird weltweit auch bei First-TIERs eingesetzt ;) Mein Grundtenor bleibt in diesem Bereich aber immer der selbe: - Gutes IT-Management muß vorhanden sein !
Ah Wegstaben Verbuchsler, du bist hier ja der Schnacker vom Dienst. Solche Lokus-Weißheiten habe ich ja noch nie gehört. Ich wette du studierst gerade das Buch „c++ für dummies“ und verkündest jetzt deine angelesenen Weißheiten. Hallo ITler (Gast) "Programmierst du schon? oder planst du noch?" Planung mach ich nicht zweimal und das ich ein ganzes Projekt verwerfen muss passiert mit heute nicht mehr. Klar kann man das auch wissenschaftlich aufziehen mit tausend Dokumentationen und Pflichtenheften, vielleicht auch noch ein Buch schreiben und dabei in der Nase popeln . Am Ende hast du dann aber nur 3 Zeilen Code fertig und deine schöne Sourcecode Dokumentaion kauft dir dein Kunde nicht ab. Das kannst du mir schon glauben, die braucht und bezahlt kein Mensch.
@Neugier jaja, die Wahrheit tut weh und wird nicht gerne eingesehen. Welche meiner Sprüche hat dich persönlich am meisten betroffen gemacht, weil du dich darin wieder gefunden hast?
@Neugier um auf deine Frage zu kommen was ich so grade mache: Nö, ich lese kein c++ Buch. Ich arbeite (seit 10 Jahren) in der Qualitätssicherung, typischerweise Telekommunikationsunternehmen, und bin als Testleiter für die Einführung und Weiterentwicklung von Programmpaketen mit mehreren Mio Codezeilen in ziemlich verwegenen heterogenen Umgebungen verantwortlich. Das sind teilweise angepasste Standardpakete wie Bsp SAP (ca. 70% Basisfunktion, ca. 30% kundenspezifisch), und teilweise komplett kundenspezifische Anwendungspakete. Als Programmiersprachen wird alels mögliche verwendet, aber das ist ziemlich "egal" in welcher Sprache was geschrieben ist, sofern es dokumentiert ist. Solche komplexen Anforderungen lassen sich naturgemäß ausschließlich über strukturierte Vorgehensweisen abbilden. da ist tatsächlich 1 Zeile "Doku" (*1) wesentlich mehr wert als 1 Zeile Code. Tatsächlich ist das Verhältnis deutlich "Doku-Lastig" (*1) Doku ist alles außer Code wie z.B. Lastenhefte, Pflichtenhefte, Benutzerhandbücher, Schnittstellen- und Modulspezifikation etc. Für kleine (und auch möglicherweise große) Frickelsprojekte für einen Einzelkämpfer wie dich mag das befremdlich klingen, daßauf 1 Zeile Code 10 Zeilen Doku kommen, aber es ist in einer derartigen Umgebung das einzig mögliche, um noch irgendwie in dem alltäglichen Wahnsinn der Steuerung von hunderten Programmierern wie dich einigermaßen zurecht zu kommen.
@Neugier: > ... und das ich ein ganzes Projekt verwerfen muss > passiert mit heute nicht mehr. Hört sich an als hättest Du aus Erfahrung gelert. Bitte verrate die Details warum Du früher ganze Projekte verwerfen musstest? Und warum heute nicht mehr? Wie strukturierst Du Deine Programme? Kannst Du ein paar Beispiele geben, bitte? Gruß, Feadi
Ihr wollt doch jetzt nicht aufhören? :-) Das ist wirklich ein sehr interessanter Thread. Zuerst fragt Feadi eine ziemlich naive Frage (nicht böse gemeint), deren Antwort eigentlich ein Studium füllt! Aber es finden sich Leute, die mit unglaublicher Geduld die Kunst des Softwareentwurfs schildern. Und dann prallen auch noch die "Frikler" auf die "Planer". Also muss ich auch noch meine Meinung anbringen: @neugier: Du hast völlig recht. Die ganze Plaung und Doku zahlt kein Kunde. Allerdings klappt das nur in deinem speziellen Fall! Wenn du andere Software einbinden, deine Software exportieren müsstest, noch ein paar Kollegen oder einen Chef, der das Produkt unabhängig von dir verkaufen will, hättest, würde dein Ansatz nicht funktionieren! @Wegstaben Verbuchsler: Dein Ansatz ist natürlich generell richtiger. Aber ist es nicht so, dass deine verwegenen, heterogenen Umgebungen nur so chaotisch sind, weil früher schlecht geplant wurde bzw. ein Kunde die Planung nicht bezahlten wollte bzw. ein Chef eine falsche Entscheidung getroffen hat? Ihr habt also beide eigentlich das gleiche Problem :-) @feadi: Softwareentwicklung ist eigentlich eine Kunst. Natürlich kann jeder programmieren...aber Bilder malen kann eigentlich auch jeder. Es gibt wirklich extrem viel Bücher zu diesem Thema und mit kleinen Tipps ist es leider nicht getan! Ein Anfang ist wie immer: http://de.wikipedia.org/wiki/Softwaretechnik So, ich wünsche allen einen guten Rutsch!
> Ihr wollt doch jetzt nicht aufhören?
z.Z. bin ich mit dem Go4-Buch beschäftigt ;)
Ich habe aber gemerkt dass ich viel zu wenig plane. z.B. implementiere
ich Programmteile die ich dann garnicht brauche, oder ich finde einen
Weg der das Problem viel besser löst.
Aber wenn Herr Neugier große Programme ganz ohne Planung und Doku
schreibt, hat er entweder ein großes Super-Gehirn ;) oder eine andere
Vorstellung von 'groß'.
Feadi wrote: >.... z.B. implementiere > ich Programmteile die ich dann gar nicht brauche, oder ich finde einen > Weg der das Problem viel besser löst. Jo mei das ist doch normal, je mehr du in ein Thema einsteigst, desto einfacher findest du dich darin zu recht. Am Anfang glaubst du, du brauchtest nen Kran. Den hast grad nicht aber nen Kettenzug also erst mal hoch das Zeug und der letzte ruck geht mit nem kleinen Hebel Kein Kran und noch nen Tag gespart. > Aber wenn Herr Neugier große Programme ganz ohne Planung und Doku > schreibt, hat er entweder ein großes Super-Gehirn ;) oder eine andere > Vorstellung von 'groß'. Nein das muß nicht sein. Das wirkt nur auf uns Gedächtniskrüppel abstrus. Wir sollten uns damit vertraut machen, dass Menschen mit ihrer an sich gleichen Ressource Hirn unterschiedlich umgehen können. Weit verbreitet ist die Meinung, nur sozial Orientierte hätten die besseren Chancen. Diese Meinung ist zwar evolutionstheoretisch schwer von der Hand zu weisen, jedoch selbst in diesem Kontext widerlegbar, so kann in Extremsituationen (länger anhaltender akuter Mangel an evident Notwendigem) eine Gruppe schwerer überleben als ein Spezialist welcher isoliert leben kann, da im knappe Ressourcen ein Überleben ermöglichen. Nicht von ungefähr hat das Wort "Krise" im Altgriechischen die Doppelbedeutung welche wir von selbiger als "Chance" abstrahieren. Neuere wie auch ältere Studien beschäftigen sich mit Menschen bei denen sich die Gerichtetheit der Hirnleistung weg vom sozialen hin zu verstärkter Abstraktionsfähigkeit gestaltet. Es ist ein fließender Übergang, wo jeder von uns sich da einzuordnen vermag muss er selbst bestimmen. Die meisten meiner Mitschüler waren mit bruchrechnen und Euklidscher Geometrie voll ausgelastet aber fanden sich in der Klassenstruktur bestens zurecht. Ich "Trottel" hingegen kam damit zunächst gar nicht klar (Schulklasse wie C-Klasse, heute besser aber noch immer nicht gut), da gegen waren Chemie, Mathe und Physik weniger langweilig als Sprachen(die ich erst neuestens entdecke). Die erste Grenze meines Abstraktionsvermögens erreichte ich bei der Auflösung von Integralen 3. Ordnung. Es fehlte mir schlicht an Phantasie das passende Ergänzungsintegral zu bilden um das zu Lösende um einen Grad zu reduzieren, ich benötigte plötzlich ein Schema nachdem vorzugehen sei. Aber diese Universalkrücke habe ich bis heute nicht gefunden. Fakt ist es gibt Menschen mit nahezu unglaublichen Abstraktionsfähigkeiten und fotographischer Gedächtnisleistung, welche leider oft seelische Krüppel sind. Ich bitte alle das nicht persönlich zu nehmen und ich neige nicht zu Generalisierung. Daneben gibt es solche deren Lebensbasis ungeheures soziales Feeling ist (ich meine hier nicht Mutter Theresa) sondern einfach ganz normale Menschen die zwar nicht mehr als ihre Wohnung und den Kochtopf beherrschen aber es verstehen alle sie umgebenden Personen so in ihr Umfeld einzubauen, das die sie rundum versorgen. Auch das lässt sich ins Extreme verfolgen. Soziales Feeling ohne Gewissen führt zum skrupelloser Selbstbereichehrung. Betrüger nutzen genau ihr soziales Wissen, um die Schwächen der Gutgläubigen für sich zu plündern. Ich bin bereit Neugier zu glauben und stelle die These auf das auf in das Savant-Syndrom zumindest im Ansatz zutreffen mag, ohne das er darunter leiden muss. http://de.wikipedia.org/wiki/Inselbegabung Die Frage ist nur: Was ist normal? der Anstandsleiter oder "seine" Insassen ;_)))))) Ist sozial == normal oder können uns auch gänzlich unsozial organisierte Persönlichkeiten wichtig sein, ja sind sie nicht unverzichtbar? Meine 2. These ohne Savants gäbe es keinen heutigen Menschen. Unsere Vorfahren hätten den Urwald nie verlassen ;-)). Und seien wir mal ehrlich nur unsere Umwelt und die Disziplin machen uns Freaks in der Gesellschaft der „Normalos“ hoffähig. ein gutes Neues Uns Allen, den organisierten und den unorganisierten Chaoten. back to Topic.
p.S. Worüber ich die ganze Zeit nachdenken mußte, während ich den Thread las: Bin ich nun ein frickelnder Planer oder ein planender Frickler ?-)
Hallo, Ein Punkt kommt mir hier zu kurz. Alle denken mir zu abstrakt. Motivation spilet für mich die grösste Rolle bei umfänglichen Projekten (eines davon ist beispielsweise Microsoft Windows). Und da zählen ganz andere Faktoren: - Bezahlung - Arbeitsklima - eine Vision haben - Realisierbarkeit und praktischer oder persönlicher Nutzen usw. Es macht gar nicht so sehr ein Unterschied in Assembler oder in einer vorgegebenen Architektur in einer höheren Sprache zu programmieren solange das Umfeld Ok ist. Zugegeben ist Assemblercode zunächst unübersichtlich und schlecht wartbar und auch keine rechte Architektur, aber das muss nicht so sein. Ich habe die Erfahrung gemacht, dass man sich in Details beginnt zu verzetteln und nicht weiterkommt, weil man "das Problem" beginnt aus den Augen zu verlieren oder es einfach zu schwierig ist. Das helfen gute Ratschläge in Form von GO4 und Arbeitsteilung und Zeitplanung wenig. Das sind alles Dinge um sich herumzudrücken, dem eigentlichen Problem auszuweichen. Ein Beispiel ist die Aufgabe: "Baue ein sprachverstehendes intelligentes System!". Ein anderes Extrem ist eine lästige Trivialaufgabe der Realisierung einer vorgegebenen Benutzeroberfläche für ein solches System. Im Programmieralltag begegnen einem viel Trivialaufgaben, um die man sich gerne nur herumdrückt. Und da sind die Methoden der modernen Softwareentwicklung wirksam. Da kommt dann auch noch ein Betriebswirt mit seinem Zeitplaner intellektuell mit. Leider sind solche "Lösungen" meistens ziemlich verzichtbar. Also interesssante Aufgaben, die über eine Textverarbeitung hinausgehen kosten einfach ihre Zeit und erforderen etwas von Genialität und Einsicht in die Zusammenhänge, was mit Programmieren dann gar nicht mehr so viel zu tun hat. Was mich jetzt ärgert ist, dass es Entscheidungsträger/Arbeitgeber/Auftraggeber gibt, die sowas alles in einen Topf werfen und mit ihrer Stoppuhr praktisch eine Zeitmaschine geschenkt bekommen haben wollen. In diesem Sinne stehe ich über GO4 weil leeres Stroh gedroschen wird. Das musste mal gesagt werden! Gruss 2007 Jorge
> In diesem Sinne stehe ich über GO4 weil leeres Stroh gedroschen wird.
1) Gibt es durchaus Leute, die das was im GO4 diskutiert wird
interessant finden
2) Ist genau der Inhalt vom GO4 eienr der Bausteine, die einem
helfen, den faden Routinejob möglichst schnell hinter sich
zu bringen um sich dann mit Genuss den interessanten 5%
in einem Projekt zu widmen.
Eigentlich bin ich dafür und nicht dagegen. Ich habe nur etwas gegen den unreifen religiösen Eifer. GO4 gibts schon lang. Es hat nix bewegt. >1) Gibt es durchaus Leute, die das was im GO4 diskutiert wird interessant finden Ha. Bürokraten. Über die Wahrheit kann man nicht demokratisch entscheiden, d.h. man kann es zwar aber... >2) Ist genau der Inhalt vom GO4 eienr der Bausteine, die einem helfen, den faden Routinejob möglichst schnell hinter sich zu bringen um sich dann mit Genuss den interessanten 5% in einem Projekt zu widmen. "Form Follows Function". Also zuerst die Eingebung. Die 95% meistert man hauptsächlich über "Motivation". Anschliessend kann man sich dann noch der Verbesserung einer Architektur zuwenden. Ansonsten erfüllt es noch die Funktion des Blendwerk. Mir ist es schon passiert, dass der Auftraggeber abgesprungen ist, weil er sein Vorhaben für unrealistisch befunden hat. Hat ein bisschen gejammert und ist dann frischen Mutes zur nächsten Klitsche gegangen. Dort hat man ihm Zwischenlösungen verkauft. Und wenn sie nicht gestorben sind... Also die Realität des Alltags bewegt sich woanders. Das meine ich.
>>1) Gibt es durchaus Leute, die das was im GO4 diskutiert wird > interessant finden > > Ha. Bürokraten. Würde ich nicht sagen. Algorithmen und Datenstrukturen haben mich schon immer fasziniert. Und ich bin sicher kein Bürokrat. > Die 95% meistert man hauptsächlich über "Motivation". :-) Die 95% meistert man in 3 Nachtschichten 1/2 Woche vor Abgabe. :-)
Es beruhigt mich, das Andere auch Nachts Dinge durchziehen welche im Stress des Alltags einfach nicht zu lösen sind weil ständig irgend etwas den notwendigen Fluß stört: -Arbeit, -Essen, -Trinken und -unwichtige Termine, -Schatzi könntest du nicht mal schnell..., -beim .... gibts .....Sonderangebot ..., -Sonnenlicht und -das Geschrei der Vögel
Winfried Jaeckel wrote: > Es beruhigt mich, das Andere auch Nachts Dinge durchziehen welche im > Stress des Alltags einfach nicht zu lösen sind weil ständig irgend etwas > den notwendigen Fluß stört: > -Arbeit, > -Essen, > -Trinken und > -unwichtige Termine, > -Schatzi könntest du nicht mal schnell..., > -beim .... gibts .....Sonderangebot ..., > -Sonnenlicht und > -das Geschrei der Vögel -völlig unwichtige Programmfeatures, die aber oberaffengeil sind. Wen interessiet schon die Eingabe und Verwaltung von Kundendaten wenn er in der gleichen Zeit auch ein Partikelsystem zur Simulation von Vorhängen die im Wind flattern machen und optimieren kann :-) Ist zwar nur ein Gimmick im Programm, zu nichts nutze, aber schön zum anschauen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.