@nqounetです。
RPG のモンスターを Perl と Moo で大量に作りながら、オブジェクトのコピーを学ぶ全6回の連載です。スライムを new() で10体作ると30行以上になる、という困りごとから始め、MooX::Clone の clone() で量産し、浅いコピーで武器が共有される罠にはまり、Storable::dclone() の深いコピーで直します。最後に、作ってきたものが GoF の Prototype パターンだったと名前を付けます。
各回は前の回のコードを引き継ぐので、第1回から順に読むのが早道です。このページは目次を兼ねた案内板です。入口は「どこから読むか」で、困りごとが決まっているなら「困りごとから探す」で選んでください。
前提
Mooで覚えるオブジェクト指向プログラミングの続編です。Moo の基本(has、new、extends)が分かっていれば読めます。
どこから読むか
- 第1回 — Moo のオブジェクトを大量に作る話を最初から追うなら。new() で10体作ると、なぜ苦しくなるのか
- 第2回 — 同じ属性のオブジェクトを何体も作っているなら。MooX::Clone の clone() で、30行が3行になる
- 第4回 — clone() したのに、元のオブジェクトまで変わってしまったなら。浅いコピーが起きる仕組み
- 第5回 — 入れ子のオブジェクトを丸ごと複製したいなら。前提は第4回の、浅いコピーの問題
困りごとから探す
- 第1回 — 同じ属性を毎回 new() に書くのが面倒で、修正も10箇所に及ぶ
- 第2回 — 1体作ったオブジェクトを、コピーして量産したい
- 第3回 — コピーしたあとで、色や HP だけ変えたバリエーションを作りたい
- 第4回 — clone() したあとで属性を変えたら、元のオブジェクトも変わった
- 第5回 — 参照を持つオブジェクトを、元と完全に独立した形で複製したい
- 第6回 — Prototype パターンと Factory Method の違いを知りたい
全6回の目次
第1回 - Moo で同じスライムを10体作ると、new() の属性指定だけで30行以上になる
同じ属性のスライムを10体作るだけで、同じ指定を10回書くことになります。冗長になる、修正が10箇所に及ぶ、という困りごとを体験する、シリーズの出発点です。
第2回 - Moo のスライムを MooX::Clone の clone() で複製すると、30行が3行になる
MooX::Clone を use して clone() を使い、ベースのスライムを複製して量産します。HP の変更もベース1箇所で済みます。
第3回 - clone() したスライムの色だけ変えて、赤・青・金の色違いを量産する
複製してから色や HP だけ変えて、色違いや強化版を作ります。コピーは元と独立しているので、元のスライムは変わりません。
第4回 - clone() したドラゴンの武器を書き換えたら、元のドラゴンの武器も変わった
武器を持つドラゴンを複製して武器を変えると、元のドラゴンの武器まで変わります。浅いコピーが、参照を共有する仕組みを確かめます。
第5回 - 浅いコピーでドラゴンの武器が共有される問題を、Storable::dclone() の深いコピーで直す
Storable::dclone() で入れ子のオブジェクトごと複製し、元と完全に独立したコピーを作ります。MooX::Clone との使い分けも整理します。
第6回 - clone() で量産してきた仕組みは、GoF の Prototype パターンだった
ここまで作ってきたものに、Prototype パターンという名前を付けます。Factory Method との違いも比べます。
シリーズの流れ
graph LR
A["第1回<br>new()の限界"] --> B["第2回<br>clone()導入"]
B --> C["第3回<br>バリエーション作成"]
C --> D["第4回<br>浅いコピーの罠"]
D --> E["第5回<br>深いコピーで解決"]
E --> F["第6回<br>Prototypeパターン"]
style A fill:#fff3cd
style B fill:#d1e7dd
style C fill:#d1e7dd
style D fill:#f8d7da
style E fill:#d1e7dd
style F fill:#cfe2ff
