取りあえず何か創る

ソフトウェアエンジニアだけど仕事以外でも何か作りたくなったので、主にその記録のためにブログを開設しました。

読書記録 良いコード/悪いコードで学ぶ設計入門

0. この投稿の概要

  • 最近話題の「良いコード/悪いコードで学ぶ設計入門」を読んだので学んだことをまとめます。どれくらいのレベル感の内容が説明されているか知るための参考になれば幸いです。

1. 学んだこと

クラス設計の基本

  • 完全コンストラクタ: 初期化時点でインスタンス変数を指定し終え、その後はsetterなどで値を変更しない。値を更新する必要があれば新しくインスタンスを生成して返す。→思わぬ場所で値が変更されることを防ぎ、実行結果が毎回同じになるためテストもしやすくなる。
    • Pythonでも3.8からFinal型注釈を付けられるようになっています。 PEP 591 – Adding a final qualifier to typing | peps.python.org
    • ローカル変数や引数も基本的には不変にしておくことが推奨されています。可変にするのは大量のデータ処理などでパフォーマンスに影響があるケースなど。
    • getterやsetterを実装することはカプセル化ではない。
  • 値オブジェクト: 値をプリミティブ型ではなくクラスとして表現する。これにより不正な値を防ぐことができる。また、その値に関する計算も備えさせると、そのロジックが色々な場所に実装されることを防げる。
    • 基本的にはインスタンス変数を用いるメソッドをクラスに持たせ、ログ出力用のような汎用的なもの以外でstaticメソッドを避ける。
    • 目的別に異なる初期化をするためのファクトリメソッドもstaticメソッドとして実装される。
  • コレクション型についても同様にコレクションとそれを操作するメソッドをクラスにまとめる(ファーストクラスコレクション)。
    • Pythonではリストの要素の変更を禁止するメソッドは見当たりませんでした。代わりにcopyメソッドで別のオブジェクトとして返せばいいかと思います。
  • サブクラスはスーパークラスに大きく依存するため、継承は安易に使うべきではない。継承より委譲、コンポジションとして使いたいクラスをもたせると変更の影響を受けにくい。

ネストを浅くするテクニック

  • 早期リターンでif文のネストやif-else文をすっきりさせる。
    • C言語の一部の規約では関数末尾以外でのreturnを禁止されているため、自分は早期リターンに心理的な抵抗がありましたが、今後はもっと活用しようと思います。
  • 種類毎に処理を切り替えたい場合はswitch文の代わりにinterfaceを用いて実装する(ストラテジパターン)。mapから使いたいインスタンスを持ってきて、共通のメソッドをコールする。
  • 複数の条件をチェックしたい場合はポリシーパターンを使う。これは条件判定のinterfaceを作り、それを元に具体的な条件を1つ1つ実装する。ルールを集約するクラスに必要な条件をコレクションとして持たせてfor文で全て確認する。

名前設計

  • たとえ現実世界のオブジェクトが1つだとしても、関心事や目的に応じてより具体的なクラスへ分割する。例: Userを個人認証のためにPersonalAccount、特徴表現のためにProfileとして定義する。
  • 開発中の会話の中で頻発するキーワードや形容詞はそのままコード上のクラス名などに実装する。
  • Manager, Processor, Controllerという単語をclass名に入れると巨大なクラスになりがち。具体的にやることで名付けるべき。
  • 「動詞+目的語」のメソッドに注意。この場合目的語の概念を表現するクラスを作り、そのクラスに動詞1語のメソッドを追加するとよい。

2. 総評

  • オブジェクト指向プログラミングにまだ自信のない自分としては、参考になるテクニックを見つけることができました。ただ章と章の結びつきが弱く、ストーリー性が薄いためTips集のような印象を受けました。逆に言えばどの章からでも読み始められる利点はあるのですが…
  • interfaceの理解は特に重要だと思いますが、本書のように初心者向けの本でわかりやすい説明が書かれたものは少ないように思います。言語の本は機能だけの説明になりがちですし、OOPの本でさえポリモーフィズムの説明はありますがそれが実践の場でどのように役立つのかイメージしづらいです。
  • そういった意味でJavaエンジニアの初心者には文法を学んだ次の一冊としておすすめします。初心者にとって他言語で書かれた本はとっつきにくい所ではありますが、オブジェクト指向の言語を使うのであればJavaエンジニア以外も選択肢に入れて良いと思います。

3. その他の参考書

  • 現場で役立つシステム設計の原則: 業務システムを例としたシステム設計の入門書です。言語はJavaで、データベースやUIなどについても説明されているため本書よりも範囲が広いです。本書でも紹介されていますが、業務システムを開発するなら次に読む本として丁度いいかと思います。