001
10.11.2004, 21:02 Uhr
ao
(Operator)
|
Ein verbreiteter Ansatz ist, das Projekt in funktionelle Blöcke zu unterteilen. Beispiel: Wir schreiben einen MP3-Player, sowas wie Winamp. Der muss folgendes können:
1. MP3-Datei von Festplatte öffnen und einlesen (mit Hilfe von WinAPI-Funktionen) 2. MP3-Dekompression (mit einer MP3-Decoder-Bibliothek) 3. Soundkarte finden und öffnen und den dekomprimierten Wave-Datenstrom ausgeben (wieder mit Hilfe von WinAPI-Funktionen)
und er muss eine Oberfläche haben, die das alles bedienbar macht.
Das wären die Minimal-Funktionen. Geschickt wäre es nun, alles, was mit dem Öffnen und Einlesen von Dateien zu tun hat, in eine Klasse zu packen. In eine andere Klasse die Handhabung des MP3-Codecs und in eine dritte Klasse die Bedienung der Soundkarte.
Eine weitere Klasse enthält die Programmlogik; diese verknüpft die bisher erwähnten Klassen in geeigneter Weise: Zuerst die Vorbereitung: Soundkarte "öffnen" und belegt halten und den MP3-Codec initialisieren. Dann die MP3-Datei öffnen, kurz sicherstellen, dass es sich wirklich um ein MP3-File handelt und dann blockweise lesen. Die komprimierten Daten in den Codec stopfen und dekomprimiert wieder abholen und ins Sound-Device schicken. Wenn die Datei am Ende ist, alles schließen.
Alle diese Klassen können oberflächenfrei sein. Die alles verbindende Oberfläche kommt in eine oder mehrere weitere Klassen, aber spätestens hier kommt dann meist MFC oder ein anderes Toolkit ins Spiel, was den Projektaufbau maßgeblich beeinflusst.
Wichtig ist, dass jede Klasse ihr "Kerngeschäft" hat, was sie sauber realisiert, und sich aus den "Nebensachen" ebenso konsequent raushält. Falsch ist zum Beispiel, wenn die MP3-Codec-Klasse darauf angewiesen ist, dass ihr ein geöffnetes Sounddevice übergeben wird, auf dem sie Töne direkt ausgeben kann. Solche Abhängigkeiten sind möglichst zu vermeiden, weil sie es sind, die ein Projekt kompliziert machen. Das Prinzip ist "Teile und herrsche" und lass nicht zu, dass jeder den anderen kennt, denn dann beginnt der Filz.
Oder, wenn du sowas wie Multithreading brauchst, ist es eine gute Idee, die Kernfunktionen (Thread erzeugen, im Thread-Kontext eine Arbeitsroutine laufenlassen, Thread wieder zerlegen) in eine Basisklasse auszulagern. Dann kannst du sie immer wieder verwenden, mit einer dem Zweck angepassten Arbeitsroutine.
Viel Erfolg für euer Projekt
ao |