CodeGym /Kurse /Frontend SELF DE /Alles ist ein Objekt

Alles ist ein Objekt

Frontend SELF DE
Level 39 , Lektion 0
Verfügbar

1.1 Objekte und Klassen

Heute werden wir darüber sprechen, wie ein typisches Programm in JavaScript aufgebaut ist. Und die wichtigste Neuigkeit: Jedes Programm in JavaScript besteht aus Klassen und Objekten. JavaScript ist eine objektorientierte Sprache, und alles darin ist ein Objekt: Zahlen, Strings, Funktionen und sogar die Klassen selbst.

Was sind also Klassen?

Lassen wir uns zuerst eine Analogie machen. Stell dir vor, du möchtest ein kleines Schiff bauen. Zuerst musst du eine Blaupause erstellen, dann gibst du diese Blaupause an die Fabrik, wo nach diesem Plan ein Schiff gebaut wird. Oder ein Dutzend, egal wie viele Schiffe. Nach einer Blaupause entstehen Dutzende identische Schiffe, und das ist wichtig.

In der Programmierung mit JavaScript läuft es genau so.

Die Blaupausen

Ein Programmierer ist wie ein Ingenieur. Der Ingenieur zeichnet Pläne, während der JavaScript-Programmierer Klassen schreibt. Dann werden auf der Basis dieser Pläne Teile gebaut, und auf Basis der Klassen entstehen Objekte.

Blaupausen

Zuerst schreiben wir Klassen (machen Blaupausen), und dann, während das Programm läuft, erstellt JavaScript Objekte anhand dieser Klassen. Genau so, wie Schiffe anhand von Blaupausen gebaut werden.

Es gibt nur eine Blaupause, aber viele Schiffe. Die Schiffe sind unterschiedlich, sie haben unterschiedliche Namen, transportieren unterschiedliche Ladungen. Aber sie sind sich sehr ähnlich: Sie alle sind Schiffe mit einer identischen Konstruktion und können ähnliche Aufgaben ausführen.

Oder nehmen wir eine andere Analogie...

Ein Ameisenhaufen

Ein Ameisenhaufen ist ein gutes Beispiel für die Interaktion zwischen Objekten. In einem einfachen Ameisenhaufen gibt es drei Klassen von Ameisen: Königin, Soldaten und Arbeiterameisen.

Die Anzahl der Ameisen jeder Klasse ist unterschiedlich. Es gibt nur eine Königin pro Ameisenhaufen, Dutzende von Soldaten und Hunderte von Arbeiterameisen. Drei Klassen und Hunderte von Objekten. Die Ameisen interagieren miteinander, mit Ameisen ihrer eigenen oder anderer Klassen nach festgelegten Regeln.

Es ist ein perfektes Beispiel. In einem typischen Programm läuft es genauso. Es gibt ein Hauptobjekt, das alle anderen Klassen erstellt. Die Objekte beginnen miteinander und mit der Außenwelt des Programms zu interagieren. In den Objekten ist ihr Verhalten strikt programmiert.

Diese beiden Beispiele zeigen zwei Seiten derselben Medaille. Die Wahrheit liegt irgendwo dazwischen. Das erste Beispiel (die Blaupause und die Schiffe) zeigt die Beziehung zwischen einer Klasse und den Objekten dieser Klasse — die Analogie ist sehr aussagekräftig. Das zweite Beispiel (Ameisenhaufen) zeigt die Beziehung zwischen den Objekten, die während der Programmausführung existieren, und den geschriebenen Klassen.

Zuerst musst du die Klassen für alle Objekte im Programm schreiben und dann auch noch ihre Interaktion beschreiben. Klingt kompliziert, ist aber einfacher, als es scheint.

In JavaScript sind während der Programmausführung alle Entitäten Objekte, und das Schreiben eines Programms reduziert sich darauf, verschiedene Möglichkeiten der Interaktion von Objekten zu beschreiben. Objekte rufen einfach die Methoden voneinander auf und übergeben die notwendigen Daten.

Dokumentation

Und wie weiß man, welche Daten man an die Methoden übergeben muss? Das ist schon vor dir gelöst worden.

Normalerweise hat jede Klasse eine Beschreibung, in der steht, wofür sie erstellt wurde. Auch hat normalerweise jede öffentliche Methode ebenfalls eine Beschreibung: was sie macht und welche Daten man an sie übergeben muss.

Um eine Klasse zu verwenden, musst du im Großen und Ganzen verstehen, was sie tut. Aber du musst genau wissen, was jede ihrer Methoden macht. Und du musst überhaupt nicht wissen, wie sie das macht. Eine Art Zauberstab.

Sehen wir uns mal ein Codebeispiel an — das Kopieren einer Datei:

JavaScript
    
      const fs = require('fs');

      // Dateien öffnen
      const src = fs.createReadStream('source.txt');
      const dst = fs.createWriteStream('destination.txt');

      // Den Inhalt von source.txt nach destination.txt kopieren
      src.pipe(dst);

      // Dateien schließen, nachdem das Kopieren abgeschlossen ist
      src.on('end', () => {
        src.close();
        dst.close();
      });
    
  

Wenn man diesen Code Zeile für Zeile liest, kann man grob verstehen, was er macht. Dafür braucht es aber Erfahrung und Übung. Nach einer Weile wird dir dieser Code aber vertraut und verständlich vorkommen.

1.2. Programmplanung

Die Planung eines Programms ist eine Kunst für sich. Es ist gleichzeitig einfach und schwierig. Einfach, weil es keine strengen Gesetze gibt: Alles, was nicht verboten ist, ist erlaubt. Und schwierig aus genau diesem Grund: Es gibt viele Möglichkeiten, etwas zu machen, und es ist nicht einfach, die beste zu finden.

Ein Programm zu planen ist wie das Schreiben eines Buches. Auf der einen Seite schreibst du einfach Buchstaben, Worte, Sätze. Auf der anderen Seite sind die Handlung, die Charaktere, ihre inneren Widersprüche, Konflikte, Erzählstil und Spannung wichtig.

Das Wichtigste ist, zu verstehen, für wen du den Code schreibst. Und dieser Code ist für andere Programmierer.

Die Entwicklung eines jeden Produkts besteht aus Veränderungen: etwas wird hinzugefügt, etwas entfernt, etwas umgestaltet. Und so entstehen durch kleine Iterationen große, enorme und gigantische Projekte.

Die wichtigste Anforderung an den Code ist, dass er für andere Programmierer verständlich sein muss. Falscher, aber verständlicher Code kann verbessert werden. Richtiger, aber unverständlicher Code kann nicht verbessert werden. Er wird bloß entsorgt.

Wie schreibt man also guten und verständlichen Code?

Dafür musst du drei Dinge tun:

  • Guten und verständlichen Code innerhalb von Methoden schreiben — das Einfachste
  • Entscheiden, welche Entitäten im Programm sein müssen
  • Das Programm richtig in logische Teile aufteilen

Was steckt hinter diesen Konzepten?

Guten Code innerhalb von Methoden schreiben

Wenn du zumindest grundlegende Englischkenntnisse hast, hast du vielleicht schon bemerkt, wie einfach Code manchmal zu lesen ist — wie Sätze in englischer Sprache:

  • class Cat extends Pet — die Klasse Cat erweitert die Klasse Pet
  • while (stream) — solange der Stream nicht leer ist...
  • a < b ? a : b — wenn a kleiner als b ist, gib a zurück, andernfalls b

Das ist Absicht. JavaScript ist eine der wenigen Sprachen, in denen man leicht selbstdokumentierenden Code schreiben kann: Code, der ohne Kommentare verständlich ist. In gutem JavaScript-Code lesen sich viele Methoden einfach wie Sätze in englischer Sprache.

Deine Aufgabe beim Schreiben von Code ist es, ihn ebenfalls so einfach und prägnant wie möglich zu machen. Denk einfach daran, wie leicht dein Code zu lesen sein wird, und du wirst dich in die richtige Richtung bewegen.

In JavaScript ist es üblich, leicht lesbaren Code zu schreiben. Ideal wäre es, wenn jede Methode vollständig auf den Bildschirm passt (20–30 Zeilen pro Methode). Das ist die Norm in der JavaScript-Community. Wenn der Code verbessert werden kann, sollte er es auch.

Der beste Weg, um zu lernen, guten Code zu schreiben, ist ständige Praxis. Schreibe viel Code, studiere fremden Code, bitte erfahrenere Kollegen, deinen Code zu überprüfen. Und denk daran, dass der Moment, in dem du dir sagst „das reicht aus“, der Moment ist, in dem du dich nicht weiterentwickelst.

Entscheiden, welche Entitäten im Programm sein müssen

Du schreibst Code, der für andere Programmierer verständlich sein soll. Wenn 9 von 10 Programmierern beim Entwurf eines Programms Klassen A, B und C erstellen, dann sollte auch dein Programm Klassen A, B und C haben.

Exzellenter, funktionierender, schneller, aber unorthodoxer Code ist schlechter Code.

Du musst fremde Projekte studieren: Das ist der beste, schnellste und einfachste Weg, die Weisheit der IT-Industrie zu übernehmen.

Und übrigens, du hast bereits ein exzellentes, beliebtes und gut dokumentiertes Projekt zur Hand — React. Fang damit an.

Analysiere die Klassen und die Klassenstrukturen. Überlege, warum einige Methoden statisch sind und andere nicht. Warum haben die Methoden genau diese Parameter und keine anderen? Warum genau diese Methoden? Warum heißen die Klassen genau so, und warum sind sie genau in diesen Paketen?

Wenn du die Antworten auf all diese Fragen verstehst, wirst du Code schreiben können, der für andere verständlich ist.

Ich möchte dich jedoch davor warnen, den Code in den Methoden von D3.js zu analysieren. Der Code vieler Methoden wurde mit dem Ziel, die Arbeitsgeschwindigkeit zu maximieren, überarbeitet — die Lesbarkeit ist dabei fraglich.

Das Programm richtig in logische Teile aufteilen

Jedes Programm wird normalerweise in Teile oder Module unterteilt. Jedes Teil ist für seinen eigenen Aspekt des Programms zuständig.

Dein Computer verfügt z. B. über einen Tower, einen Monitor, eine Tastatur, und all das sind separate, wenig abhängige Teile. Darüber hinaus ist ihre Interaktion standardisiert: USB, HDMI usw. Wenn du also Kaffee auf die Tastatur verschüttest, kannst du sie einfach unter dem Wasserhahn reinigen, trocknen und weiter benutzen.

Ein Notebook hingegen ist ein Beispiel für eine monolithische Architektur: Die logischen Teile sind zwar vorhanden, aber viel stärker integriert. Bei einem MacBook Pro musst du möglicherweise die Hälfte des Notebooks auseinandernehmen, um die Tastatur zu reinigen. Und verschütteter Kaffee führt oft direkt zum Kauf eines neuen Geräts. Am besten also keinen Kaffee.

1.3 Eigene Klassen erstellen

Du lernst gerade zu programmieren, also solltest du klein anfangen — lern, eigene Klassen zu erstellen.

Natürlich hast du sie schon erstellt, aber du musst lernen zu verstehen, welche Klassen im Programm sein sollen, wie sie heißen sollen, welche Methoden sie haben sollen und wie sie interagieren sollen.

Liste der Entitäten

Wenn du nicht weißt, wo du anfangen sollst, fang am Anfang an.

Zu Beginn des Programmentwurfs kannst du einfach auf ein Blatt Papier eine Liste mit Entitäten (Objekten) aufschreiben, die im Programm vorhanden sein sollten. Und dann implementierst du sie nach folgendem Prinzip: Jede Entität ist eine eigene Klasse.

Beispiel

Angenommen, du möchtest ein Schachspiel schreiben. Du benötigst folgende Entitäten: ein Schachbrett und 6 Arten von Figuren. Die Figuren haben unterschiedliche Bewegungsweisen und unterschiedliche Werte — es macht Sinn, dass dies separate Klassen sind. Und im Allgemeinen gilt am Anfang: Je mehr Klassen, desto besser.

Es ist selten, auf einen Anfänger zu treffen, der anstelle von zwei Klassen lieber zehn schreiben würde. Aber zwei oder sogar eine Klasse anstelle von zehn zu verwenden, das lieben Anfänger. Also mehr Klassen, liebe Programmierer. Und dein Code wird für alle klarer, außer vielleicht für dich selbst 😛

Schach

Angenommen, wir haben uns entschieden, Klassen für Schach zu schreiben: Wie könnten diese Klassen aussehen?

Ein Schachbrett — ist das einfach ein 8x8 Array? Lieber erstelle dafür eine eigene Klasse, die intern eine Referenz auf das Array speichert. Dann kannst du viele nützliche Methoden in die Klasse „Schachbrett“ hinzufügen, die z. B. prüfen, ob ein Feld leer oder besetzt ist.

Im Allgemeinen gilt zu Beginn immer dieses Prinzip: Ein Programm hat verschiedene Entitäten, und jede Entität hat einen Typ. Dieser Typ ist die Klasse.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION