DebTab

  • ホーム
  • DevTabとは
  • 記事一覧
    • きたえる
    • かえる
    • つくる
    • みちびく
    • たばねる
    • つたえる
かんたんログイン
Githubでログイン
Githubアカウントでかんたんにログインして、DevTabをもっと便利に使おう。

DebTab成長しつづけるデベロッパーのための情報タブロイド

DebTab

ログイン

検索 検索

ドメインモデル中心のアーキテクチャ

写真増田 亨

かえる

2016.11.09

ポイントポイント

0

ギルドワークスの増田です。

河上さんが書いていたヘキサゴナルアーキテクチャに関連して、ドメインモデル中心のアーキテクチャについて考えてみます。

「ドメイン駆動設計」本のアーキテクチャへの疑問

私の設計の考え方は、6年ほど前に出会ったエリック・エバンスの「ドメイン駆動設計」が基本になっています。しかしドメイン駆動設計を実践するためのアーキテクチャについては、エバンスが「ドメイン駆動設計」本の中で描いているアーキテクチャの図が、どうもしっくりきませんでした。 4章のレイヤ化アーキテクチャの説明そのものは、すっきりしています。

プレゼンテーション層
ユーザ向けの情報の表示。ユーザからのコマンドを受け取って解釈。
アプリケーション層
ソフトウェアが行うべき仕事を定義。実際の処理はドメイン層に委譲する。
ドメイン層(モデル層)
ビジネスの概念、ルールの記述。業務アプリケーションの核心。
インフラストラクチャ層
上位のレイヤを支える技術的な機能を提供する


しかし本に掲載されたアーキテクチャ図をみると、ドメイン層がアプリケーションの中心であるようには見えません。そこに違和感がありました。

ドメインモデルを中核にしたアーキテクチャ

ドメインモデルを中心にしたアーキテクチャの私のイメージはこんな感じです。 アーキテクチャ

私のオリジナルではなく以下のアーキテクチャを参考にしたものです。

  • アリスター・コバーンのヘキサゴナルアーキテクチャ
  • アンクル・ボブのクリーンアーキテクチャ
  • ジェフリー·パレルモのオニオンアーキテクチャ

共通しているのは、「内側」にアプリケーションやビジネスロジックがあって、「外側」に外部とのインタフェースがある、という捉え方です。 ユーザインタフェースも、データベースも、通信インタフェースも、外部とのインタフェースという意味で同じ性格の構成要素と考えます。

マーチン・ファウラーは「エンタープライズ・アプリケーション・アーキテクチャパターン」のなかで、コバーンのヘキサゴナルアーキテクチャにも触れています。ファウラーは「UIとデータベースとは、性格が異なるので、別のレイヤ要素として考えたがほうが良い」と述べています。

二人のアーキテクチャ観は、相反してはいません。

まず、アプリケーションの中核は、ビジネスの概念やルールを記述する、という考え方は、まったく同じです。 外部とのインタフェースを、その責務や構造から考えた時に、ユーザインタフェース層とデータアクセス層は、異なる要素である、という点も同じです。 コバーンの図でも、データベースとUIは、別の方角に配置しています。つまり同じ外部インタフェースだが、別の性格であることも意識しているわけです。

私自身は、図で示したように、全体のアーキテクチャを大きく3つに分けて考えています。

ドメインモデル(中核)
ビジネスルールの表現。ビジネスデータを元に、判断・加工・計算をするロジックを記述。
ユースケース層
業務手順を記述(できるだけ簡潔に)
外部インタフェース(外殻)
外部との接続インタフェース。イベントに反応して必要な処理を呼び出す「コントローラ」、処理の結果を表現する「プレゼンター」、外部システムとの連携を行う「ゲートウェイ」で構成する。


大きな関心事として「ドメインモデル」「ユースケース」「外部インタフェース」の三つに分けるという設計です。

技術の関心事:外部インタフェース

外部インタフェースは純粋に「技術」の関心事です。

技術の関心事は、どのような業務アプリケーションでも、ほぼ共通します。広く受け入れられている、定番的な解決方法が多いのが外部インタフェースの領域です。 外部インタフェースは、最近ではオープンソースのフレームワークやライブラリを使うことがあたりまえになっています。 対象分野固有の業務の関心事やビジネスルールを分離してしまえば、「外部インタフェース」は、純粋な技術的な世界です。そして、フレームワークなどで、汎用的な解決手段が提供されている領域です。

一般的な業務アプリケーションでは、それほど難しい設計は要求されない部分です。

※外部インタフェースにも、もちろん、難しい設計課題はあります。大量のデータを効率的に扱う/同時の多数のアクセスをさばく/サービス停止を防ぐ/障害発生時もデータを完全に保護する、などです。

業務の関心事

一方、外部インタフェースから分離したユースケースとドメインモデルは、そのアプリケーションに固有の課題です。そして、業務アプリケーションを複雑にし、設計を難しくする根本原因です。

業務アプリケーションが複雑になるのは、次のようなビジネス要求が絡み合うからです。

  • 商品の「種別」や、顧客の「区分」による場合分け
  • 残高、在庫状況、承認の済・未済など「状態」に応じた場合分け
  • 役割や権限に応じた「見える・見えない」「できる・できない」の場合分け
  • 未来の予定(予算)と実績との差異チェックとそれに基づくアラート
  • ...

こういうさまざまな視点の場合分けと関連する判断や計算のルールを、多元的に組み合わせたものがビジネスルールです。 そして、それらの場合分けとビジネスルールは、ビジネスの成長やビジネス環境の変化に合わせて、常に、変更が繰り返されます。 業務アプリケーションが複雑になるのは、こういう現実のビジネス世界の構造的な複雑さと、ビジネスは常に変化し続けるという流動性に起因する、必然なわけです。

ユースケースとドメインモデルの分離

複雑な業務ニーズを、やみくもにコードに落としても、プログラムが不要に複雑になり変更がたいへんになるばかりです。 そうならないために、業務の関心事を整理して、見通しの良いプログラムを記述する「工夫」が必要です。 その工夫のひとつがユースケースとドメインモデルの分離です。

もし、ユースケースの種類が少なく、また「区分」や「状態」の場合分けも単純であれば、ユースケース単位にプログラミングするのがてっとりばやい。ユースケースの業務手順の記述の中に、ビジネスルールの判断ロジックや計算ロジックを埋め込む書き方です。 これが「トランザクション・スクリプト」という設計スタイルです。

ユースケース単位でビジネスルールを記述する「トランザクションスクリプト」は、複数のユースケースに、同じビジネスルールを重複して記述することになりがちです。

たとえば「注文を登録する」「注文を変更する」「注文をキャンセルする」という3つのユースケースを考えてみましょう。この3つのユースケースは「注文」という共通の関心事についての異なるアクションです。「トランザクションスクリプト」では、「注文」に関するビジネスルール、判断・加工・計算のロジックは、3つのユースケースで重複して記述されます。

「ドメインモデル」は、この「注文」ような、複数のユースケースに共通する関心事を一か所に集約して、ビジネスルール、判断・加工・計算のロジックを整理する工夫です。「ドメインモデル」は、一つのビジネスルールをプログラムのあちこちに重複して記述することを防ぎます。重複した記述がなくなり、1箇所だけでビジネスルールを記述すれば、プログラムの変更は容易で安全になります。

ドメインモデルの設計と実装のスタイル

「ドメインモデル」は、業務の本質的な複雑さをそのまま反映しています。また、たえず、変更ニーズが発生することに備えることも、「ドメインモデル」の設計の重要な課題です。この設計課題を解決する工夫として、さまざまなアプローチのプログラミングのスタイルが提案され、実践されてきました。

手続き型プログラミングであれば、さまざまなビジネスルールを「共通サブルーチン」として実装します。 オブジェクト指向スタイルの設計であれば、関連するデータとロジックをクラスやパッケージに集約して、ビジネスロジックの整理を図ります。 Prologやルールエンジンのような論理型のパラダイムであれば、ドメインモデルは「ルール」と「事実」の集合とその演算として表現するでしょう。 関数型のパラダイムであれば、ビジネスルールは「関数」のネットワークとして表現することになりそうです。

どのようなスタイルで設計するとしても、大切なことは「ドメインモデル」を、アプリケーションの全体の中で、独立性の高い中核部品として分離することです。独立性が高い、という意味は、ユースケースや外部インタフェースの構造や都合に影響されないようにする、という意味です。 アプリケーションの中核に「ドメインモデル」を配置し、「ユースケース」はドメインモデルに依存し、「外部インタフェース」は、ユースケースとドメインモデルに依存する構造にします。こういう構造にする動機は次の2点です。

  • 業務の関心事と技術の関心事を分離して全体の見通しをよくする
  • 個々の業務を表現するユースケースから、業務をまたがって共通するビジネスロジックを「ドメインモデル」に集約して、複数のユースケースでひとつののビジネスロジックを重複して記述することを防ぐ

結果として、どこに何が書いてあるかわかりやすく、変更すべき箇所の特定が容易で、変更の影響範囲を構造的に限定できる、あつかいやすいソフトウェアになります。

※注意:この記事は2015年7月10日にGuildWorks Blogで公開したエントリをリライトしたものです。

"いきなり最強チーム"の資料のお申込み

共感した

ポイントポイント

0

取り消す

この記事に共感したら、何度でも押してこの記事のポイントをみんなでアップしよう。

自分の感想を残す

この感想は、サイトに公開されることはなく自分にしか見えません。自分の考えのログを残すために感じたことを登録し、のこしておきましょう。あとで振り返ったときに、あのとき自分はこう考えていたのかということを知ることにより、あなたの成長へとつながります。

Githubでログイン

Githubアカウントでかんたんにログインして、DevTabをもっと便利に使おう。

  • ひとつ前の記事

    Emotional Development.

  • ひとつ後の記事

    開発チームの設計力を強化する

この記事もどうですか?

SIerを飛び出して、どんな風景が見えたか

これはギルドワークス Advent Calendar 2019 7日目の記事となります。 私は前職で…

つくる

かえる

2019.12.07

ポイント
2

越境と正しいものを正しくつくる、9つのお話。

この記事は、 ギルドワークス アドベントカレンダーの17日目の記事です。 手元のディレクトリの数によ…

かえる

みちびく

たばねる

2017.12.17

ポイント
0

越境はいつだって1人から。でも、いつまでも1人ではない。

 2018年秋、TEDxKobe 2018で話をしました。 この会のテーマは「Burning to …

かえる

みちびく

たばねる

つたえる

2018.12.01

ポイント
8

シェア
  • Twitter
  • このエントリーをはてなブックマークに追加
  • Google Plus

ログインして
ブックマーク

  • Twitter
  • このエントリーをはてなブックマークに追加
  • Google Plus
  • ログイン
LINE@

新しい記事が出たときや、注目の記事などを
定期的にLINEでお知らせしていきます

LINEで登録

LINEイメージ

DevTab
成長しつづけるデベロッパーのための情報タブロイド

株式会社ギルドワークス
https://guildworks.jp
  • プライバシーポリシー
  • お問い合わせ

Copyright © GuildWorks Inc. All Rights Reserved.

ページのトップへ