Undo・Redo・マクロまで備えた簡易テキストエディタを、Perl と Moo で全10回かけて作ります。第1回は text 属性に文字列を持ち、指定位置に挿入する insert と、指定位置から指定の文字数を消す delete だけの Editor クラスを作り、元に戻す機能がまだ無いところから始めます。
Perl と Moo で設定ファイルマネージャーを作りながら、モジュールごとに new した設定が食い違う問題に出会い、インスタンスを1つにまとめ、最後に Singleton パターンだと名前を付ける全5回の連載の目次です。どこから読むか、困りごとからも選べます。
第4回で作った state $instance と instance() は、GoF の Singleton パターンの核心にあたる。定義と構造に Config の実装を当てはめ(外からの new を防ぐ部分は未実装)、どこからでも同じインスタンスに届く利点と、テストの間で設定が残る・依存が見えにくくなるといった注意点、向いている場面を整理します。
引数で渡し続けず、グローバル変数も使わずに、メインと Logger で同じ Config を使いたい。state 変数で唯一のインスタンスを抱える instance() を Config に足し、両方の呼び出しを Config->instance() に替えて、メインで OFF にしたデバッグログが出なくなるのを確かめます。
Logger モジュールの中で Config->new すると、メインスクリプトで debug を 0 にしても、Logger は設定ファイルを読み直して ON のままログを出す。new するたびに別のインスタンスができることを実行結果と図で確かめ、引数で渡す・グローバル変数にする、の2案では何が困るかを見ます。
設定値をコードに書いている限り、デバッグモードを切り替えるだけでもスクリプトを開いて直すことになる。key = value 形式の config.ini を1行ずつ読み、空行とコメントを飛ばして正規表現で解析する load_config と、ハッシュに値を出し入れする set・get を Config に足します。
アプリ名・バージョン・デバッグモードを変数でスクリプトに直書きしていると、どこに何の設定があるのか見渡せない。Perl と Moo の has で3つの設定を Config クラスに集め、読み取り専用(ro)にして、default の値を new の引数で上書きできるようにします。
Perl と Moo で本棚アプリを作りながら、内部の配列を使う側に見せずに本を1冊ずつ取り出す仕組みを組み立て、最後に Iterator パターンだと名前を付ける全5回の連載の目次です。どこから読むか、困りごとからも選べます。
第1回から作ってきた BookShelf・BookIteratorRole・BookShelfIterator は、GoF の Iterator パターンそのものだった。Iterator・ConcreteIterator・Aggregate・ConcreteAggregate の4役に当てはめ、ReverseBookShelfIterator を1つ足して、ループを変えずに逆順で巡回します。
BookShelfIterator->new(bookshelf => $shelf) と書く限り、使う側は走査クラスの名前に縛られる。BookShelf に iterator() メソッドを足して自分用の走査オブジェクトを返させ、使う側は $shelf->iterator だけを知っていればよい形にします。
インデックスを数えるループを使う側が書いている限り、本棚の作りが変わればそこも直すことになる。Moo::Role の requires で has_next と next を約束させ、BookShelfIterator に走査の位置と手順を集めて、while ループ1つで全冊を回します。
本棚の本を一覧表示しようと $shelf->books->@* と書くと、中身が配列であることに使う側が依存する。get_length と get_book_at に変えても「番号で取り出せる」という前提は残る。内部の作りを変えたときに何が壊れるかを2つのループで比べます。
本棚には何冊もの本が並ぶ。複数の本を1つのオブジェクトにまとめて持つ「集合体」から始める。Perl と Moo で title と author を持つ Book クラスと、本を配列で抱える BookShelf クラスを作り、add_book・get_book_at・get_length で本棚を操作します。
天気を返す Moo のクラスを1つ作り、メソッド名も戻り値も違うサービスを足し、包んで同じ呼び方に揃え、3つを1つのループで回す。最後にそれが GoF の Adapter パターンだと名前を付ける全5回の案内板です。
第3回・第4回の橋渡しクラスは、GoF の Adapter パターンだった。Target・Adaptee・Adapter・Client の4役をこの連載のクラスに当てはめ、既存コードを変えずに済む理由と、Facade・Decorator・Proxy との違いを表で比べる。全5回の完成コードも載せます。