2012/03/05に開催された『DDD(ドメイン駆動設計)をやってみよう』のメモがこちらです。
メモを文章に書き改めたものなので、実際に話した内容とは必ずしも一致していません。
しかも、開始時間に間に合わなかったので、途中からという… 前半は適宜補完してください。
DDDのこだわりポイント
ドメインモデル = 利用者の関心事の模型です。
ドメイン駆動はトレンドではありません。ビジネスの要請によるものです。
事業やビジネスは、得たフィードバックを早く反映したいのです。
ビジネスを展開するうえで、まず作って何もいじらない …というモデルは成立しません。
逆に言うと、役所のような場所ではイテレーティブ・インクリメンタルな開発は成立しないということです。
xDD
テスト駆動(TDD)、振る舞い駆動(BDD)、ユースケース駆動(UCDD)、チケット駆動(TiDD)、画面駆動(ScrDD、エクセル方眼紙駆動(ExDD)など、いろいろあります。ちなみに、リスクやアーキテクチャで駆動するのがRUPです。
xDDは華麗で楽しいのですが、それだけでよいのでしょうか? どこかに特化してそれだけをドライブすればよい、というのはリアルではありえないですよね。だからmultiDDが大切です。状況にあわせ、それぞれの駆動の強みや弱みをうまく組み合わせるのです。
8輪駆動の車があります。これはポルシェより加速性能がよく、燃費なら10倍もすぐれています。タイヤが8つもあるので、あちこちに制御する仕組みが入っています。普通は1輪の箇所に2輪あるのです。もし制御がうまくいかなくて、1つでもタイヤが逆向きに動いたら逆に効率は悪くなるでしょう。駆動の間の強調動作が入り、ものすごい効率を生み出すのです。
プロジェクトでも同じです。メンバーそれぞれが持っている駆動を信頼してうまくまわすのです。オブジェクトも同じです。そして、これがもっと大きなものを動かすというブレイクスルーのポイントです。
ところで、TDDですが、これは受け入れテストを自動化するためのものです。以外だけど、単体テストは必要ありません。単体テストはユーザの価値ではないですよね?
ドメイン駆動を実践
理論編
使ってみてわかったのですが、利用者の要求のキャッチ力が高まりました。だって、ドメイン駆動はユーザの言葉にアンテナを立てないとできないですよね? それから、関心事の構造がクラスや関連としてドメイン駆動設計から出てきたりもしました。また、要件の追加や変更が安全になります。それから、顧客の仕様変更が理不尽ではないこともわかります。ドメイン駆動することによって、単に自分達が見落としていただけということが分かるようになりました。
よい設計の原則というものがあります。関心事の分離 … 単一責任の原則、カプセル化、高凝集(モジュール化)。協調 … 疎結合、インタフェースの最小化(モジュール化)。これらをドメイン駆動に適用するのがドメイン駆動です。
関心事の分離には基本になるパターンがあります。whole-partパターンです。デザインパターンやアナリシスパターンはこれのサブです。wholeはパブリック(表)であり、クライアントが利用する為のものです。ユーザから見て、有用でシンプルなインタフェースにします。partには単一責任の原則です。単機能がいっぱいあるのがよいです。
partをどうまとめればよいでしょうか? これは表の内部設計の問題になります。コントロールもいいですね。委譲はどうでしょうか? 委譲すれば、ロジックはpartに集まります。wholeがコントロールすると、コントローラにif文が溜まりすぎてしまいます。
実践編
まず利用者の関心事の置き場所を作りましょう。これは、関心事についてだけ記述する場所です。
次に、要求を見つけましょう。関心事の中でコードにしましょう。そして、書いたものがユーザの価値になっているかの妥当性を検証しましょう。
※できるかどうかのハードルは高いです。特に関心事だけを置く場所を作るのは難しいです。どうしても関係ないものが混ざってきてしまうからです。
関心事の分離とはなんでしょうか? 画面、UIコントローラ、DBアクセス、メール、メッセンジャーといったものの外に関心事の置き場所を作りましょう。それを画面などが使いにいくのです。置き場所には呼び出し元が何であろうと関係ありません。これを徹底しましょう。こうすると、要求や仕様の変更は、まずドメインに行くはずです。
さて、関心事だけが置き場所にあることをどうやって確認すればよいのでしょうか? grepがあります。インポートしているパッケージがJava.Utilくらいであれば、問題ないでしょう。そうでなければ…
顧客登録の場合を考えて見ます。UIコントローラは顧客登録サービスを呼び出し、サービスはリポジトリ・トランスファー(メール)・顧客を使用するものとします。リポジトリとトランスファーが分離しているのは、これらが別の関心事だからです。ユーザから見ればそれぞれ保管と通知に対応しています。
顧客の言葉を手がかりに、モデル以下にサブパッケージ、クラス、フィールド、メソッドを追加していきましょう。これを繰り返しましょう。ごちゃごちゃしてきたら、リファクタリングの出番です。
また、本を見るのもいいでしょう。技術書ではなく、対象業務の入門書です。できれば洋書にしましょう。クラス・パッケージ名・メソッドの宝庫です。
接頭辞や接尾辞が並ぶモデルは駄目です。顧客XX,
顧客YYといったものが並ぶのは何かおかしいです。顧客.XXや顧客.YYとなるようにしましょう。
リファクタリングはよいものですが、それだけでは時間がかかります。パターンも使いましょう。
用語や概念、何が関心事であるか?どう設計するか?の参考になります。関心の分離のさせかたや協調のさせかたが分かります。パターン本は使えます。目次は種々の関心事を俯瞰できます。
ポイント
バリューオブジェクトを書きましょう。表現力の向上につながります。また、オブジェクトは不変なものとし、演算結果はコピーとして返すようにします。
6つの役割で考えてみましょう。
・外部への見せ方
・調整役
・制御役
・部品の構造化
・サービス提供
・情報保持
DDDのエンティティクラスに相当するものを作ることが大事です。
手順やルールはクラスにまとめてしまいしょう。
顧客の処理や手順、ポリシーはXxProcedure, XxPolicyというクラスにしてしまいしょう。ステートレスにすることもお忘れなく。
アドバンス編
以下はこれからの課題です。
1. 隣接ドメインとの領域の重なりをどう考慮しましょうか? 顧客は、同じように見えるコンテキストでも微妙に単語を使いわけることがありますよね? どういうことなのでしょうか?
2. 状態遷移をどうしましょうか? 状態マシン図はいいものですが、書いたものをユーザは見ませんよね? モデルを作ってもコミュニケーションもフィードバックももらえないってどうなのでしょうか?
3. イベントソーシングをどうしましょうか?
4. 顧客はリストではなく、表やキューブ形式のデータを扱うようになってきていますよね?
5. あいまい検索のニーズもありませんか?
~~~
書いていてつくづく思ったのですが、手書きのメモにはやはり限界があります。かなりの量をメモしたつもりでしたが、文章にするには圧倒的に情報が足りず、かなり補間する必要がありました。話すスピードと比べると、早さが圧倒的に足りていないのです。 …PCを調達しよう。
B面勉強会の皆様、増田 亨様、お疲れ様でした。
0 件のコメント:
コメントを投稿