テストはコンパイルも実行できるドキュメントである。テストは「常に最新の用例集」としての役割を果たす。ホワイトボックステスト。プログラマが読めるようにプログラム言語で記述される。ブラックボックステスト。顧客が読めるように顧客自身が設計した言語で記述される。1回分のイテレーションの仕様をとり上げて、受け入れテストのフレームワークを作るのはそれほど困難ではない。作っただけの見返りは得られる。Refactoring(リファクタリング)書き上げるモジュールも、保守するモジュールもすべてリファクタリングするべきである。ダイアグラムを使うことが適切でない時もある。それは、ダイアグラムを検証するコードを作らず、それに従ってプログラムを作ろうとする場合。ダイアグラムを使うことは問題はないが、できたダイアグラムが最適なものであると思い込んでしまうことに問題がある。最良の設計は、まずテストを用意し、小さなステップの積み重ねで生まれていくもの。Design(アジャイル設計)以下は、貧弱な設計の兆候である。以上の原則に違反している可能性が高い。下記は、オブジェクト指向設計の原則である。Design?(アジャイル設計とは?)アジャイル設計とは、ソフトウェアの構造や可読性を向上させるために、原則、パターン、プラクティスを継続的に適用する行為である。仕様変更にも素早く対応できる。仕様が最も変わりやすいものだということはみんなが知っている。仕様変更が原因で設計が劣化していくなら、それは自分たちの設計やプラクティスが間違っている。仕様は変化するものであり、設計もその変わっていくものなので、アジャイルなチームは初期の設計に時間をかけるようなことはしない。そこに時間をかけるのではなく、ユニットテストや受け入れテストをできるだけ頻繁に行うようにして、変更しやすいように保つべき。新しい要求、仕様変更が来た時点で、今後の変更にも対応できるように設計を改善するのがよい。先を見越して設計をするのは工数の無駄に終わることが多いし、逆に不要なコードが含まれて理解が難しいコードになってしまう。アジャイルでいう「柔軟」とは、どちらかというと設計のシンプルさに重点を置いている。汎用性を揚げようとすると、ほとんどの場合、永遠に使われないモジュールであふれかえって複雑なものができあがる。クリーンなコードってなんや?シンプルなコードとは違うのか?無駄なコードがない。バグっぽいコードがないってことではないか。後からたぶん仕様変更があると分かっていて、その対応をあらかじめいれておかないと、変更するときに二度手間にならない?確実に仕様変更があると分かっているのならあらかじめ対応をいれておけばよいし、その判断は期待値によるのでは?ただ、あらかじめ対応コードを入れておく方法は、逆に仕様変更がなかった場合に意味のない無駄なコードを残すことになるリスクや、結局あとからコードを消さないといけなくなるリスクが常にある。アジャイル設計はプロセスではないのか?翻訳ミスですね。アジャイルプロセスって言葉もあるしね。単一のクラスは単一の責務だけを持つべきであるクラスが複数の責任を持っていることの弊害そのクラスを使うモジュールが必要のない部分まで含んでしまう。そのクラスを変更すると、そのクラスを使用しているモジュールをリビルド、再テスト、再ロードしないといけない。永続性のあるシステム(データベースなど)と、ビジネスルールは、単一クラスに絶対に混ぜてはいけない。永続性のあるシステムはあまり変化しないけど、ビジネスルールは頻繁に変化する。永続性のあるシステムとビジネスルールはまったく違う理由で変化する。言っているように、必要になってから行えばよい。「永続性のあるシステム」と「ビジネスルール」を分離する必要性がいまいち分からない。なくてもごく基本的な考え。分離していないと、あまり変更のない部分だけを利用したいクラスでも無駄なリビルドやテストが頻繁に発生してしまう。永続化部分とビジネスロジックが分かれていないと、ビジネスロジックのユニットテストを記述することが困難になる。するには、依存の矢印があると無理なので「抽象」を使用する。どの部分をどのように抽象化すべきかは、求められているシステムによって異なる。むやみに適用すべきではない。抽象をむやみに使用すべきではない。抽象を使いすぎるとコードは複雑になる。抽象化にはある程度の時間がかかる。抽象化は、変化が起こる部分(変化しやすい部分)が明らかになってから行えばよい。前世紀の考え方では、あらかじめ抽象を仕込むこと=柔軟と考えられていたがこれは間違いである。抽象化には、将来の仕様変更をある程度予測する洞察力が必要だ。その予測はほとんどの場合外れる。抽象化されたクラスは邪魔でしかなくなる。変化が起こってから抽象化を行うのであれば、変化の可能性はプロジェクトの早めに知ることができたほうがよい。そのためには、テストファーストで開発をする。短いサイクルで開発し、顧客へのリリース頻繁に行う。重要な機能から優先的に開発を進める。テストファーストでどうして変化の可能性を早く知ることができるのか?変化の可能性を知るというよりは、あらかじめテストで想定されうる入力を洗い出すことで、早い時点で抽象化するべき部分を見極めることができるということではないか。1988基本クラスの使えるところでは必ず派生クラスのオブジェクトが使えなければならないという意味。派生型の本当の定義は、基本型と置き換えられるということ。クラスのサブクラスのオブジェクトを渡しても適切に振舞わなければならない。文でオブジェクトの型を判断して処理を振り分けるようなコードは記述してはならない。違反し、修正に対して「閉じ」なくなってしまう。基本クラス以下のことしかできないものは基本クラスの代わりにはなり得ないから。あるメソッドをオーバーライドして、実装を空っぽにしてしまうのは典型的な違反例。基本クラスを使っているメソッドは、派生クラスが投げる例外をキャッチするようには設計されていないため。準拠させるためには、「振る舞い」の等しさに注目して継承関係を持たせないといけない。関係」を持つということは、つまり、「振る舞い」が等しいということである。モデルの正当性は立場によって異なり、その使い方によって正しかったり正しくなかったりするので、普遍的に正しいモデルは存在しない。以下のテクニックを使えば、そのクラスが合理的だと仮定している「振る舞い」を明確にできる。メソッドの事前条件と事後条件を明確にすることでユーザに対して「振る舞い」を明示する。派生クラスの事前条件は、基本クラスで許可されているものは全て許可しなければならない(派生クラスで事前条件を厳しくしてはいけない)。派生クラスの事後条件は、基本クラスで課せられている条件を全て満たさなければならない。これにより、基本クラスのオブジェクトの代わりに派生クラスのオブジェクトを使用できることが保証される。ユニットテストユニットテストによって契約内容を記述することもできる。ユーザはユニットテストを見れば、そのクラスについて何が仮定されているか知ることができる。違反してしまう場合は、共通部分だけを親クラスにくくり出すことによって解決できることがある。共通部分を親クラスにくくり出すというが、実装の多重継承ができない言語を使用していて、既にあるクラスを継承している場合はどうするのか?そーゆー場合は、インタフェースだけくくり出すしかないのでは。そのインタフェースを使うメソッドは何らかの「振る舞い」を期待したコーディングをしてはいけない。上位のモジュールは下位のモジュールに依存してはならない。どちらのモジュールも抽象に依存すべきである。抽象は実装の詳細に依存してはならない。実装の詳細が抽象に依存すべき。下位レイヤのモジュールがサブルーチンライブラリという形で再利用できるのは当たり前。いうことを言っているのではなく、ここでは、上位のモジュールを再利用できるようにするために、下位のモジュールに依存しないように設計しようと言っている。いう学習過程を辿ってきた人には重要な原則。ここで「上位のモジュール」といっているのは、アプリケーションの全体的な動きなどの方針を決める部分で、実装の詳細(下位のモジュール)が変更されても影響を受けない本質的な部分。下位のモジュールが提供するインタフェースを利用するのではなく、上位のモジュールが要求しているインタフェースを下位のモジュールが実装するという考え。