読書メモ CleanCode

Clean Code アジャイルソフトウェア達人の技

Clean Code アジャイルソフトウェア達人の技

ついにこの本を読むときが来た。電車で読もう。(でかいんで邪魔だが)

第3章 関数

関数では1つのことを行うようにせよ。その1つのことをきちんと行い、それ以外のことを行ってはならない。

まあそこはなんとなくわかるけど、問題は何を持って1つのこととするのか。

関数が1つ以上のことをしていないか調べる、もう1つの方法は、その関数の実装の中から単なる言い換えではなく別の関数を抽出できるかを調べることです。

関数内の処理の抽象レベルが合ってるかということ?。それならなんとなくわかりそう。

フラグ引数

フラグ引数は汚い方法です。〜 これは、ただちにメソッドのシグネチャをわかりにくくします。

これは良くやってしまっている。。確かに保守性下がっちゃうかもしれないのでなるべく避けよう。

第4章 書式化

縦方向の書式化

インスタンス変数は、これに対しクラスの頭で宣言するべきです。これは、垂直距離を広げることにはなりません。 垂直距離を広げるとは、密接に関連した概念を、垂直方向に離して配置することの、アンチパターン

上記引用は、インスタンス変数はそれでいいよと言ってる。使用するメソッドなりの直前で宣言しなくて良い理由は、ちゃんとクラス設計していれば、全てではないにしても、非常に多くのメソッドから使用されるはずだから。

第6章 オブジェクトとデータ構造

データ抽象化

単に変数との間に関数の層を入れるということは、実装の隠蔽ではありません。実装の隠蔽とは抽象化なのです!

単純にゲッターとか用意すりゃいいわけじゃないぞと言っている。何を外に伝えたいかを考えるのが、データの抽象化だということ?

データ/オブジェクトの非対称性

データとオブジェクトは相反する概念。 データ型の追加より、関数の追加が多いシステム(そんなない)では手続き型とデータ構造の方が適している。

混血児

オブジェクトとデータ構造との混血児は作ってはいけない。関数の追加もデータ構造の追加も困難にする。

第7章 エラー処理

(例外処理における)tryブロックはあたかもトランザクションに見えます。

まさに! (例外機構は本当に良く出来たアーキテクチャだと思う。はじめはC#なのか?)

非チェック例外を使用する

チェック例外を完全にdisっている。

チェック例外の代償は解放閉鎖原則に違反する点です。

下位のメソッドのシグネチャ変更が上位に影響すると。 ただこれは若干疑問。例外シグネチャも通常のメソッド間のIFだとすれば、普通では?ハンドリングを強制できるメリットはでかい気がする。。

nullを渡さない

nullを許容しないメソッドの挙動として、アサーションを推奨。

assert arg != null : "arg should not be null" 通常のnullチェックだと、実行時エラーになるので、問題は解決してるとはいえない。

第9章

テストをきれいに保つ

汚いテストを持つということはテストを持たないことと同値だということ

たしかに。(前のプロジェクトが正にそうで、リファクタリングの補助になっておらず、むしろ阻害していた。。)

クリーンテスト

テストをきれいに保つには、読みやすさが最も大事。テストコードもちゃんと設計しよう!

1つのテストに1つのアサート

いろいろあるけど、

確実にいえることはアサート文の数をなるべく少なくするべきということです。

厳しすぎる規範は微妙だけど、やれるならやりたいよね。という感じ。 ここは、テスト書いてていつも悩む部分。1テスト1アサートにしようとすると、コードの重複しがちになる。。。

1つのテストでは1つの概念を扱う

これは激しく同意。 例えば、日付の加減算関数のテストで、いろんな条件を一回でしちゃってるとかはダメ。分ける!

F.I.R.S.T.

  • 高速である
  • 独立している
  • 再現性がある
  • 自己検証可能

長いファイルを読まないとテスト結果がわからないようなテストは避けるべき。

  • 適時性がある

テストは製品コード直前にあるべき。

第9章 クラス

こっからひとつ段階があがるかんじ。重要そう!

カプセル化

変数、ユーティリティ関数を private とするのを好みますが、それに固執するわけではありません。テストからアクセス可能とするため、〜 protected にする必要がある場合もあります。筆者らはテストを優先します

クラスは小さくしなければならない!

理由はいわずもなが。問題はどうやって小さくするか?

  • クラスの大きさ≒責務の数

クラス名は、そのクラスの責務を表すべきです。〜 あいまいな名前は、責務が不適当に集められているサインです。

やっぱり、名前付け≒設計ってこと。

単一責務の原則

SRP (Single Responsibility Principle)

クラス、モジュールは変更の原因となるものが1つでなければなりません。 〜 責務(変更の原因となるもの)を探すことは、コードの抽象化を高めることに役立ちます。 〜 システムは、少数の大きなクラスではなく、多数の小さなクラスで構成する必要があります。

凝集性

初耳なのでメモ。

あるメソッドが操作する(インスタンス)変数が多いほと、そのクラスのメソッドの凝集性は高いといえます。

高い方が、全体としてひとつのロジックを表してるので適切ということらしい。

変更のために最適化する

洗練されたシステムは、変更に対するリスクが最小限となるよう構成される。

変更から切り離す

具象クラスに依存していると、詳細が変更されたときに影響を受けるリスクがあります。

インタフェースと抽象クラスを導入しましょう。

箸休め

ちょっとメモ

  • SRP 単一責務の原則
  • OCP 開放/閉鎖の原則
  • DIP 依存関係逆転の原則

今まで出てきたものですごく気になる、大事そう。。書籍「アジャイルソフトウェア開発の奥義[PPP]」に詳しくあるらしい。

アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技

アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技

本書はその続編とも言えるらしいので、先に読みたくなってきてしまった。ポチろうかな。。。

第11章 システム

システムを使うことと、構築することを分離する

例えば、オブジェクトの生成を利用する際に行っているなど。あらゆる場面でそのオブジェクトが正しいと言える?テストのときは?

依存性注入

オブジェクトの利用と生成を分離するための強力な仕組み!!