Fliegengewichtsmuster in Java

1. Übersicht

In diesem Artikel werfen wir einen Blick auf das Muster des Fliegengewichts. Dieses Muster wird verwendet, um den Speicherbedarf zu verringern. Es kann auch die Leistung in Anwendungen verbessern, in denen die Objektinstanziierung teuer ist.

Einfach ausgedrückt basiert das Fliegengewichtsmuster auf einer Fabrik, die erstellte Objekte recycelt, indem sie nach der Erstellung gespeichert werden. Jedes Mal, wenn ein Objekt angefordert wird, sucht die Factory nach dem Objekt, um zu überprüfen, ob es bereits erstellt wurde. Wenn dies der Fall ist, wird das vorhandene Objekt zurückgegeben. Andernfalls wird ein neues Objekt erstellt, gespeichert und dann zurückgegeben.

Der Status des Flyweight-Objekts besteht aus einer invarianten Komponente, die mit anderen ähnlichen Objekten gemeinsam genutzt wird ( intrinsisch ), und einer varianten Komponente, die vom Client-Code bearbeitet werden kann ( extrinsisch ).

Es ist sehr wichtig, dass die Objekte im Fliegengewicht unveränderlich sind: Jede Operation am Zustand muss von der Fabrik durchgeführt werden.

2. Implementierung

Die Hauptelemente des Musters sind:

  • Eine Schnittstelle, die die Operationen definiert, die der Clientcode für das Flyweight-Objekt ausführen kann
  • eine oder mehrere konkrete Implementierungen unserer Schnittstelle
  • Eine Fabrik zur Instanziierung und Zwischenspeicherung von Objekten

Mal sehen, wie jede Komponente implementiert wird.

2.1. Fahrzeugschnittstelle

Zunächst erstellen wir eine Fahrzeugschnittstelle . Da diese Schnittstelle der Rückgabetyp der Factory-Methode ist, müssen wir sicherstellen, dass alle relevanten Methoden verfügbar gemacht werden:

public void start(); public void stop(); public Color getColor();

2.2. Betonfahrzeug

Als nächstes machen wir eine Autoklasse als konkretes Fahrzeug. Unser Auto wird alle Methoden der Fahrzeugschnittstelle implementieren. Der Status wird eine Engine und ein Farbfeld haben:

private Engine engine; private Color color;

2.3. Fahrzeugfabrik

Zu guter Letzt erstellen wir die VehicleFactory . Der Bau eines neuen Fahrzeugs ist sehr teuer, daher wird in der Fabrik nur ein Fahrzeug pro Farbe hergestellt.

Zu diesem Zweck verfolgen wir die erstellten Fahrzeuge mithilfe einer Karte als einfachem Cache:

private static Map vehiclesCache = new HashMap(); public static Vehicle createVehicle(Color color) { Vehicle newVehicle = vehiclesCache.computeIfAbsent(color, newColor -> { Engine newEngine = new Engine(); return new Car(newEngine, newColor); }); return newVehicle; }

Beachten Sie, dass der Clientcode nur den äußeren Zustand des Objekts (die Farbe unseres Fahrzeugs) beeinflussen kann, indem er als Argument an die Methode createVehicle übergeben wird.

3. Anwendungsfälle

3.1. Datenkompression

Das Ziel des Flyweight-Musters besteht darin, die Speichernutzung zu reduzieren, indem so viele Daten wie möglich gemeinsam genutzt werden. Daher ist es eine gute Grundlage für verlustfreie Komprimierungsalgorithmen. In diesem Fall fungiert jedes Fliegengewichtsobjekt als Zeiger, wobei sein äußerer Zustand die kontextabhängige Information ist.

Ein klassisches Beispiel für diese Verwendung ist ein Textverarbeitungsprogramm. Hier ist jedes Zeichen ein Objekt im Fliegengewicht, das die für das Rendern erforderlichen Daten gemeinsam nutzt. Infolgedessen nimmt nur die Position des Zeichens im Dokument zusätzlichen Speicherplatz ein.

3.2. Daten-Caching

Viele moderne Anwendungen verwenden Caches, um die Reaktionszeit zu verbessern. Das Flyweight-Muster ähnelt dem Kernkonzept eines Caches und kann diesen Zweck gut erfüllen.

Natürlich gibt es einige wesentliche Unterschiede in der Komplexität und Implementierung zwischen diesem Muster und einem typischen Allzweck-Cache.

4. Fazit

Zusammenfassend konzentrierte sich dieses kurze Tutorial auf das Entwurfsmuster im Fliegengewicht in Java. Wir haben auch einige der häufigsten Szenarien untersucht, die das Muster betreffen.

Der gesamte Code aus den Beispielen ist im GitHub-Projekt verfügbar.