LoginSignup
26
11

More than 3 years have passed since last update.

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

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

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

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

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

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

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

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

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

26
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
11