Dieser Post ist sehr lang und bisweilen abstrakt geraten. Wenn du mittendrin das Gefühl hast, dass er dir nicht hilft, lies ihn bitte trotzdem bis zum Ende, denn das Wichtigste kommt zum Schluss.
Dein Anliegen ist eine hochspannende Frage, auf die ich selbst seit langer Zeit eine Antwort suche. Es gibt wohl unzählige Bücher und Lehrer da draußen, die dir Konzepte wie Objektorientierung und Kapselung durch Geheimnisprinzip und Lokalitätsprinzip beibringen. Diese Konzepte sind heute sowohl in der Industrie als auch in der Lehre sehr verbreitet und sollen dir durch Konventionen und Vorschriften Leitlinien geben, nach denen du deine Gedanken zunächst in kleinere Einheiten (Teilsysteme), dann in noch kleinere Einheiten (Klassen/Objekte) und schließlich in Quelltext umordnen kannst. Ich kenne deinen Wissensstand nicht. Wenn du von all diesen Dingen noch nichts gehört hast, ist das vollkommen in Ordnung.
Mein Problem mit dem beschriebenen Ansatz ist, dass er vielerorts mindestens so viel Unnötiges wie Sinnvolles fabriziert. Ich gehe davon aus, dass dir diese Konzepte in deinem Buch in der ein oder anderen Form auf alle Fälle beigebracht werden. Vorgegebene Leitlinien verhindern zwar gegebenenfalls grobes Chaos, viel zielgerichteter und effizienter arbeitest du jedoch, wenn du die Gründe für diese Leitlinien verstehst und direkt nach diesen handeln kannst, anstatt auf den Leitlinien entsprechenden Umwegen umständlichen Code zu schreiben und dir damit ggf. selbst die einfachsten Wege zu verbauen.
Mein Rat ist deshalb, dir zunächst einfach zu überlegen,
wie dein Programm funktionieren soll, und nicht, wie dein Programm aussehen soll. Mit etwas Erfahrung kannst du später im Optimalfall die Funktionsweise direkt in Programmcode umwandeln, der sich von einer einfachen informellen Beschreibung der Funktionsweise nur unwesentlich (durch die Grammatik der gewählten Programmiersprache) unterscheidet.
Die Quintessenz der oben genannten Konzepte ist eigentlich ganz einfach: Komplizierte Programme sind nicht nur kompliziert zu verstehen, sie sind auch kompliziert zu schreiben, kompliziert zu erweitern und kompliziert zu verbessern. Die Leistung der Konzepte besteht darin, die Einfachheit eines Programmes genauer zu charakterisieren und gezielt zu fördern. Das hört sich jetzt schwierig und abstrakt an, ist es aber eigentlich nicht. Wichtige Ideen sind zum Beispiel:
- Stets möglichst wenige Probleme auf einmal lösen. Die Lösung eines Problems kann zum Beispiel die Berechnung eines Wertes sein, oder die Ausgabe von Text. Um den Überblick zu behalten, würde man im Quelltext jeder Lösung eine eigene Funktion (oder jedem Problem eine Klasse) spendieren. Ein guter Grundsatz ist hier: Eine (Teil-)Aufgabe pro Funktion, eine Aufgabe pro Klasse. Was getrennt funktioniert, lässt sich auch getrennt verstehen, und vereinfacht somit die Entwicklung.
- Vieles, was am Anfang als großes komplexes Problem daherkommt, zerfällt bei näherem Hinsehen in viele sehr einfache Teilprobleme, die sich wie eben ausgeführt getrennt lösen lassen. Sind diese Teilprobleme erstmal gelöst, ergibt sich die Lösung des komplexen Ausgangsproblems oftmals durch einfache Kombination der Teillösungen (Aufruf der Teilproblem-Funktionen, Instanziierung der Teilproblem-Klassen)
- Es ist sehr hilfreich, wenn problemspezifische Programmteile unabhängig von anderen Programmteilen arbeiten und funktionieren. Natürlich sollte dich das nie von sinnvoller Zusammenarbeit mehrerer Programmteile abbringen. Gerade als Anfänger sind viele jedoch geneigt, das Programm wild durch verschiedene Teilbereiche springen zu lassen. Dann wird es mit der Zeit oftmals schwierig, den Ablauf des Programms zu überblicken. Bei Änderungen an einem Programmteil gehen dann leicht andere Programmteile kaputt. Im Optimalfall funktioniert Zusammenarbeit azyklisch, das heißt wenn ein Programmteil einen anderen benutzt, sollte letzterer nach Möglichkeit nicht auch direkt von ersterem abhängig sein.
- Konzentriere dich auf das genaue Problem und versuche nicht, möglichst allgemein alle Fälle abzudecken. In die Falle der übermäßigen Allgemeinheit tappen gerade objektorientierte Programme häufig, weil Objektorientierung gerne mit Wiederverwendbarkeit und Allgemeingültigkeit verbunden wird. Je mehr Fälle du abdeckst, umso komplizierter und schlussendlich fehlerhafter wird ein Programm, ohne dass es davon profitiert, weil du ja eigentlich nur ein konkretes Problem lösen wolltest.
Ich habe dich jetzt schon mit Leitlinien bombardiert, in der Hoffnung, dass diese sehr abstrakte Skizzierung dir diese einigermaßen plausibel erscheinen lässt und dir ein gewisses Gefühl dafür gibt, wodurch du dir die Arbeit leichter machen kannst. Ich selbst bin leider heute so weit von meinem Anfangsstadium weg, dass ich die Verständlichkeit des Geschriebenen darin nicht mehr objektiv beurteilen kann.
Unabhängig davon ist es aber vor allem Übung, Erfahrung und kritische Analyse durch dich selbst wie durch andere, die dir nach und nach die sinnvolle Implementierung immer größerer, komplexerer und vor allem
robusterer Programme ermöglichen. Deshalb ist mein Rat am Ende wieder: Mach dir nicht zu viel Gedanken zum Programmaufbau, sondern versuche lieber direkt die
Funktionsweise in Quelltext umzusetzen.
Überlege dir, was ein Taschenrechner leisten muss und wie er das leisten kann. Dann fange mit den Einzelschritten an, teste diese isoliert, und baue sie nach und nach zu einem Taschenrechner zusammen.
Mein Angebot an dieser Stelle: Halte uns über deinen Quelltext auf dem Laufenden, dann können wir versuchen, dir Anregungen zur Vorgehensweise und Hinweise zu verfügbaren Optionen zu geben. Wenn du das tust, beginne damit möglichst bald, denn je kleiner und unbedeutender dein Programm am Anfang ist, umso leichter haben wir selbst es, dir bei dessen Entwicklung zu folgen.