プログラムを書く時の雑メモ
前提
日頃、Ruby on Railsを使用してWeb APIを書くことが多く、それを前提としている。
クラスの設計について
レイヤーを跨いでいないか
MVCであれば、それぞれのレイヤーの責務を逸脱していないか。外部APIと連携をするインフラ層を作る場合、modelがインフラ層へ浸食してはいけない。その逆も同じ。
対象とする範囲が大きすぎる
抽象度が高すぎるクラスに様々な関心事が集まりすぎていないか。ActiveRecordの場合、modelとテーブルが密結合になっているので、カラム数が多い、多くなりそうな概念には注意。
依存関係の数
依存元が多い場合、変更がしにくくなることを理解しておく。依存先が多い場合、複数の関心事が混在していないか注意。
依存関係の方向
モジュール間での依存の方向を整える。相互依存は作らない。
メソッドの設計について
使いやすいインターフェースを考える
仕様がシンプルであること。引数の数が多すぎないこと。引数が増えてきた際は引数をグルーピングできないか検討する。そもそもクラスやメソッドの責務が間違っているケースも考えられる。あとは、使う側から見た振る舞いが反映された命名であること。内部実装を説明するような命名は避け、あくまで使う側から見た振る舞いを意識する。
クラスの責務を逸脱していないかを考える
クラスが持つデータ(プロパティ)に関連しない処理を持っていないか。
入力と状態に応じて網羅的に振る舞いを考える
基本的に入力と状態に応じて、振る舞いは決まるはずなので、パターンを洗い出して考える必要がある。
複数回実行された場合の振る舞いを考える
意図せず複数回処理が実行されるケースは容易に想像される。UPDATE、DELETEであれば冪等に作られているか、POSTであれば重複データが発生しないか。
同時実行した場合の振る舞いを考える
同時実行のタイミングによってデータ不整合が発生する場合、排他制御を行う。
最悪ケースを考える
どの箇所で意図しないエラーが起きたとしても、リカバリーできる策を考えておく。
プロセスについて
小さい部品を作り、組み上げていく
トップダウンに作っていくか、ボトムアップに作っていくかの話でボトムアップなアプローチをよく採用する。全体の構成をイメージして部品を見出し、小さなプログラムとテストを書く。テストファーストには拘らないが、「この部品はどう使われるのか」は常に意識する。部品を先に作り、責務を閉じ込めることで、依存元の検証パターンを減らすことができ、使う側から見た振る舞いのみに焦点を当てて次の開発を進めることができる。
小さいサイクルで高速に検証を回す
何か修正を加えた際、自分の目で確認するより、テストを回して確認する方が確実に正確で速い。ただし、偽陰性には注意しておく必要があり、確実に落ちるテストを一度通しておく。
その他
処理の計算の重さを考える
ループ処理での実行回数、SQLにおけるN+1問題など。使い回すことができるデータであれば、メモ化も有効。
空行や記述の順番を工夫してグルーピングを行い、整理しながら書いていく
ある程度意味のあるまとまりを持たせることで、コードの構造化を行う。可読性の向上、リファクタリングのヒントを得ることができる。
不要なロジックを書かない、見つけたら消す
例えば、不安だからnilチェックを入れておく、のような実装。実装ミスであればエラーで落ちて気づけることに、気づけなくなってしまう。