Flyweight Pattern in Java

Fliegengewichtmuster in Java

1. Überblick

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, bei denen die Objektinstanziierung teuer ist.

Einfach ausgedrückt basiert das Fliegengewichtmuster 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. Ist dies der Fall, wird das vorhandene Objekt zurückgegeben. Andernfalls wird ein neues Objekt erstellt, gespeichert und anschließend zurückgegeben.

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

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

2. Implementierung

Die Hauptelemente des Musters sind:

  • Eine Schnittstelle, die die Operationen definiert, die der Client-Code für das Flyweight-Objekt ausführen kann

  • eine oder mehrere konkrete Implementierungen unserer Schnittstelle

  • Eine Factory, die die Instanziierung und Zwischenspeicherung von Objekten verwaltet

Lassen Sie uns sehen, wie die einzelnen Komponenten implementiert werden.

2.1. Fahrzeugschnittstelle

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

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

2.2. Betonfahrzeug

Als nächstes machen wir eineCar-Klasse zu einer konkretenVehicle.-Klasse. Unser Auto implementiert alle Methoden der Fahrzeugschnittstelle. Der Status wird über eine Engine und ein Farbfeld verfügen:

private Engine engine;
private Color color;

2.3. Fahrzeugfabrik

Zu guter Letzt erstellen wir dieVehicleFactory. Der Bau eines neuen Fahrzeugs ist ein sehr teurer Vorgang, sodass die Fabrik nur ein Fahrzeug pro Farbe herstellt.

Zu diesem Zweck verfolgen wir die erstellten Fahrzeuge mithilfe einer Karte als einfachen 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 Client-Code nur den äußeren Zustand des Objekts (die Farbe unseres Fahrzeugs) beeinflussen kann, indem er als Argument an die MethodecreateVehicleü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 Fliegengewichtobjekt 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 Fliegengewicht-Objekt, das die für das Rendern benötigten Daten teilt. Infolgedessen nimmt nur die Position des Zeichens im Dokument zusätzlichen Speicherplatz ein.

3.2. Daten-Caching

Viele moderne Anwendungen verwenden Caches, um die Antwortzeit zu verbessern. Das Flyweight-Muster ähnelt dem Kernkonzept eines Caches und eignet sich gut für diesen Zweck.

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

4. Fazit

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

Der gesamte Code aus den Beispielen ist überthe GitHub project verfügbar.