読者です 読者をやめる 読者になる 読者になる

What one likes, one will do well 〜好きこそ物の上手なれ〜

寄り道しながらも、最後は昔から好きな物理とプログラミングに戻ってくる。そんな男の思いをつづるブログです。

アジャイルソフトウェア開発の奥義を読みました。

はじめに

アジャイル開発に興味があり調べていると、「アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技」と言うのがオススメされていて読んでみました。コードがたくさん書いてあり、具体的で体系的にまとまれていて、とても読み応えがあり、楽しかったです。かなり分厚い本なので、最後は息切れしてしまいましたが。。。読んで心に残ったことをまとめます。

アジャイル開発

最初はアジャイル開発のアジャイルアライアンス宣言や原則、エクストリームプログラミングのプラクティスがまとめられています。顧客が受け入れテストを書くと言うのが目からうろこでした。

実際にリファクタリングをする例やプログラミングエピソードで実際にペアプログラミングテストファーストを実践している例がコードと共に書かれていて、具体的にイメージできました。かなり勉強になりました。

アジャイル設計

設計における原則が書かれていました。難しい内容も多かったのです。後の章で実際のコードと共に原則を使っており、とても大切なことがわかります。自分の理解を整理する上でも内容をまとめます。

  • 単一責任の原則は、クラスは一つの責務を持つこと
  • オープンクローズドの原則は、修正せずに(クローズド)拡張できること(オープン)。具体的には、ポリモーフィズムを利用して、サブクラスを追加する事で機能追加できる設計
  • リスコフの置換原則は、スーパークラスをサブクラスに置き換えても正常に動く状態。これを満たしていないとオープンクローズドの原則が満たされない可能性が高い。またサブクラスがスーパークラスのメソッドで使わないものがあれば違反している
  • 依存関係逆転の原則は、上位がインターフェースを提供し、それに下位が合わせる状態。上位が下位を使うと下位に依存する。下位が上位に依存するのが正当。そうすれば同じインターフェースを持つ下位を自由に使える。実現において重要なのは抽象化
  • インターフェース分離の原則は、関連がうすいインターフェースを分離すること。関連のないインターフェースの変更の影響がそれを使うクライアントにいかない事が大切
  • 原則はたくさんあるが必ず守る必要はない。しかし一度問題が発覚したら、次は起こらないように原則を適用して改善することが大切

給与システムのケーススタディ

抽象化することでオープンクローズドの原則に則って実装されのが具体的にわかりました。クラス作りすぎるのは煩雑だと思っていたけど、変更に強いし、理解すればわかりやすいです。コードがたくさんでボリュームがありますが、コードを読むことで理解が深まりました。このケーススタディで使われていたデザインパターンが最初にまとめられていたので、自分の理解を整理するためにまとめます。

デザインパターン

  • Commandは、クラスにコマンドを実装
  • Template methodパターンは、処理のテンプレートを実装して、それを継承し、詳細な処理を実装する
  • Strategyは、必要な処理をインターフェースに移譲し、処理を実装する。実際の処理を実装しているクラスと処理しているクラスが分離される
  • Facadeは、汎用インターフェースをシンプルに使いやすくする。ラッパーと似てると思うけど、違うかわからなかった。汎用インターフェースに使用方針や制約を課す
  • Mediatorは、Facadeと同じく方針や制約を課すのだけど、リスナーなどを使用して、意識することなく課される
  • Singletonは、自身のインスタンスをstaticで持ち、コンストラクタはprivateにし、インスタンスの生成は決まったstaticなメソッドで行い、staticな自身のインスタンスを返す事で、インスタンスが一つしか発生しないようにする
  • Monostateは、変数をstaticにし、別のインスタンスからでも同じstaticな変数を返すため、全て同じインスタンスのように振る舞う
  • Null Objectは、何もしないオブジェクト。クラスにstaticなNull Objectを保持し、インスタンスが生成できない条件のときに返す。Nullのときのメソッドの処理を調整し、存在チェックをシンプルにできる。(例:DBに存在しないときは、Null Objectを返すなど)

給与システムのパッケージング

給与システムのケーススタディのクラスをパッケージングしていました。最初にパッケージ設計の原則があり、その後使うデザインパターンの説明、最後に実際のコードでパッケージングしていました。難しかったです。。。

パッケージ設計の原則

  • 再利用リリース等価の原則は、再利用されるパッケージとリリースの単位が等価であること。再利用されるパッケージがリリースの単位より小さくなることはない。
  • 全再利用の原則は、パッケージ内のクラスは一緒に再利用されるべきで、関係ないものは含まないということ。パッケージには強い関連性があるもののみを含む
  • 閉鎖性共通の原則は、単一責任の原則のパッケージ版。変更に対して閉じているべきで、変更はパッケージ内全てに影響を及ぼすが、他のパッケージには影響しない。同じ理由で変更される可能性のあるクラスをまとめることでもある
  • 非循環依存関係の原則は、依存関係を循環させないこと。循環すると結局全てのパッケージと依存関係が生まれ一つの変更で全てビルドリリースが必要になる。解決するには依存関係逆転の原則を使う。AがBを使っているとする。Aが使うインターフェースを作る。Bはインターフェースを利用したクラスを提供する。Bがインターフェースに依存するので、依存関係が逆転する。またAとB両方が依存する新しいパッケージを外出して作るのも循環を防ぐ。パッケージ構造は変化し成長するもの。トップダウンでは設計できない
  • 安定依存の原則は、安定していて変更したくないパッケージに依存するようにして、変更したいものは依存されないようにすること。依存関係は安定するものに流れるようにする
  • 安定度抽象度等価の原則は、パッケージの安定度と抽象度は同程度でなければならないこと。安定するということは、抽象化されているということ

デザインパターン

  • Factoryは、インスタンス化することを請け負う。具体的なインスタンス化は、依存になる。依存をさけるためFactoryを作成し、インターフェースのみにつながる。しかし複雑なため乱用は勧めない

パッケージ設計で注意すべき点

  • パッケージは似た機能をまとめるだけではダメ。依存される「責任がある」パッケージと依存しない「独立した」パッケージがある。「責任がある」パッケージは、抽象化され再利用可能なもの。「独立した」パッケージは、変更が頻繁な詳細な処理を持つ。しかし保守性や再利用背性と依存関係の複雑性はトレードオフでパッケージの利用によって検討する必要がある。
  • パッケージ内で処理を完結させる
  • メトリック。凝縮度、内側に向かう結合度、外側に向かう結合度、抽象度、不安定度、主系列からの距離。定量的に測る

気象観測所のケーススタディとETSのケーススタディ

これ以降は内容が難しくなってきて、一応読んだもののケーススタディはほとんど理解できませんでした。何とかまとめたデザインパターンだけ記載しておきます。

  • compositeは、同じ処理を繰り返し行うときに使う。既存の処理は変えずに、リストに入れ、繰り返し処理すればよい
  • observerは、何かを監視するときに使う。observerを登録して、subjectに変化がありnotifyされたら、登録されているobserverのupdateを読んで更新する。更新にはpull型とpush型がある
  • abstract serverは、インターフェースをいれて、具体的なクラスが直接依存しないようにする。インターフェースを定義するときにクライアント側の名前にするのがコツ
  • adapterは、ソースコードを持っていない対象にabstract serverパターンを適用する時に使う
  • bridgeは、中間にコントロール層を作って管理する。複雑になるためおすすめはしない
  • proxyは、ビジネスロジックとDBの処理を分離すること

まとめ

アジャイル開発の原則からプラクティス、プラクティスの具体例に、デザインパターンケーススタディのコードと盛りだくさんでした。まえがきで「コードをじっくり読んでほしい」とあるが、まさにその通りで、コードを読むことで学ぶことがたくさんありました。(最後は読み切れませんでしたが。。。)

付録にある「皮肉な運命」や「ソースコードは設計である」はとても興味深い内容でした。

全てを読み切れなかったし、読んだ部分も全てを理解できている訳ではないので、何度か読みなおしたい本です。本を見ればわかるように分厚く、かなりのボリュームです。その分内容もかなり深いと思います。オススメの一冊です。

 

 

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

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