Perl と Moo で、アドレス帳を CSV・JSON・YAML に書き出すデータエクスポーターを作っていく全10回の連載です。if/else で形式を切り替える素朴なスクリプトから始め、形式を足すたびに伸びていく分岐を見たところで、出力処理を形式ごとのクラスに分けます。Moo::Role による約束、処理を任せる DataExporter、実行中の差し替えと isa による確認、形式名からクラスを選ぶ exporter_for と足していき、YAML まで出せる完成版にまとめたあと、第10回で、作ってきたものが Strategy パターンだと名前を付けます。
各回は前の回のコードに手を入れていく作りなので、通して読むなら第1回からが早道です。このページは目次を兼ねた案内板です。入口は「どこから読むか」で、困りごとが決まっているなら「困りごとから探す」で、順に追うなら「全話一覧」で選んでください。
対象は、Perl の基本的な文法がわかり、Moo の has でクラスを書いたことがある方です。コードは Perl v5.36 以降(サブルーチンシグネチャ)で書いています。Moo が初めてなら、先に前シリーズ「変数とサブルーチンだけで書いていたPerlを、Mooのクラスで整理する全12回」の目次(このページの最後にリンクがあります)から読んでください。
どこから読むか
- 第1回 — if/else の素朴な実装から、設計が育つ順にたどりたいなら。第2回で、形式を足すと何が困るかを確かめる
- 第3回 — 出力処理をクラスに分けるところから入りたいなら。第4回で、Moo::Role で export を約束にする
- 第5回 — エクスポーターを持って処理を任せるクラスの形を見たいなら。前提は第4回の ExporterRole で、第6回・第7回で実行中の差し替えと型の確認を足す
- 第10回 — Strategy パターンの役割分担から入りたいなら。作ったクラスとの対応を先に見られる
困りごとから探す
形式を足すたびに、if/else が伸びていく
メソッド名が、エクスポーターごとにばらつきそう
- 第4回 — どのクラスも export を持っているのはたまたまで、次の人が別の名前を付けても止まらない
エクスポーターを使うコードを、別の場所でも使い回したい
- 第5回 — メイン処理がエクスポーターを選んで直接呼んでいて、別の場所で使うとそのコードを写すことになる
出力形式を、実行中に安全に切り替えたい
- 第6回 — 同じデータを CSV と JSON の両方で出したいのに、作ったあとでエクスポーターを替えられない
- 第7回 — エクスポーターでない値を入れても、export_data を呼ぶまでエラーにならない
どのクラスを new するかの分岐が、メインに残っている
- 第8回 — 出力はクラスに分けたのに、形式名を見てクラスを選ぶ if/else が消えない
部品はあるのに、1本のエクスポーターとして動かせない
- 第9回 — YAML を足して、csv・json・yaml を引数で選べるスクリプトにまとめたい
作った仕組みに名前があるのか知りたい
- 第10回 — 形式ごとのクラスを差し替えて使う設計が、Strategy パターンのどこに当たるのか言えない
- 第10回 — この設計が、開放/閉鎖原則などの SOLID 原則とどうつながるのか説明できない
全話一覧
- 第1回 CSVとJSONで書き出すPerlのデータエクスポーターを、一から作る。まずはif/elseで形式を切り替える【if/else】
- 第2回 形式を足すたびにelsifが伸び、CSVを直すだけでも全形式の処理に触れる。if/elseの肥大化を確かめる【条件分岐の悩み】
- 第3回 4形式の出力処理が1つのif/elseに詰まっている。形式ごとにexportを持つCsvExporterとJsonExporterに分ける【責務分離】
- 第4回 どのエクスポーターもexportを持っているのは、たまたまだ。Moo::Roleのrequiresで約束にする【ロール】
- 第5回 メイン処理がエクスポーターを直接呼んでいて、同じ出力を別の場所で使うとコードを写すことになる。処理を任せるDataExporterを作る【委譲】
- 第6回 同じデータをCSVとJSONの両方で出したいのに、作ったあとでエクスポーターを替えられない。exporterをrwにして実行中に切り替える【実行時の切り替え】
- 第7回 エクスポーターでない値を入れても、export_dataを呼ぶまでエラーにならない。isaでExporterRoleかを確かめ、入れた時点で止める【isa】
- 第8回 出力はクラスに分けたのに、どのクラスをnewするかのif/elseがメインに残っている。形式名から選ぶexporter_forを作る【Factory的な選択】
- 第9回 部品はそろったのに、まだYAMLで出せない。YamlExporterを足し、全部を1本のエクスポーターにまとめる【統合】
- 第10回 形式ごとのクラスを差し替えて使う設計には、Strategyという名前がある。作ったクラスを3つの役割に当てはめる【Strategyパターン】
必要なモジュール
JSON::PP はコアモジュールです。Moo と YAML::Tiny はインストールしてください。
| |
