「Application Architecture for .NET」を読んだ - 1部

.NETのエンタープライズアプリケーションアーキテクチャ 第2版 (マイクロソフト公式解説書)

.NETのエンタープライズアプリケーションアーキテクチャ 第2版 (マイクロソフト公式解説書)

古めですが、ここに参考文献が上がっています
matarillo.com: .NETのアプリケーションアーキテクチャ

第一部基礎編のメモ。

TL;DL

アーキテクチャとはシステム開発の利害関係者(ステークホルダー)全体にまたがる共通理解を指す

  • システム開発の利害関係者は、それぞれが異なった要望や関心事を持っている
    • 大まかに分類すると、利用者の領域、ビジネスの領域、そしてシステムの領域となる。それぞれはトレードオフの関係にあることも多いため、アーキテクチャはこれら3つの領域のバランスを取ったものになっていなければならない

1. 現代のアーキテクトとアーキテクチャ

  • アーキテクトは役割
    • ≒ Lead Developer
    • Architect extends Developer
  • アーキテクチャは顧客のためのシステムを構築するもの
    • 明確な答えはないが、見つけ出すことは仕事
    • 良いアーキテクチャ: 変更が困難な決断が全て適正なものであることがわかる
  • 重要な決断を下さなければならないことがアーキテクチャ
    • プロジェクトの出来るだけ早い段階で正しく下さなけばならないもの(先送りにしたいもの)

2. 成功のための設計

  • ソフトウェアプロジェクトの最大の敵はBBM
  • 成功するソフトウェアプロジェクト
    • ビジネスニーズを理解し、そこから上手くいくソリューションを引き出すプロジェクト
  • 上手く設計されたソフトウェア
    • 成功するプロジェクトを背景とし、既存のコードとインフラストラクチャを再利用した上で設計され、利用可能なテクノジと既知のベストプラクティスを踏まえて改良されたソフトウェア
  • ボスは追従者を生み、リーダーは他のリーダーを生む
  • マネージメントチームがリーダーシップを理解していてる + 開発チームがコードの品質について理解している == プロジェクトを成功に導く
  • リファクタリングはプロジェクトに価値を生み出さないけど、行わないと価値が失われる
  • Legacy Code: 側に置いてはいるが、側に置きたくないコード
    • testが書かれていない == Legacy Code
    • 幅広く利用されているため、置き換えるのが難しい
    • これ以上、Legacy Codeを増やさないようにするのが問題
  • 切り離されたブロック(black box) == 境界付けられたcontext

3. ソフトウェアの設計原則

基本的な設計原則
  • 凝集性: 密接に絡み合った責務 - 高いのが理想
    • 単一責任の原則
  • 結合性
    • AクラスBクラスの結合の度合い - 低いのが理想
  • 内蔵型のobject(高凝集)が安定したinterfaceを通じて他のobjectとやり取りする(疎結合)ことを意味する
  • 関心の分離 - AOP
オブジェクト指向設計(OOD)
  • 関連のあるobjectを見つけ出し、相互にやり取りするobjectの結合性を最小限に抑え、コードを再利用する
  • 合成と継承
    • 派生classは親classのコードを継承するだけではなく、contextを警鐘し、そこから親classに対する可視性を手に入れる
    • 合成は防御的
  • 関心の分離
    • 変化する可能性が高い部分を切り出す
    • classが必要でないことがある。関数だけで良いなら、それを使用するだけにする
    • 現実の世界がモデルではなく、イベントを表す、イベントがデータを運ぶもの
開発ベクトルと設計ベクトル
  • SOLID原則
    • 単一責務の原則(SRP)
      • 責務とは変更の理由のこと
      • 限界まで追及するとプロパティだけの貧血classになる危険がある
    • 開放/閉鎖の原則(OCP)
      • 拡張に対して開いている / 修正に対しては閉じたまま
      • composite / interface / generics
    • リスコフの置換原則(LSP)
      • classを作成するとしたら合成の方が安全
      • サブclassをその基底classと置き換えることが出来ないといけない
        • 派生classはその基底classよりも多くのことを要求すべきではなく、それ以下のものを提供すべき
        • class継承のcontextで「特殊な」という表現がされたら注意する
    • インターフェース分離の原則(ISP)
      • クライアントが使用しないinterfaceにクライアントを強制的に依存させてはならない
    • 依存関係逆転の原則(DIP)
      • 上位moduleを下位moduleに依存させるのではなく、両方のmoduleを抽象化に依存させるべき
        • Service Locator
        • Dependency Injection(constructor / setter / interface)
  • coding vector

4. 高品質なソフトウェアの作成

  • テストされていないものは壊れていると思え
  • どのようなシステム、どのようなcontextにおいても単純さは常に長所
  • 依存関係を排除するテスト
    • テストダブル(fakeとmock)
      • fake object: objectの比較的単純なcopy(元のobjectと同じinterfaceを提供する。状態は無くハードコーディングされているケースが多い)
        • やり取りに関心は無い
      • mock object: fake object + 独自の特性を持つobject
  • TDDのテストの最終目的はカバレッジを広げることでは無く、「設計を改善する事」
    • テストは目的では無く、良い設計を実現するための手段
  • applicationのロジックを左右する重要な決断が下される場所(ビジネス層/ドメイン層)で、テストを重点的に行なうべき
  • codeの拡張性
    • 早まった拡張はソフトウェアの諸悪の根源になりかねない(過剰性能)
  • 読み易さは主観的な問題
    • coding以外の事をする十分な時間がない事を承知しているなら、最初から読み易いコードを書くように
  • code comment: codeにおいて下される自明ではない判断について説明する文(特定の部分関する洞察に満ちた見解)
  • code品質
    • テスト容易性/拡張性/可読性