9
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

マンガでわかる Flyweight

BB6E8DB9-E842-49B7-A56B-274D2D9D6675.png

なんだか普通にためになるマンガを描いてしまった。...いや、何を言ってるんだ、これでいいのか。

Flyweight パターンは言葉から意味を連想しにくいパターンのひとつですが、簡単に言えば、等価なオブジェクトを共有するのが、軽量化の最良の手ですよというだけの話です。

たとえば、データベースのレコードの関係は、いくらでも関係を辿れる木構造になったりします。愚直にオブジェクトでツリーを構築してしまうと、意味が同じレコードが複数箇所に現れることがあります。同じはずのオブジェクトが異なるインスタンスになってしまうと、単にそのインスタンスの重複ぶんが無駄になるだけでなく、そこから先に伸びる関係全体も、無駄な重複としてメモリを圧迫すると考えられます。

また、無駄な重複は、操作の回数の無駄にもつながります。オブジェクトを共有していれば 1 回で済むことを、何度も処理しなければならないかもしれません。この無駄な処理には、ネットワークを介した遅延ロードなども含まれます。

ゲームの場合で例えると、画面上に複数登場する同じ絵柄のパーツが、いちいち個別に画像データのコピーを持つのは無駄ですね。画面上の座標と画像へのポインタしか持たない、軽量なオブジェクトをたくさん生成するのが普通です。

もちろん、キャッシュがあると時間差での変化を追従できない心配があるなどの理由で、ぜんぶ再評価したい気持ちになることもあるでしょう。が、負荷を甘く見ていると、思ってもいなかった無駄は再帰的に広がっていきます。「n + 1」問題はすぐに、「n + 1 の m 乗問題」に化けるのです。

エンティティを再利用できるリポジトリを持った ORM ではなく、問い合わせごとに、つねに新規オブジェクトを生成する ActiveRecord を使う場合、Flyweight を意識的にやらないといけないので、注意が必要です。

コンピューターのリソースは有限なので、共有でよい範囲をうまく見定めて、すでにあるオブジェクトをうまく再利用しましょう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
9
Help us understand the problem. What are the problem?