Flyweightパターンの解説

Flyweightパターンとは、メモリを節約するために、同じようなオブジェクトを使い回すデザインパターンだ。これにより、同じ状態を共有することで、大量のオブジェクトを効率よく扱うことができる。

たとえば、ゲームの中で木や岩など、同じ形のオブジェクトをたくさん配置する場合、このパターンが役立つ。

では、サンプルコードを一緒に見ていこう。

解説

例えば、何千個もの木を描くとき、全ての木を一つずつ作るのではなく、木の共通部分(形や色など)を使い回して、効率的に木を生成するんだ。

Step 1: 共通のデータを持つクラスを作る

まず、たくさんの木を描くために、木の「種類」を表す `TreeType` というクラスを作る。このクラスは、形や色などの共通部分を持つんだ。木の種類が同じ場合、同じインスタンスを使い回せる。


// 木の種類を表すクラス(フライウェイト)
class TreeType {
  constructor(name, color, texture) {
    this.name = name;
    this.color = color;
    this.texture = texture;
  }

  displayTree(x, y) {
    console.log(
      `${this.name}の木を位置(${x}, ${y})に描画しました。色: ${this.color}, 質感: ${this.texture}`
    );
  }
}
      

Step 2: 木の種類を管理する工場クラスを作る

次に、たくさんの木を効率的に作るため、木の種類を管理する `TreeFactory` を作ろう。この工場クラスは、すでに同じ種類の木がある場合は、新しく作らずに既存の木の種類を返す。


// 木の種類を管理する工場クラス
class TreeFactory {
  constructor() {
    this.treeTypes = {}; // すでに作った木の種類を保存する
  }

  getTreeType(name, color, texture) {
    const key = `${name}-${color}-${texture}`;
    if (!this.treeTypes[key]) {
      this.treeTypes[key] = new TreeType(name, color, texture);
    }
    return this.treeTypes[key];
  }
}
      

Step 3: 個別の木を作成するクラスを作る

木自体の位置や特定のデータを管理する `Tree` クラスを作るよ。このクラスは、木の種類(`TreeType`)を使い回してメモリを節約する。


// 個別の木を表すクラス
class Tree {
  constructor(x, y, treeType) {
    this.x = x;
    this.y = y;
    this.treeType = treeType;
  }

  display() {
    this.treeType.displayTree(this.x, this.y);
  }
}
      

Step 4: 木をたくさん描く

最後に、`TreeFactory` を使って、たくさんの木を効率よく生成して描画する。木の種類が同じ場合、すでに作った木の種類を使い回すから、メモリを節約できるんだ。


// 木の工場を作成
const factory = new TreeFactory();

// 木を生成
const forest = [];
forest.push(new Tree(10, 20, factory.getTreeType("オーク", "緑", "滑らか")));
forest.push(new Tree(30, 40, factory.getTreeType("オーク", "緑", "滑らか")));
forest.push(new Tree(50, 60, factory.getTreeType("松", "濃緑", "針状")));

// 木を描画
forest.forEach(tree => tree.display());
      

Step 5: メモリ節約の確認

上記のコードでは、同じ種類の木は `TreeFactory` によって一度だけ作られ、それを使い回している。これにより、大量の木を作る場合でも、メモリの無駄遣いを防ぐことができるんだ。

Flyweightパターンの重要なポイント

これでFlyweightパターンの解説は終わりだ。
このパターンを使うと、オブジェクトの数が非常に多くなる場面でメモリ消費を抑え、効率的に動作させることができる。