JavaのFlyweightパターン

1概要

この記事では、flyweightデザインパターンを見てみましょう。このパターンは、メモリ使用量を減らすために使用されます。オブジェクトのインスタンス化が高価なアプリケーションでもパフォーマンスを向上させることができます。

簡単に言えば、flyweightパターンは作成後にそれらを格納することによって作成されたオブジェクトをリサイクルする工場に基づいています。オブジェクトが要求されるたびに、ファクトリはオブジェクトがすでに作成されているかどうかを確認するためにそのオブジェクトを調べます。持っていれば、既存のオブジェクトが返されます。そうでなければ、新しいオブジェクトが作成され、格納されてから返されます。

flyweightオブジェクトの状態は、他の同様のオブジェクトと共有される不変コンポーネント( intrinsic )とクライアントコードによって操作されることができるバリアントコンポーネント( extrinsic )で構成されています。

flyweightオブジェクトが不変であることは非常に重要です。状態に対する操作はすべてファクトリによって行われなければなりません。

2実装

パターンの主な要素は次のとおりです。

  • クライアントコードができる操作を定義するインターフェース

flyweightオブジェクトで実行する ** 私たちのインターフェースの1つ以上の具体的な実装

  • オブジェクトのインスタンス化とキャッシュを扱うファクトリ

各コンポーネントの実装方法を見てみましょう。

2.1. 車両インターフェース

はじめに、 Vehicle インターフェースを作成します。このインタフェースはファクトリメソッドの戻り値の型になるので、関連するすべてのメソッドを必ず公開する必要があります。

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

2.2. コンクリート車

次に、 Car クラスを具体的な__Vehicleとして作成しましょう。その状態については、エンジンとカラーフィールドがあります。

private Engine engine;
private Color color;

2.3. 自動車工場

大事なことを言い忘れましたが、 VehicleFactory を作成します。新車の建設は非常に費用のかかる作業であるため、工場は色ごとに1台の車を作成するだけです。

それをするために、我々は単純なキャッシュとして地図を使用して作成された車両を追跡します:

private static Map<Color, Vehicle> 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;
}

クライアントコードが createVehicle メソッドの引数として渡すことで、オブジェクトの外的な状態(ビークルの色)にのみ影響を与えることができることに注目してください。

3ユースケース

3.1. データ圧縮

flyweightパターンの目標は、できるだけ多くのデータを共有することによってメモリ使用量を減らすことです。したがって、これはロスレス圧縮アルゴリズムの良い基盤です。この場合、各flyweightオブジェクトはポインタとして機能し、その外部状態はコンテキスト依存情報です。

この使い方の典型的な例はワードプロセッサです。ここでは、各文字はレンダリングに必要なデータを共有するflyweightオブジェクトです。その結果、ドキュメント内の文字の位置だけが追加のメモリを占有します。

3.2. データキャッシング

最近の多くのアプリケーションは応答時間を改善するためにキャッシュを使用しています。 flyweightパターンはキャッシュのコアコンセプトに似ており、この目的によく合うことができます。

もちろん、このパターンと一般的な汎用キャッシュの間には、複雑さと実装にいくつかの重要な違いがあります。

4結論

まとめると、このクイックチュートリアルでは、Javaのflyweightデザインパターンに焦点を当てました。また、パターンを含む最も一般的なシナリオのいくつかをチェックしました。

例のコードはすべてhttps://github.com/eugenp/tutorials/tree/master/patterns/design-patterns[GitHubプロジェクト]から入手できます。