Einzelnen Beitrag anzeigen

OlafSt

Registriert seit: 2. Mär 2007
Ort: Hamburg
284 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#20

AW: Warum und wann eine Klasse benutzen

  Alt 17. Okt 2013, 10:59
Eigentlich ist die Antwort ganz simpel - und zugleich sehr kompliziert.

Ich benutze mal das Beispiel, mit dem ich meinem Kollegen, seines Zeichens krasser Anfänger, die Augen öffnen konnte. Sein "Fachgebiet" damals waren MP3-Player jeder Art.

Nun ist es nicht allzu schwer einen MP3-Player zu stricken. BASS.DLL rein und damit ist er schon fast fertig. Aber das ist langweilig, also verzichten wir auf die BASS.DLL und machen das alles selbst. Also schreiben wir ein paar Routinen, die DirectSound initialisieren, uns einen DirectSound-Kontext holen, Daten an DS senden und so weiter. Das sind alles Basics und wir haben dann u.a. folgende Routinen:

- InitDirectSound
- GetDSContext
- SendToDS
- CloseDSContext
- FinalizeDirectSound

Anschließend greifen wir uns das simple Format "WAV". Das hat einen Header und dann rohe Sounddaten. Also basteln wir weitere Routinen:

- OpenWAVFile
- ProcessWAVHeader
- ProcessChunkofWAVData
- CloseWAVFile

Wesentliche Daten werden in Records gespeichert und in globalen Variablen gehalten *hust* - typisch Anfänger halt.

However. Wenn das alles implementiert ist, klickt man auf "PLAY" und das zuvor selektierte WAV-File wird abgespielt. Bis hierhin haben wir den Umfang eines normalen Hobbycoder-Projektes erreicht. Und bis hierher machen Klassen auch kaum einen Sinn, das ganze geht auch mit dem Programmierparadigma "strukturiert" zu bauen.

Aber nun verlassen wir diese Ebene. Wir haben plötzlich die absonderliche Idee und möchten jetzt auch MP3-Files abspielen.

Im bisherigen Schema mußt du nun ALLE ROUTINEN, die sich mit Dateien befassen, ERNEUT schreiben. Also Routinen wie
- OpenMP3File
- ProcessMP3Header
- ProcessChunkofMP3Data
- CloseMP3File

Selbst dann, wenn der Code völlig identisch zu dem der WAV-Files ist - natürlich könnte man sagen "okay, rufe ich einfach die WAV-Routinen auf". Kann man machen, aber dann hast du den berühmten Spaghetti-Code produziert und nach 6 Monaten fragst du dich "Hä, ich fummel hier mit MP3 herum, wieso ruf ich da nu WAV-Routinen auf ?!?". Macht man also nicht.

Auch brauchst du nun alle die schönen Records ein weiteres Mal. Und die globalen Variablen.

Nun hast du 2 Sätze an Routinen gebaut und mehrfach identischen Code mitsamt fast identischer Datenstrukturen produziert. Hier kommt nun OOP ins Spiel.

Man bastelt sich eine Klasse namens "WAVFile". Wir schreiben uns die Methoden
- OpenFile
- ProcessHeader
- ProcessData
- CloseFile

Da wir mit WAV anfangen, kann unser erster Entwurf, genauso wie oben am Anfang, nur mit WAV umgehen. Natürlich integrieren wir die Records in diese Klasse und - oha - globale Variablen sind eigentlich nicht mehr nötig.

Fügen wir nun MP3 hinzu, vererben wir kurzerhand (Hier fiel vor 25 Jahren bei meinem Bruder der Groschen ). Wir leiten eine Klasse MP3File von WAVFile ab. Da OpenFile und CloseFile identisch für WAV und MP3 sind, brauchen wir das gar nicht mehr programmieren - Zeit, Code und Fehlersuch-Ärger gespart. Wir implementieren nur noch ProcessHeader und ProcessData und PAFF - können wir MP3, nachdem wir ein paar Anpassungen an den internen Strukturen gemacht haben.

Und nun kommt OGG hinzu - nach altem Schema bastelst du nun wieder 4 Routinen und einen Satz Records, von denen wieder einiges identisch ist und du hast nun etliche Male denselben Code da stehen. In OOP leitest du wieder von WAVFile ab, schreibst nur neuen Code und hast Zeit, Code und Fehlersuch-Ärger gespart.

Tja, und dann... Dann möchtest du nicht nur DirectSound unterstützen, sondern auch das brandneue Soundsystem "OpenSound". Die gleiche Leier.

Ergo: In Kleinstprogrammen, wie sie Anfänger basteln und die kaum über den Umfang von 5000 Zeilen hinauskommen, wirkt OOP völlig sinnlos und produziert sogar scheinbar mehr Aufwand. Die Stärken der OOP kommen erst in größeren Projekten voll durch - und je größer und komplexer, desto effektiver ist OOP.

Mein Tip: Auch wenn es sinnlos oder aufwändig erscheint - programmiere immer objektorientiert. Hast du dich erstmal an den inzwischen prähistorisch anmutenden strukturierten Stil gewöhnt, wird es irgendwann schwer, wieder auf OOP umzuschwenken. Viele, viele, viele Hobbyprogrammierer bleiben genau das: Hobbyprogrammierer, die auch nach der 50. Version ihres MP3-Players noch einen neuen anfangen und doch immer wieder dieselben Features basteln und nur die Oberfläche ändert sich. Etliche von diesen hören auch wieder auf mit dem Programmieren.

Ein paar allerdings infizieren sich unheilbar mit dem Coder-Virus und womöglich bist du auch einer von diesen Irren Dann sind Programme im 50k-Bereich eher das übliche Tagewerk und dann haut OOP richtig rein.

Geändert von OlafSt (17. Okt 2013 um 11:02 Uhr)