CleanCode読書記録〜システム〜
TweetRobert C. Martin先生のCleanCode第11章を読んだメモ。
システム(第11章)の概要
- あなたは、街をどうやって作りますか?
- 自分だけで全ての詳細を管理することはおそらく無理
- 何人かは全体像に対する責任があり、残りは詳細に関心を持つ。
- ソフトウェアも同じ。
- より高いシステムのレベルを綺麗な状態に保つ方法を考える。
- システムを使うことと、構築することを分離する。
- 使うと構築することは異なる。
- オブジェクトの生成などの開始処理はアプリケーションが扱わざるを得ない関心ごと。
- 大体のアプリケーションは関心ごとの分離ができていない。
- よく見られる、1回目はインスタンス化して返す。2回目は以前インスタンス化したものを返すみたいな実装は、構築のロジックと通常の実行処理が混ざっている。
- 小さな意味でSRPに違反している。
- これらはモジュール化して通常のランタイム処理から切り離し、それが主要な依存関係を解決するための生合成の取れた手段となるようにする。
- mainの分離
- 1つの方法として、構築処理をmainモジュールへと移動し、システムの残りの部分はオブジェクトが適切に生成された前提のもとに構築する。
- 依存関係を表す矢印が、いずれもmainから出る方向を向いている。
- これはアプリケーション側は、mainやオブジェクトの構築処理についてなんら知識を持たないことを意味する。
- ファクトリ
- オブジェクトの生成に対してアプリケーションが責任を持たなければならない時もある。
- この時は、抽象ファクトリパターンを用いて、アプリケーションコードから分離する。
- DI
- オブジェクトの利用と生成を分離する強力な仕組み。
- 制御の反転(IoC)の適用
- 通常はmainルーチンか、特殊用途のコンテナ(多分DIコンテナのこと)を利用する。
- 大体のDIコンテナはオブジェクトが必要になるまで生成しない。
- こうしたコンテナは遅延評価の用途に用いることで最適化の効果が得られる。
- 遅延評価と遅延初期化は最適化の1つにすぎなくて、まだ未成熟であるということを忘れないこと。
- スケールアップ
- 将来を見通して、最初から正しいシステムは神話に過ぎない。
- 可能なのは今日の「ストーリー」を実装し、明日のストーリーを実装するためにリファクタリングして拡張していくことだけ。
- これがアジャイルのイテレーティブでインクリメンタルな手法の本質。
- しかし、システムレベルのアーキテクチャは単純なものから複雑なものへとインクリメンタルに成長するものではないことは明らか。
- EJBのバージョン1,2は関心ごとを分離できていない。
- そのため、大量のライフサイクルメソッドや、RDBの詳細、トランザクションの特性、セキュリティ束縛などを1つ以上のXML配備記述子で指定する必要がある。
- その結果、テストが困難
- EJB2のアーキテクチャ外での再利用は事実上不可能。
- 横断的関心事
- EJB2のアーキテクチャはある領域では関心ごとの分離ができている。
- トランザクション、セキュリティ、永続化の挙動の設定はソースコードとは独立して指定できる。
- 永続性のような関心ごとは、オブジェクトの自然なドメイン境界に横断的に現れる。
- EJBアーキテクチャに対して、今後AOPの活躍が予想される。
- AOPは横断的関心事に対してモジュール構造を取り戻すための一般的なアプローチ
- EJB2のアーキテクチャはある領域では関心ごとの分離ができている。
- Javaプロキシ
- プロキシを通じてメソッドの呼び出しをラップすることがAOPであると誤解されがち
- 真のAOPの価値的はシステムの振る舞いをわかりやすく、モジュール構造を保って指定できることだが、プロキシではこういったことができない。
- Pure JavaのAOPフレームワーク
- Springでは、ビジネスロジックをPOJOで書くことができ、純粋にドメインに集中できる。
- 横断的関心ごとを含んだアプリケーション基盤は設定ファイルやAPIによって宣言的に組み込まれる。
- XMLが冗長で読みにくくなるがアノテーションを使うことで、明示的な結線ロジックを減らすことができる。
- このようなSpringの宣言的モデルによる横断的関心ごとをEJB3では継承している。
- 永続化のマッピング詳細が頻繁に変わらない限り、おそらく多くの開発部隊はアノテーションを選ぶ。
- Springでは、ビジネスロジックをPOJOで書くことができ、純粋にドメインに集中できる。
- AspectJアスペクト
- 非常に豊富で強力な関心ごとの分離を実現するツールだが、ツールに慣れる必要があるのと新しい言語とそのイディオムの使用を学習する必要がある。
- アノテーションでだいぶ改善された。
- 全機能説明するのは本書の範囲を超えてるから詳細は、ドキュメント読んで。
- 非常に豊富で強力な関心ごとの分離を実現するツールだが、ツールに慣れる必要があるのと新しい言語とそのイディオムの使用を学習する必要がある。
- システムアーキテクチャのテスト実行
- アプリケーションのドメインロジックをPOJOで記述できればアーキテクチャのテスト実行が可能となる。
- 事前の大規模設計(Design Up, Front, BDUF)が不要。
- 世界中の最も大規模なウェブサイトのいくつかは、高い可用性とパフォーマンスを実現できている。
- お互いの依存性が少ない設計は、抽象化とのスコープのレベルが単純だから、キャッシュ、セキュリティ、仮想化といったものを柔軟に、効率的に用いることができる。
- 良いAPIは、ほとんどの場面で境界の外になければいけない。
- 開発チームの労力をユーザストーリの実装に集中させる必要がある。
- そうしないと、アーキテクチャのしばりが顧客への価値提供の効率化を邪魔する。
- 意思決定を最適化する
- 大きなシステムであれば全ての意思決定を一人で行うことは不可能
- 資格のある人たちに権限を委譲するのが最善。
- 決定は、それが手遅れとなる直前まで延期することが最善である。
- 早すぎる決定は、最善とは言えない知識のもとで行われる。
- 顧客からのフィードバック、プロジェクトに対する精神的な思い、選択した実装の経験がずっと少なくなってしまう。
- 検証可能な価値を追加する際には、標準を賢く使用する。
- EJB2が標準であるといった理由で選択されていることがある。
- 誇大広告付きの標準に取り憑かれ、自分自身の顧客にとっての価値を実装することをないがしろにしてしまったチームを数多く見てきた。
- 標準は、アイディア、コンポーネントの再利用、経験を持った開発者の求人、アイディアのカプセル化などを容易にする。
- しかし、標準の策定に必要な時間が長過ぎて、いくつかの標準はそれが使われる場面で必要となる真のニーズと乖離してしまう場面がある。
- EJB2が標準であるといった理由で選択されていることがある。
- システムはドメイン特化言語を必要とする。
- DSLの作成が再び脚光を浴びている。
- ドメイン専門家が書くような散文構造のようにコードが読めるようになる。
- 優れたDSLはドメインの概念とそれを実装するコードとの間の「コミュニケーションギャップ」を最小化する。
- 効果的に使用すれば、DSLは抽象レベルをコードのイディオムとデザインパターンよりも上に引き上げることができる。
- 開発者はコードの意図を、適切な抽象レベルに見せることができる。
感じたこと
この章で伝えたかったことがうまく読み取れているか自信がないが、
- オブジェクトの生成とビジネスロジックを分離すること
- 詳細と共に死にたくないなら、抽象化してPOJOで書こうね
- 標準をありがたがってないで考えろ
ということかなと。
あとは、そうしないことによるデメリットがつらつらと書かれている印象。
ただ、DSLに関して、本書とは異なった印象を持っている。
個人的にはDSLは詳細に含まれると思っている。
そのため、上記に記載の通り、意思決定の最適化の観点ではそんなに手放しで喜べるものではないと思っている。
覚えても3年後には陳腐化とかが十分にありえる危険なものという認識なので極力避けたい。
このあたり、何か誤解があるかもしれないのでもう少しドメイン特化言語について学ぶ必要があるかもしれない。