Featured image of post 「実行」と「記録」が別の関数で、片方の呼び忘れが防げない。Drop で必ず記録させる【RAII】

「実行」と「記録」が別の関数で、片方の呼び忘れが防げない。Drop で必ず記録させる【RAII】

水やり関数と記録関数を別々に呼ぶ作りでは、記録の呼び忘れや二重実行をコードが止められない。当番を表す値がスコープを抜ける瞬間に記録まで済ませる Drop トレイト(RAII)を Rust で実装します。

連載 コード庭師 (第4話 / 全12話)
Featured image of post 箱の中に箱がある船倉の重さを、型判定の再帰で数え落とす。単品も集合も同じ口で答えさせる【Composite】

箱の中に箱がある船倉の重さを、型判定の再帰で数え落とす。単品も集合も同じ口で答えさせる【Composite】

船倉の総重量が、入れ子の箱を is_a? で判定する手書きの再帰で数え落とされ、2.8t ずれていた。単品と集合が同じ weight で答える Composite に引き直し、任意の深さを1回の呼び出しで集計する設計を Ruby で実装します。

連載 コード航海士 (第12話 / 全12話)
Featured image of post 座標も燃料も生の Float で持ち回り、単位や座標系の取り違えが静かに通る。値を不変の小さなクラスでくるむ【Value Object】

座標も燃料も生の Float で持ち回り、単位や座標系の取り違えが静かに通る。値を不変の小さなクラスでくるむ【Value Object】

座標と燃料量が裸の Float のまま渡され、単位や座標系を取り違えても数値としては通ってしまう。値を不変の小さなクラスにくるむ Value Object を、Ruby 3.2 以降の Data.define と Minitest で実装します。

Featured image of post 欠測センサーの nil チェックが6か所に並び、1か所忘れると NoMethodError になる。「何もしない」実装で分岐を消す【Null Object】

欠測センサーの nil チェックが6か所に並び、1か所忘れると NoMethodError になる。「何もしない」実装で分岐を消す【Null Object】

一部のセンサーが欠測するだけで、集計側に if sensor.nil? が6か所並んでいた。本物と同じ口を持つ「何もしない」NullSensor で分岐を消し、隠してよい nil と隠してはいけない nil の線引きまで Ruby と Minitest で解説します。

Featured image of post 手順書は「点検を1回呼ぶ」の1行なのに、コードは11手続きが7か所に散らばる。段取りを1つの窓口に集める【Facade】

手順書は「点検を1回呼ぶ」の1行なのに、コードは11手続きが7か所に散らばる。段取りを1つの窓口に集める【Facade】

同じ11手続きの呼び出しが7か所に散らばり、下位の順序が変わるたびに全部を直す羽目になる。段取りを PreflightCheck に集約する Facade を、キーワード引数の既定値による依存注入で Ruby に実装します。

Featured image of post 操作を打ち間違えても、実行済みの操作を戻す手段がコードにない。動作をオブジェクトにして、戻し方も持たせる【Command】

操作を打ち間違えても、実行済みの操作を戻す手段がコードにない。動作をオブジェクトにして、戻し方も持たせる【Command】

キーストロークの打ち間違いで実行済みの yaw や thrust を戻せず、日誌にも「yaw変更」としか残らない。動作を実行と取り消しを持つオブジェクトにし、履歴スタックで巻き戻す Command を Ruby で実装します。

Featured image of post 状態を文字列と巨大な case 文で回し、許されない遷移を通してしまう。状態をクラスにして、書けない場所を作る【State】

状態を文字列と巨大な case 文で回し、許されない遷移を通してしまう。状態をクラスにして、書けない場所を作る【State】

接舷シーケンスの状態を文字列と case 文で管理し、書き漏らしから許されない遷移が通る。状態をクラスに引き上げ、飛び越しを構造的に書けなくする State を Ruby で実装します。

Featured image of post 保冷・防振・保険の組み合わせごとにクラスを作り、掛け算で増えていく。オプションを1枚ずつ重ねる【Decorator】

保冷・防振・保険の組み合わせごとにクラスを作り、掛け算で増えていく。オプションを1枚ずつ重ねる【Decorator】

積荷のオプション3種を組み合わせごとのサブクラスで表すと、クラス数が掛け算で増える。オプションごとのラッパーを重ねる Decorator に引き直し、継承と合成の使い分けを Ruby で解説します。

Featured image of post 港ごとに通信規格が違い、増えるたびに交信コード本体の case 分岐を開く。違いを通訳に押し込む【Adapter】

港ごとに通信規格が違い、増えるたびに交信コード本体の case 分岐を開く。違いを通訳に押し込む【Adapter】

港が増えるたびに、交信コード本体の case 分岐で方言を吸収する作りになっていた。相手は変えられないので、港ごとの通訳を間に立てる Adapter を、Ruby の委譲とダックタイピングで実装します。

Featured image of post プローブの型を足すたび、散らばった case 文を全部直す羽目になる。生成の窓口を1つにまとめる【Factory Method】

プローブの型を足すたび、散らばった case 文を全部直す羽目になる。生成の窓口を1つにまとめる【Factory Method】

生成の case 文が通常発進と緊急再発進の2か所に散らばり、新型を足すたび修正が連鎖する。生成を専用の窓口に隔離する Factory Method を、クラスもオブジェクトである Ruby の特性を活かして実装します。