📝Design Principle(設計原則)

📝Design Principle(設計原則)

up: 📂ソフトウェア設計


設計原則. 設計手法.

TDD #

Test-Driven Development. テスト駆動開発.

BDD #

振る舞い駆動開発.

DDD #

Domain-Driven Design.Eric Evans 氏の唱えた設計手法.

ref. ドメイン駆動設計 - Wikipedia

特徴 #

  • 複雑なドメインの設計はモデルベースで行うべき
  • システムを実装するための特定の技術ではなくドメインそのものとドメインのロジックに焦点を置くべき

基本原則 (前書きより) #

  • コアドメインに集中すること
  • ドメインの実践者とソフトウェアの実践者による創造的な共同作業を通じてモデルを探求すること
  • 明示的に境界づけられたコンテキストの内部で, ユビキタス言語を語ること.

基本用語 #

巻末に用語集がある.

ドメイン #

  • 知識, 影響, 活動の領域.
  • アプリケーションが対象とする業務領域.

ユビキタス言語 (p24) #

ドメインエキスパートと開発者の間で使う共通言語.

  • モデルを言語の骨格として使用する.
  • チーム内のすべてのコミュニケーションとコードにおいて, 厳格にその言語を用いること.
  • 図, ドキュメント, コード, 会話において, 同一の言語を用いること.

UML #

  • UML によって議論に確固とした基盤が与えられる.
  • クラス図と相互作用図がつかいやすい.
  • オブジェクトの名前や関係性を共有できる.
  • オブジェクトの概念, なにをおこなうかははっきり伝えることができない.
  • クラス図の操作名やコミュニケーションでそれとなくは伝えられる. はっきり伝えるためには, 補足的なテキストや会話が必要.
  • 説明のためのモデルはオブジェクトモデルである必要は全くなく, 通常はそうでないほうがよい.

ドキュメント #

  • モデルは図ではない.図はコミュニケーションの手段に過ぎない.
  • 設計に関する本質的な詳細は, コードにおいてとらえられる.
  • すでにコードでうまくやっていることを, ドキュメントでもやろうとすべきでない.
  • ドキュメントは活動の役にたたなければならず, 最新の状態を保たなければならない.
  • ドキュメントを最小限にとどめ, その重点をコードと会話の補足に絞ることで, ドキュメントを常にプロジェクトに結びつけた状態にたもつ.

モデル駆動設計 (P45) #

  • 分析モデルと設計ととう二分法を捨て去り, 両方の目的に使える単一のモデルを探し出す.
  • モデリングと設計のプロセスは, 反復されるただ 1 つのループ.
  • 設計で必要とする用語法と責務の基本的な割り当てをモデルから引き出すこと.
  • 開発は, モデルと設計, コードを単一の活動として改良しつづける, イテレーティブなプロセスとなる.

モデル駆動設計の構成要素 (p65) #

レイア化アーキテクチャ (p66) #

以下の 4 つに分解される.

  • UI 層

    ユーザとの相互作用の境界となる層 (Web 層, プレゼンテーション層)

  • アプリケーション層 (サービス層)

    ドメインオブジェクトを操作することで, ソフトウェアが果たすべき仕事を実現する層. 薄くシンプルにたもち, 仕事はドメイン層のオブジェクトにやらせる.

  • ドメイン層

    ビジネス上の概念を表現する層.モデル層

  • インフラストラクチャ層

    上の 3 層を支える技術的な基盤となる層. データベース, 通信など.

エンティティ (参照オブジェクト) (p87) #

属性ではなく,連続性と識別性によって定義されるモノ

  • 連続性
    • 状態をもつ.
    • ライフサイクルをもつ.
  • 識別性
    • 一意であることが保証された記号をそえることによって実現できる.
    • ID, 座席番号, 出席番号… システムが生成する.

振る舞いと属性を, 他のオブジェクトに移動できないか検討する. (別のエンティティ, 値オブジェクト, サービス..)

値オブジェクト (p95) #

事物の特性を記述するオブジェクト. 概念的な同一性はない.

  • 識別子を持たない (与えてはいけない) 属性にのみ興味がある.
  • オブジェクトは不変でなければならない (fatal)
  • 通例読み出し専用のオブジェクト.
  • Flyweight パターンを用いて共有できる.
  • しばしば, オブジェクト間のメッセージでパラメータとして渡される.

サービス (p103) #

  • 操作をおこなう責務をもつ.
  • ソフトウェアが実行すべきことに対応し, 状態には対応しない.
  • オブジェクト自身に操作をさせずに, それぞれごとにオブジェクトの操作をするものは, しばしばマネージャーと呼ばれる.それは手続的だ.
  • 状態をもたせないこと.
  • 要求に応じてクライアントのために行われるなにか. なので, 名詞よりも動詞として定義される.
  • 操作名がユビキタス言語の一部になること.

モジュール / パッケージ (p108) #

  • モデルの意味ある一部.
  • モジュール内は高凝縮, モジュール間は低結合.
  • モジュールは本で言えば章.
  • モジュール名は, ユビキタス言語をつけること. ドメインに関する深い洞察を反映していなければならない.

ドメインオブジェクトのライフサイクル (p122) #

集約 (Aggregates) (p123) #

  • 関連を最小限にして設計する.
  • モデル内にある参照をカプセル化するための抽象化が集約.
  • 関連するオブジェクトの集まりであり, データを変更するための単位. -> 集約のときに宣言する型は抽象クラスかインタフェースになるのかな?
  • 集約にはルートと境界がある.
    • ルート
  • 集約に含まれている特定の 1 エンティティ.
  • 外部オブジェクトへの参照をもつ.(車がルート, タイヤは違う)
  • グローバルな一貫性をもち, 不定条件をチェックする最終責務をもつ.(リソースの開放処理とか?)
    • 境界
      • エンティティと値オブジェクトを集約のなかにまとめ, 各集約の周囲に境界を定義すること.
  • 境界の内部に存在するオブジェクトへのアクセスは, ルートオブジェクトを経由して制御すること.

ファクトリー (p134) #

  • オブジェクトや集約全体を生成するのが複雑だったり, 内部構造をさらけ出し過ぎている場合は, 別のオブジェクトに移譲すること.
  • ファクトリーでカプセル化する.
  • 実装を簡単に切り替えられるようにできる.
  • 要求される型によって抽象化する.
  • デザインパターンでいくつかまとまっている
    • ファクトリーメソッド
    • ビルダー
    • アブストラクト・ファクトリー
  • ファクトリの置き場所は,
    • 集約のルートオブジェクトにメソッドを用意する.
    • 他のオブジェクトの生成に密接に関わるオブジェクト.

リポジトリ (p146) #

  • オブジェクトを使用するための方法は

    1. 生成する
    2. 関連を巡る
    3. クエリを実行して,
      • 属性に基づいてデータベース内でオブジェクトを見つける
    • オブジェクトの構成要素を見つけて, それを再構築する
  • この第 3 の方法こそがリポジトリ.

  • データベース検索は, グローバルにアクセスすることができて, どんなオブジェクトにも直接到達できる. オブジェクトのネットワークは管理しやすくなる.

  • 開発者は通常, そういう設計の機微についてあまり考えない.

  • 格納されたデータからインスタンスを生成することは, エンティティのライフサイクルの一部. なのでこれを再構築と呼んで, 生成と区別する.

  • 関連でほとんどの場合は十分!

    • 一時的なオブジェクト (値オブジェクト) は必要ない. ライフサイクルが短く, それを利用するクライアントで生成と破棄がされる.
    • 永続化されりオブジェクトのうちで, 関連を巡ってみつけるほうが便利なものに対しても, クリエによるアクセスは必要ない. なによりも, 集約内部にあるどのオブジェクトも, ルートから辿る以外の方法でアクセスすることは禁止だ.
    • 永続化された値オブジェクトを見つけるには, それをカプセル化する集約のルートとして機能するエンティティから関連を巡るのが普通のアプローチ.
  • どのようなときに検索が必要?

    • オブジェクトの属性に基づいた検索を通じて, グローバルにアクセスできなければならないものもある. そういうアクセスを必要とするのは, 集約のルートのうち関連を巡って到達しようとする都合の悪いもの.
    • データベースへのアクセス方法はいくつかある
      • SQL をクエリオブジェクトにカプセル化する
      • メタデータマッピング層でオブジェクトとテーブル間の変換をおこなうこと.メタデータマッピング - Strategic Choice
  • リポジトリの作り方

    • リポジトリは, 特定の型のオブジェクトをすべて概念上の集合として表現する. この定義の集合を通じて, 集約のルートに対するアクセスが提供される.
    • クラアイントがリポジトリに対してオブジェクトを要求する際は, クリエメソッドを使用する.
    • グローバルアクセスを必要とするオブジェクトの各型に対して, あるオブジェクトを生成し, その型のすべてのオブジェクトで構成されるコレクションが, メモリ上にあると錯覚させるようにできるようにすること.
    • 実際に直接的なアクセスを必要とする集約ルートに対してのみ, リポジトリを提供すること.

DSL #

特定のタスク向けに設計されたコンピュータ言語.

DSL は大きく 2 つに分類出来る.

  • 内部 DSL
  • 外部 DSL

内部 DSL #

汎用プログラミング言語 (Java, Ruby, Scala…などなど) をベースにしてつくるもの.

外部 DSL #

まったくの独自文法とインタプリタによってつくるもの.

Bookmarks #

Amazon

エッセイ:

そもそも「ぼくらは, 何のためのソフトウェア作るの? 」決して, コンパイルを通すことが目的ではなくて, あるドメインを IT によって実現するためですよね.

オージス総研 パターンの分類:

解説 PDF

MDD #

モデル駆動開発. 組み込み業界で熱い?オワコン?

DRY #

Don’t Repeat Yourself

🏷YAGNI #

You ain’t gonna need it.

ref. YAGNI - Wikipedia

REST #