Deveroper メモ

記事内容に絶対の保証はなく..どちらかというと自分用のノウハウ蓄積ページ。 それでも良ければ見ていってください。

クリーンアーキテクチャを読んで...

  • 印象に残ったことをつらつらとメモに残しておきます。
    • 読むだけだと忘れるので
    • まずは 22章まで

以下印象に残った文章

  • アーキテクチャの重要性は変更コストによって計測できる
  • 不完全な知識で運用する事を認める
    • そうするのが人間であり得意である
  • アーキテクチャは、実装と計測によって証明すべき仮説である
  • 設計とアーキテクチャに何も違いはない
  • ソフトウェアアーキテクチャの目的は、求められるシステムを構築・保守するために必要な人材を最小限に抑える
  • ソフトウェアのソフトは...簡単に振る舞いを変更できるため
    • 対して変更ができないものをハードウェアとよんだ
    • ウェアはプロダクトの意味
  • アイゼンパワーのマトリックス
    • 緊急と重要の2種類の問題がある。緊急と重要は違う。重要なことが緊急になるわけではない
  • 3つのパラダイム
  • 「構造化プログラミング」の価値を高めるのは反証可能なプログラミングの単位を作成する能力である
    • 機能分割がベストプラクティスであると考えられる理由
  • UI, ビジネスルール, DBアクセス
    • ビジネスルールは 独立させる事ができる
    • ビジネスルールは独立してデプロイ可能である
    • DBやUI とは別のチームが開発可能である
  • 構造化プログラミング
    • 直接的な制御の移行に規律を課すものである。
  • オブジェクト指向プログラミング
    • 間接的な制御の移行に規律を課すものである。
  • 関数型プログラミング
    • 代入に規律を課すものである。
  • ソフトウェアの振る舞いは、既存の成果物を変更せず拡張できるようにすべき
    • アーキテクチャを学ぶ理由
    • 拡張ではなく大量の変更になってしまったら失敗である
  • SRP
    • 単一責任の原則
    • モジュールはたったひとつのアクターに対して責務を負うべき
      • 単一の修正が一つだけではなく複数の修正を誘発してしまうのは違反
  • OCP
    • オープンクローズドの原則
    • 拡張に対しては開き、修正に対しては閉じてなくてはならない
    • 既存の成果物を変更せず拡張できるようにすべき
  • リスコフの置換原則(LSP)
    • クラスの継承 = S型のオブジェクトo1の各々に、対応するT型のオブジェクトo2が1つ存在し、Tを使って定義されたプログラムPに対してo2の代わりにo1を使ってもPの振る舞いが変わらない
    • 派生型である
    • 置換可能性に少しでも違反してしまうと、システムのアーキテクチャが特別な仕組みだらけになってしまう
  • 変化しやすい具象クラスを参照しない
    • 変化しやすいクラスを継承すると
    • 変化のたびに変更が必要になる危険性があがる
  • 全再利用の原則(CRP
    • どのクラスをひとまとめにすべきか ではなく...
    • どのクラスをひとまとめにすべきではないか
  • 循環依存は厄介
    • あるコンポーネントの変更が 依存関係を循環し、自身にも悪影響を与えてしまう
    • 解消するには依存関係の逆転が必要
  • 初期段階では必要しないが...モジュールなどが増えてきたら
  • 独立コンポーネント
    • 外部要因で変更が必要になることはない
    • ほかのコンポーネントに依存していない
  • 複数のコンポーネントに依存しているコンポーネント
  • ファン・イン
    • 依存入力数
  • ファン・アウト
    • 依存出力数
  • 不安定さ
    • I = ファン・アウト÷(ファン・イン+ファン・アウト)
  • 「方針」と「詳細」
  • アーキテクトの目的
    • 方針とは無関係に詳細を決めながら、方針をシステムの最も重要な要素と認識するシステムの形状を作ること
    • 方針を決める際に 詳細を気にする必要はない
  • 会社がDBの選択を決めていた場合...
    • 優秀なアーキテクトならば、まだ決まっていないと主張するだろう
  • 切り離し方式
    • ソースレベル(rubygems など)
    • デプロイレベル
      • あるモジュールのソースコードに対する変更が、ほかのモジュールに影響を与えない単位
    • サービスレベル(マイクロサービスなど)
      • 物理的な場所に依存しない、通信で繋がっている
    • どの方式が最適か?は初期段階で判断するのは難しい
      • サービスレベルは依存が疎になりやすいが、コストが大きくなりやすい
      • 初期はソースやデプロイ単位で切り離すが、サービスレベルで切り離せるよう組んでおく(著者の好み)
  • 早すぎる決定とは...
    • ビジネス要件とは関係のない意思決定をしてしまう
      • framework, DB, web server, ライブラリ, etc...
    • 1台しかサーバが使えない状況もあり得る
  • 境界線を引くとは...
    • 例: RDB を使うべきか? 迷っている
      • データの入出力をする部分に「境界線」を引いた(疎結合にした)
      • 結果: TEXT ファイルで十分だった
      • 境界線以降をtextファイルにした
  • DB と ビジネスルールは別物
    • 本来切り離せる
    • DB を何にするか?決定を遅らせても構わないはずである。
  • エンティティ
    • 最重要ビジネスデータを操作する最重要ビジネスルールを含んだインターフェース
    • ビジネスを表すものとして独立させる
    • これがないとビジネスとして成立しない最低限の単位
  • ユースケース
    • 自動化されたシステムを使用する方法を記述したもの
    • アプリケーション固有のビジネスルールを記述する
    • 入力データ、出力データ、それらがやり取りする適切なエンティティへの参照といった、データ要素を持っている
  • エンティティは自身を制御するユースケースのことを知らない。
  • クリーンアーキテクチャ
    • 依存関係の方向性と円の図
    • 図はいろいろなサイトに載っている
    • 依存の矢印は外側から内側に向かわせる
    • フレームワーク非依存
    • テスト可能
      • ビジネスルールはDB, http, その他外的要素がなくともテストできる
    • UI非依存
      • ビジネスルールの変更なしに変更できる
      • 項目自体を増やすとかじゃなく...http 経由 -> コンソールUI にするなど
    • データベース非依存
      • ビジネスルールはDBが何であろうと構わない -> 束縛されない
    • 外部エージェント依存
      • ビジネルルールは外界のIFを知らない
      • ブラウザ経由 -> アプリにする際に変更がない