Skalierbarkeit – Programmieren lernen mit JavaScript – Thytos
Nächstes Video startet in 3 Sekunden.
Programmieren lernen mit JavaScript

Skalierbarkeit

Wenn die Leis­tung ei­nes Sys­tems stei­gen­dem An­spruch ge­recht wird, ist das Sys­tem »ska­lier­bar«. Die­ser und an­dere wich­ti­ge Be­griffe kom­men in der Soft­ware­ent­wick­lung im­mer wie­der vor.

In einem der letzten Artikeln der Serie wurde ein Datenbank-Objekt erstellt, über das einfache Objekte einem Array hinzufügt werden können.
Das wurde genutzt, um Informationen zur Besetzung von Das Schweigen der Lämmer zu speichern.

Jeder Eintrag in der Datenbank enthielt die Keys "name", "gender" und "birthday"

Seht ihr etwas, das sich ständig wiederholt? Mit jedem Eintrag werden die Keys, die Namen der Properties, "name", "gender" und "birthday" abgespeichert.
Je mehr Objekte in der Datenbank liegen, desto mehr Speicher wird benötigt — aber nicht nur für die eigentlichen Werte, sondern jedes Mal auch für die Namen der Werte, für die Keys. Der Overhead, der Datenüberhang, ist dadurch sehr groß. Die Datenbank skaliert nicht gut. Besser wäre es, wenn der Speicherbedarf für die Keys der Werte nahezu gleich bliebe, unabhängig davon, wie viele Einträge sich in der Datenbank befinden.

Wie kann das erreicht werden? Die Datenbank lässt sich umdrehen: Statt ein Array mit Objekten, könnte sie ein Objekt mit Arrays haben. Dadurch bräuchte jeder Propertyname nur einmal gespeichert werden.

Ein Objekt mit den Keys "name", "gender" und "birthday" enthält als Werte nur Arrays. Die Einträge in der Datenbank werden auf die Arrays verteilt.

Die Datenbank-Methoden müssten dann natürlich neu geschrieben werden, um mit der Veränderung der Datenstruktur zu funktionieren. Das Tolle: Angenommen, die Datenbank wäre bereits im Einsatz in einem Programm, das mit ihr interagiert – der Code des Programms müsste nicht verändert werden, um weiterhin zu funktionieren. Das Datensatz-Array könnte gegen ein Datensatz-Objekt ausgetauscht werden, ohne dass der Code außerhalb der Datenbank dafür angepasst werden müsste.
Denn der Code außerhalb greift nicht auf das Datenbank-Array direkt zu, sondern nur auf die Methoden, die die Datenbank zur Verfügung stellt.

Solange der Name, die Argumente und der Rückgabewert der Methoden gleich bleiben, kann sich die Methode intern beliebig verändern, ohne dass der Code, der auf die Methoden zugreift, geändert werden muss.

Möglich ist das dank Abstraktion. Komplexität wird eingekapselt und verborgen. Dem anderen Code ist egal, was im Inneren der Datenbank vor sich geht und wie sie umgesetzt ist, weil er nur mit den "öffentlichen" Methoden kommuniziert. Die sind die Schnittstelle der Datenbank.
Eine Schnittstelle ist der Punkt, an dem zwei Entitäten miteinander interagieren.
Schnittstelle heißt auf Englisch Interface. Eine Programmierschnittstelle ist eine Application Programming Interface, abgekürzt API, und bezeichnet die öffentliche Schnittstelle eines Moduls (einer Bibliothek, eines Plugins, etc.), die von anderem Code verwendet werden kann.
Öffentlich heißt in dem Zusammenhang, dass es für alle Entwickler zulässig ist, mit den angebotenen Werten und Methoden zu arbeiten. Daneben gibt es in manchen Programmiersprachen auch geschützte oder private Eigenschaften. In JavaScript kann eine Eigenschaft nicht als privat gekennzeichnet werden; trotzdem gibt es manchmal Werte, die ein Modul nur intern nutzen will und nicht möchte, dass anderer Code darauf zugreift. Solche Werte werden per Konvention mit einem einleitenden Unterstrich benannt. Im Fall der Datenbank wäre es sinnvoll, die datensatz-Property so zu kennzeichnen.

function Database () {
  // Mit einem Unterstrich zu Beginn
  // des Namens wird kenntlich gemacht,
  // dass das Modul (in diesem Fall
  // also die Database) den Wert intern
  // verwendet und nicht möchte, dass
  // anderer Code darauf zugreift
  this._datensatz = …;
}

Das Kapseln / Verbergen von Komplexität ist eine der zentralen Eigenschaften der Objektorientierung. Der Vorteil ist, dass der Code außerhalb auf diese Weise wiederverwendet werden kann, wenn es Veränderungen innerhalb eines Objekts gibt. Wiederverwendbarer Code, reusable code, ist insgesamt etwas komplexer, aber im Kern das, was der Name bereits sagt.

Begriffe vom Großen im Kleinen

Es gibt viele dieser Begriffe, die in der Softwareentwicklung immer wieder fallen gelassen werden. In der Regel werden Bezeichnungen wie API und Skalierbarkeit in größeren Zusammenhängen verwendet.
Im Fall von Skalierbarkeit zum Beispiel, wenn eine steigende Anzahl von Nutzern zeitgleich auf einen Server zugreift, dann muss der Server gut skalieren, um die gestiegene Last bewältigen zu können.

Skalierbarkeit ist ein komplexes Thema, denn es gibt auch verschiedene Arten der Skalierbarkeit: Es gibt horizontale und vertikale Skalierbarkeit. Meistens geht es dabei auch um Hardwarefragen: Wird ein Computer genommen, der mit besserer Hardware leistungsfähiger gemacht wird, um einem steigenden Anspruch gerecht zu werden, oder sollte die Last lieber auf mehrere Computer verteilt werden, die für sich genommen eher leistungsschwach sind?

Die Begriffe kommen somit eher aus einem größeren Kontext, können allerdings auch gut und konkret anhand des simplen Datenbank-Beispiels erklärt werden. Es zeigt: Ein Softwareentwickler sollte sich immer darüber Gedanken machen, wie sich seine Software verhält, je mehr sie genutzt wird. Wie verhält sich eine Datenbank, je mehr Daten sie beinhaltet? Wie verhält sie sich, je öfter und schneller auf sie zugegriffen wird? Wie verhält sich eine Webanwendung, je mehr Menschen sie gleichzeitig nutzen?
In der Softwareentwicklung gibt es immer alternative Lösungsansätze. Das Datenbank-Modul kann mit einem Array von Objekten als Datensatz umgesetzt werden oder mit einem Objekt von Arrays oder – und das ist bei "echten" Datenbanken der Fall – auf eine ganz andere Weise. Bei Datenbanken, die auch tatsächlich eingesetzt werden, ist es schließlich auch wichtig, dass sie Daten persistent speichern, also langfristig. Im Fall von der hier vorgestellten Datenbank sind alle Daten weg, sobald das Browserfenster geschlossen wird, weil die Daten bloß im Arbeitsspeicher im Kontext des Browserfensters existieren.

Gleichzeitig ist aber auch wichtig, nicht von Beginn an Faktoren wie Skalierbarkeit zu sehr zu bedenken. Bei einer Anwendung, bei der klar ist, dass sie nie hohen Ansprüchen genügen muss, bspw. weil sie nur unternehmensintern eingesetzt wird, sollte die Möglichkeit von hohen Ansprüchen nicht berücksichtigt werden, da das unter preoptimization fällt – vorausgehenden Optimierungen, oder auch: Optimierungen ohne Grund. Aufwand in etwas zu stecken, das nicht notwendig ist, ist vergeudeter Aufwand und somit ineffizient.