(22)メタモード


(22)メタモード
定義:共有オブジェクトを使用すると、多数の細さのオブジェクトを効果的にサポートできます.
タイプたいぷ:Structure Mode Structure Mode
クラス図:
ファセットパターン構造:
l抽象享元ロール(Flyweight):このロールは、実装する必要がある共通インタフェースまたは抽象クラスを規定するすべての特定の享元クラスのスーパークラスです.外部状態(External State)を必要とする操作は、メソッドのパラメータを介して入力することができる.抽象的なエンティティのインタフェースはエンティティを可能にするが、サブクラスに共有を強制するわけではないため、すべてのエンティティオブジェクトが共有できるわけではない.
l具体的な享元(ConcreteFlyweight)ロール:抽象的な享元ロールに規定されたインタフェースを実現する.内部ステータスがある場合は、内部ステータスにストレージスペースを提供する責任を負わなければなりません.エンティティオブジェクトの内部状態は、エンティティオブジェクトがシステム内で共有できるように、オブジェクトが置かれている周囲の環境とは無関係である必要があります.具体的な享元キャラクタは単純な具体的な享元キャラクタとも呼ばれることがあります.複合享元キャラクタは単純な具体的な享元キャラクタから複合されているからです.
l複合享元(UnshaableFlyweight)キャラクタ:複合享元キャラクタが表すオブジェクトは共有できませんが、1つの複合享元オブジェクトは複数自体が単純な享元オブジェクトの組合せに分解できます.複合エンティティロールは、共有できないエンティティオブジェクトとも呼ばれます.この役は一般的にはあまり使われません.
l享元工場(FlyweightFactoii)ロール:このロールは享元ロールの作成と管理を担当します.このロールは、メタオブジェクトがシステムによって適切に共有されることを保証する必要があります.クライアント・オブジェクトがエンティティ・オブジェクトを要求する場合、エンティティ・ファクトリ・ロールは、システムに要求に合致するエンティティ・オブジェクトがすでに存在するかどうかを確認する必要があります.すでに存在する場合、エンティティ・ファクトリ・ロールは、この既存のエンティティ・オブジェクトを提供する必要があります.システムに適切なエンティティオブジェクトがない場合、エンティティファクトリロールは新しい適切なエンティティオブジェクトを作成する必要があります.
lクライアント(Client)ロール:このロールは、すべてのエンティティオブジェクトの外部状態を自分で格納する必要があります.
内部状態と外部状態:メタオブジェクトの内部で環境によって変化しない共有部分をメタオブジェクトの内部状態と呼ぶことができ、逆に環境によって変化する共有できない状態を外部状態と呼ぶことができる.
汎用コード実装:
//   
interface FlyWeight {
    public void operation(String s);
}
//      
class ConcreteFlyWeight implements FlyWeight {
    private String str;//     
 
    public ConcreteFlyWeight(String str) {
        this.str = str;
    }
 
    public void operation(String s) {
        System.out.println("    :" + str);
        System.out.println("    :" + s);
    }
}
//     
class FlyWeightFactory {
    public FlyWeightFactory() {
    }
 
private Hashtable<String, ConcreteFlyWeight> flyWeights =
new Hashtable<String, ConcreteFlyWeight>();
 
    public ConcreteFlyWeight factory(String str) {
        ConcreteFlyWeight flyWeight;
        flyWeight = flyWeights.get(str);
 
        if (null == flyWeight) {
            flyWeight = new ConcreteFlyWeight(str);
            flyWeights.put(str, flyWeight);
        }
        return flyWeight;
    }
 
    public int getFlyWeightSize() {
        return flyWeights.size();
    }
}
public class Client {
    public static void main(String[] args){
       FlyWeightFactory factory = new FlyWeightFactory();
       FlyWeight flyWeight = factory.factory("a");
       FlyWeight flyWeight2 = factory.factory("b");
       FlyWeight flyWeight3 = factory.factory("a");
       flyWeight.operation("a fly weight");
       flyWeight2.operation("b fly weight");
       flyWeight3.operation("c fly weight");
       System.out.println(flyWeight == flyWeight3);
       System.out.println(factory.getFlyWeightSize());
    }
}

実行結果
    :a
    :a fly weight
    :b
    :b fly weight
    :a
    :c fly weight
true
2

ファセットモードのメリットとデメリット:
享元モードは非常に簡単なモードで、アプリケーションが作成したオブジェクトを大幅に減らすことができ、プログラムのメモリの使用量を低減し、プログラムの性能を強化することができますが、同時にシステムの複雑さを高め、外部状態と内部状態を分離する必要があります.また、外部状態は内部状態の変化に伴って変化するべきではありません.システムの論理的混乱を招く.
ファセットモードの適用シーン:
lシステムには多くの類似オブジェクトが存在する.
l細粒度のオブジェクトはいずれも近い外部状態を有し,内部状態は環境に関係なく,すなわちオブジェクトに特定のアイデンティティがない.
lバッファが必要なシーン.