実践 ドメインモデリング パッケージと画面の関係

ドメインモデルのパッケージと、画面表現とはどんな関係になるだろう。
直感的には、タブ切り替えかな?

そもそも、関連するアクターが別なら、それぞれのアクターごとの画面に分かれるか。

実践 ドメインモデリング パッケージで整理する

「ユースケース駆動開発実践ガイド」では、パッケージを使った整理は、ユースケースの組織化と、実装コンポーネントの組織化にでてきます。
ドメインモデルでパッケージを使った整理は、直接はでてきません。パッケージを使うほどドメインモデルが膨らんだら、そもそもモデルを分割というか、別プロジェクトというか、そんな発想なんでしょうかね?

Domain-Driven Design ( DDD ドメイン駆動設計 ) では、基本パターンとして、Modules(モジュール)パターン があります。 人は一度に考えられる範囲は限界があるので、適切な単位に分割する。もちろん、設計の大原則 高凝集で疎結合が大切。
また、DDD では、モジュール名(パッケージ名)も重要な Ubiquitous Language(共通言語)の一部です、と言っている。

ひとかたまりと感じたら、扱いやすくパッケージにして、名前をつける。それで、そのかたまりの内容と名前が、関係者で共通理解か話し合うことが役に立ちそう。
同じドメインモデルに合意していたつもりでも、パッケージ範囲はまた別の理解をもっていそうだし、また、名前のつかけた(注目している特徴)もたぶん違っている。

以前に「汎用的であいまいな言葉」より「不細工だが長くて説明的な言葉」のほうが、モデリングの出発点、議論の手がかりとして役に立つと書きました。

「不細工で長く説明的な言葉」を並べると、同じ単語が含まれたグループが見つかることがある。 これは、もう単純にパッケージ化の候補ですね。

例えば、顧客氏名、顧客住所、顧客アカウント...
これが、顧客パッケージの氏名、住所、アカウント、という感じになる。

C# では、Java のパッケージにあたるものを「名前空間」と呼びますよね。ドメインモデルは用語集、つまり名前空間そのものですが、パッケージを使って、階層的に名前を整理したほうが便利そうですね。

データベースでも、例えば、顧客スキーマ以下に、氏名テーブル、住所テーブルをひとかたまりにする。

ドメインモデルは、パッケージ階層は基本は、1レベルだけだと思います。
パッケージが2段階以上になる規模のモデルは、一つのアプリケーションで関係者で共通のボキャブラリを持つには大きすぎると思う。

複数のアプリケーションが集まった開発プロジェクトもあるわけで、その場合、どうするの、というのは、DDD の Strategic Design (戦略設計) にいろいろパターンが紹介されている。 個人的には Separate Ways(別々の道)パターン、つまり、統合はそもそも必要ないんじゃないの?無理して統合するより、別々にしといたほうがメリットが大きいんじゃないの?というのが実践的な設計としては、有力なことが多いと思っています。

Strategic Design は、別の機会に取り上げたいと思います。


実践 ドメインモデリング 汎化

ドメインモデルについて、しょっちゅう画面との関連を書いています。これは、ICONIX プロセスが動的モデル(振る舞いモデル)で駆動しながら、静的モデル(クラスモデル)を進化させる、というアプローチだからです。
画面紙芝居→ユースケース図→ユースケース→ロバストネス図→シーケンス図という一連の振る舞いモデリングをしながら、並行して初期ドメインモデル→概念クラスモデル→実装クラス設計→コードという流れで進む。

画面の紙芝居から、初期のドメインモデルを2時間程度で作成し、あとは、振る舞いモデルを詳細化しながら、そのたびに、ドメインモデルをより詳細に、そしてしだいに実装クラスに成長させていく。
(ついついモデルのことばかり書きますが、ICONIXプロセスは、実装を重視した実践的な開発のやり方です。)

設計と実装の中心は、静的モデル(クラスモデル)。関係者とのコミュニケーションには動的(振る舞い)モデル。それを、いつも同期をとるようにする。というのが ICONIXプロセスのアプローチだと思います。

前置きが長くなりましたが、実は、ドメインモデリングでの汎化と画面の関係がちょっとあいまい。「ユースケース駆動開発実践ガイド」を読んでも汎化は「概念の整理」の手段という説明があるだけ。画面(振る舞いモデル)とか実装との関連があまり触れられていない。

「ユースケース駆動開発実践ガイド」で使われている図の汎化関係:
・「書籍一覧」のサブクラスに「検索結果」や「購入予定リスト」
・「支払方式」のサブクラスに「クレジットカード」と「請求書」
・「書籍レビュー」のサブクラスに「編集者レビュー」と「読者レビュー」

強いて画面で考えると、
・各種の一覧機能がメニュー化されて「書籍一覧」という見出しでグルーピング
・支払い方式をラジオボタンで選択式にする
・書籍詳細画面で、レビュー欄に「編集者レビュー」と「読者レビュー」を並べる
という感じですかね。

画面で考えると「集約」とあんまり区別がつかない。
共通の操作や属性を、スーパークラスに定義することが、集約との一番の違いかな。
画面デザインでは、共通の操作は、ボタンやリンクのデザインを共通にすることかな?
属性の共通化は、画面デザイン上、同じ属性には、同じ体裁を指定する。

ふむ。 XHTML + CSS で、クラス属性の定義と密接に関連するということか。

実装クラスで考えると、汎化はそのままスーパークラスとサブクラスでの実装と関係しそうです。個人的には、実装では汎化・継承は消極的です。

実装面では、継承を使ったことで、読みにくさ、思わぬ副作用、不十分なテストなど失敗体験が多く、その割には、メリットの手ごたえを感じたことが少ない。


実践 ドメインモデリング 集約=オブジェクトのかたまり

Domain-Driven Design( DDD ドメイン駆動設計 ) の Aggregates(集約)パターンは、「ブドウの房(ふさ)」の写真で始まっている。

ブドウの一粒一粒がオブジェクトで、それがブドウの軸にくっついてひとつの房になる。粒のほうをつまんで持ち上げようとすると、粒がとれてしまう。軸を持てば、房全体を持ち上げることができる。

粒がドメインオブジェクトで、軸が「集約のルート」オブジェクト、ということを表しているんでしょうね。

ドメインモデル(概念クラス図)は、オブジェクト(箱)と集約(線)だけで描く。しかし、集約はぶどうの房にあたる「かたまり」を表現する重要な手段。

集約関係の図を見て、集約ルート(ブドウの軸)とかたまり(ブドウの房)というイメージがつかめると、ドメインモデルの議論がより深くなり、モデルがより洗練される。
DDD の Aggregates(集約)パターンの説明の図にあるように、集約を手掛かりに、手書きで、ひとかたまりを図示した上で、みんなでモデルを検討する。

集約で表現したこの「かたまり」は、その単位での操作する。房を構成する一粒単位では、操作しない。

それが、問題領域の構造を正しく表現しているかどうかは重要な検討ポイントですね。
この集約による「ひとかたまり」は、当然、画面や画面遷移のデザインに反映すべきだし、DDD のFactories(ファクトリ)パターンや Repositories(リポジトリ)パターンでの実装を検討すべきです。

そういえば、クラスタというのは「房」という意味だったんですね。私は「クラスタ」は「分散」というイメージを持っていたので、理解が正反対でした。やはりカタカナ言葉はあぶないなあ。

実践 ドメインモデリング オブジェクトの粒度と画面デザイン

オブジェクトの粒度は、画面デザインと強く関係する。

というか、オブジェクトを目に見える形で表現するひとつの手段が画面ということですね。

画面とオブジェクトが一対一というケースは少ないかな?

一つの画面をいくつかのブロックに分け、複数の表示項目やリンクをひとかたまりにして、枠で囲んだり、背景色を変えたり、空白のかたまりの区切りを表現する。

この分割の視覚表現と、ドメインモデルのオブジェクトの粒度とは一致するべき。画面の視覚表現が常に正しいとは限らない。デザイナがどこまで意味を分析してデザインしているかにもよる。モデル側の修正になることもあるだろうし、画面をモデルに合わせて修正すべきこともあるでしょう。

XHTML + CSS は、ドメインモデルを実装する一つの手段なんだと思う。
ドメイン層だけが「ドメインモデル」の生きる場所ではないでしょう。
Domain-Driven Desing の Eric Evance は、Layered Architecture(層状アーキテクチャ)パターンの説明で、 Domain 層こそ、モデルの生きる場所、といっているけどね。 プレゼンテーション層だって、モデルを表現するたいせつな場所です。

実践 ドメインモデリング オブジェクトの粒度 同時性

オブジェクトの粒度(大きさ)のチェックポイントその2。

オブジェクトのライフサイクルで発生する5つのアクション
CLGUD ( Create, List, Get, Update, Delete ) に注目して、複数の属性の値が同時に作成、変更されるかを検討する。

たとえば、4つの属性を持つ氏名(姓、名、姓カナ、名カナ)クラスを考える。

これ、CLGUD の単位として、ひとかたまりで扱う。
姓だけ変更とか、名カナだけ変更とかは、あるかもしれないけど、「氏名」変更画面で全部やりますよね。(名カナだけを変更する専用画面が必要な問題領域なら、話は別ですが)
「氏名」変更画面での変更は、ユーザの意識としては「姓」だけ変更かもしれないけど、オブジェクトとしては、姓、名、姓カナ、名カナの4つの属性を新しくセットした、別のオブジェクトが誕生する。

氏名クラスは、適切な大きさ(かたまり)と判断できる。

逆のケース。
たとえば、顧客クラスに氏名、住所が属性として並んでいる場合。
登録時は同時かな?
でも、変更は、氏名変更と住所変更は別モノ。だとすると、ずらっと属性を並べるのではなく、「氏名」オブジェクトと「住所」オブジェクトに分離して「顧客」オブジェクトで集約するのが適切でしょう。

まあ、顧客情報変更画面で、氏名も住所を変更できる、という設計もありでしょうが。
氏名変更と住所変更は、ユースケース(利用場面)が、別だと思うんですけどね。




実践 ドメインモデリング オブジェクトの粒度(大きさ)

画面の紙芝居や要求の箇条書きから、問題領域の用語を拾い出していく。初期のドメインモデルとして、名前だけ並べたクラス図を描いてみる。
ユースケース記述を始めると、入力項目などを発見するので、ユースケース駆動開発実践ガイドに従って、ドメインモデルに新しい用語として追加する。

この時、クラスとして追加するか、クラスの属性として追加するか迷うときがある。いわゆるオブジェクトの粒度の問題。

UML の理論的(?)には、属性と関連クラスとは完全互換なので、どちらでも良い。どちらも has-a で説明できる。

ドメインモデルを作るのは、問題領域を分析し、役に立つソフトウェアを作るためですよね。特に関係者で共通の用語と理解を醸成することが大切。
この目的から考えると、やはり、なんらかの決めごとをつくって粒度(大きさ)の考え方は揃えたほうが実践的に役に立ちそう。
毎回、属性かクラスかで議論することは、どう考えても効率的ではない。

A. 徹底的に小さなクラスに分解
B. 徹底的に大きなクラスに属性追加

あたりまえだけど、この中間のどこかに答えがある。

小さなクラスに分解すれば、最後は、文字列(String)、数(Number)、日付(Date)というプリミティブなオブジェクトまで分解できる。
すべてこの単位までオブジェクト化して、それを関連でモデリングするというのはどう考えてもやりすぎ。扱いにくすぎる。

大きなクラスに100も属性があれば、なんぼなんでも大きすぎる。

私たちが現場で使っているいくつかの判断テクニック。

小さいすぎるオブジェクトの検出

○○番号と言ってとき、しっくりくるか?
もし、しっくりくれば、それは、Entity として個別に識別して管理したいオブジェクトである可能性が高いので、独立したクラスとする。

しっくりこない場合は、独立したクラスというより、他のクラスの属性と考えたほうがよさそう。

もちろん、完全なルールではないけど、いちおうの判断材料になる。

大きすぎるオブジェクトの検出

属性数が5を超えたら少し怪しい。多くて7。それ以上の属性になったら、クラス分割を検討する。

これは、人間が一度にぱっと把握できるのは 5プラスマイナス2、つまり3から7という認知工学の仮説(?)を参考にした数字。

論理的に属性であるべきかどうか、という観点ではなく、属性が多すぎたら理解が難しくなるよね、ということ。

この5プラスマイナス2は、マジックナンバーで、大きさ判断には何にでも使っている。メソッドの行数、Public なメソッド数、パッケージ内のクラス数などなど。
人間がぱっとみて把握しにくい大きさになったら、分割して、扱いやすくしましょう、ということ。

具体的なクラスで、関係者でこのルールで話をしてみると、だいたいおさまりが良いクラスになってくる。
まあ「いい加減」な決めごとです。

実践 ドメインモデリング 長い説明的な名前

ぴったりの名前を見つけるというのは、設計の基本であり、また奥義ですよね。
Domain-Driven Design の Intention-Revealing Interfaces(意図の明白なインタフェース)パターン でも意図の明白な「名前」がコミュニケーションの絶好の場所であるといっている。

かといって、最初から良い名前が簡単に見つかれば苦労しない。前の記事で書いたように「カタカナ」言葉を禁止すれば、さらに、適切な言葉が見つからない。語彙欠乏症がはっきりする。

こういう時、とりあえず説明的な名前をつけてしまう。
・公開条件を満たしている応募書類
・いつまで待てるかの指定
まず、不細工でも手がかりを作る。手がかりがあれば、それをみんなでブレスト(おしゃべり)しながら、良い名前(用語)を見つけていく。しゃべっているうちに突然ぴったりの名前を誰かが見つけることもあるし、一晩寝かせたら、自然に良い用語がでてくることもある。
いずれにせよ、ここに何か問題領域の重要な概念がある、という臭いを感じたら、とりあえず、説明的な名前をつけた不細工なクラスを追加しておく。

不細工であることは、「Fix Me」という叫んでいるのが良くわかるので、自然にリファクタリング(名前の変更)の対象になる。

なんとなくもっともらしい「カタカナ」言葉とか「期間指定」のようにどこでも登場しそうな言葉で済ませると、理解の不一致や問題理解のあいまいさが隠されてしまう。

良い名前に困ったら、不細工で説明的な言葉でとりあえず済ませ、そこを出発点にして、モデルを洗練させていけば良い。

実践 ドメインモデリング モデルの組織化

ICONIXプロセス(ユースケース駆動開発実践ガイド)では、ドメインモデル(概念クラス図)に、アクターを含めて描く。
アクターを基点にして、オブジェクトの関係ネットワークが広がっていく図に描く。

問題領域の用語は、どのアクター(登場人物)から見るか、で違う言葉になることが多い。例えば「発注」と「受注」は「注文」を別の登場人物から見た用語。

ICONIX プロセスは、アクターを概念クラス図に持ち込むことで、いろいろな視点の用語を混在しながら、うまく整理するやり方に見える。

いろいろな視点からの部分図を一枚の絵にまとめる。これはキュービズムですね。

アクターは図の左橋に配置され、ドメインオブジェクト(用語)のナビゲーションの基点になる。

いろいろドメインオブジェクトの集約ルートになるオブジェクトは、自然に図の中央に配置される。

図をきれいにレイアウトする作業はムダです。
でも、ICONIX プロセスの簡単な記述ルール、つまり
・アクターを左端に配置
・ナビゲーションの基点となるオブジェクトとアクタは、関連の線をきちんと描いて明示する
を守れば、自然とドメインモデルの図が組織化される。

図の真ん中にあるさまざまな集約のルートになるオブジェク(用語)が中核用語であることは一目瞭然。

もし、そのオブジェクトが中核でないのなら、本題からはずれたオブジェクトを詳細に追いかけすぎているということ。
だから、モデリングのレビューでも、図の中央の集約ルートオブジェクトの妥当性をまず議論すべきですね。

Domain-Driven Desing の Aggregates ( 集約 ) パターンの実践です。

実践 ドメインモデリング 「カタカナ」用語はアンチパターン

ドメインモデル、ICONIX プロセスでは「用語集」、Domain-Driven Designでは、Ubiquitous Language(ユビキタス言語)パターン、を作る時「カタカナ」言葉はアンチパターンです。

カタカナ言葉もりっぱな日本語なので悪い言葉ではないのですが、定義があいまいで、人によって理解・使い方に違いがあることが多い。問題領域の理解の違いを「カタカナ」言葉を導入すると、共通理解になったような気がする。
私だって、何も考えずに書くと、ついついカタカナ言葉の乱発している。反省。

「レジュメ」って何?という議論をする時、「履歴書」「経歴書」「応募書類」とか、日本語を並べながら、お互いの見解をしゃべりあうと、話がより具体的になる。問題領域の具体的で本質的な構造が見えてくる。

「チケット」で話していてもピンとこなかったことが「回数券」という用語を導入したところ、関係者であっというまに共通理解。

カタカナ用語は、とにかく怪しいと決め付けて、より具体的に話ができる日本語用語を使ってみましょう。

この記事の書き出しをちょっと書き直してみると:

問題領域の模型、ICONIX 手法では「用語集」、問題領域駆動の設計では「共通言語」を作る時「カタカナ」言葉は使ってはいけない。

わかりやすくはならないけど、このほうがいろいろな意見がでてくるかな?

calendar
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
<< July 2017 >>
システム設計日記を検索
プロフィール
リンク
システム開発日記(実装編)
有限会社 システム設計
twitter @masuda220
selected entries
recent comment
  • 番号より名前。 ニーモニックコードより名前。 【パターン】
    師子乃 (03/10)
  • Smart UI が優れている?
    masuda220 (03/10)
  • Smart UI が優れている?
    kagehiens (03/09)
  • オブジェクト指向プログラミングの教え方?
    masuda220 (12/05)
  • オブジェクト指向プログラミングの教え方?
    ZACKY (12/04)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    masuda220 (08/14)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    kompiro (08/14)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    masuda220 (06/13)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    JHashimoto (06/13)
  • 「オブジェクトの設計力」 スキルアップ講座やります
    masuda220 (02/28)
recent trackback
categories
archives
others
mobile
qrcode
powered
無料ブログ作成サービス JUGEM