コーディング、プログラミング、ライティング

モデルを実装するための手段で、私が良く使っているのは、Java, SQL, XML ですね。
XML は、ミドルウェアのセッティング, ant の build 定義、データ交換フォーマット、などいろいろな目的に使っている。

いわゆる言語ですね。

ここで、質問。

「実装する作業」をなんてよぶか?

コーディング

昔から使われているコーディング。今も、HTML コーディングとかは言うらしい。

code a message

というと、メッセージを暗号化するとか、符号化するとかという意味になりそう。
無電のモールス信号も、たしか、 Morse code だったような気がする。

ドメイン駆動設計的には、実装作業をコーディングする、というのは、よくなさそうですね。
関係者で共通の言葉・表現を、モデリングでも、実装でもどこでも使おう、というユビキタス言語の意図からはずれる。

プログラミング

番組の予定表とか、式次第とかで使われるように、「時系列」に順番にならべるという感じで使われる。
スクリプティングなども近い感じですかね。

プログラミングは、手続き型の言語では、ぴったりのような気がする。
Java なんかでも、手続き的に書く場合は、プログラミングでしょうね。

ドメイン駆動設計的には、ドメインロジックをトランザクション・スクリプトとして実装すれば、プログラミングという言葉も悪くはない感じ。

ライティング

個人的には、ドメイン駆動設計の実装は、ライティングだと思っている。
「書き物」という感覚ですね。

ドメインの知識、業務のルールをまとめた、業務マニュアルは、「ラインティング」する。
ドメイン駆動設計の実装は、業務マニュアルのライティング作業そのものなんだと思います。

マニュアルも、ステップ・バイ・ステップ式の手続き型ではない。
「○○とは◇◇と△△の合計である」というような用語の定義が中心にしたマニュアルのイメージ。

技術的には、宣言型ということですかね。

そのオブジェクト(対象物)が何であるかとか、ドメインの知識、業務のルールを、手続き的にはではなく宣言的に書く。
Kent Beck も、 Implementation Patterns の中で、「宣言的」ということを強調していましたね。

---

プログラミング言語という呼び方がかわるとは思えないけど、ドメイン駆動設計の実装は、コーディングやプログラミングでなく、ライティングでやるべきでしょう。 それも、できるだけ宣言的に。

ドメイン駆動設計 序文 リード

ソフトウェア設計の達人たちは、ドメインのモデリングと設計を、最重要課題と考えています。
20年以上も前からそうでした。
しかし、ドメインのモデリングと設計で、何をやれば良いか、どうやれば良いかは、ほとんど書かれていません。
はっきりとした形には、なっていません。
しかし、オブジェクト指向設計の底流として、ひとつの価値観が明らかになってきています。
私は、その価値観をドメイン駆動設計 ( Domain-Driven Design ) と呼んでいます。

この十年間、私は、いろいろなビジネス分野と技術分野で複雑なシステム開発をやってきました。
その仕事の中で、設計と開発のさまざまなベストプラクティスにチャレンジしてきました。
オブジェク指向の世界の、すばらしいリーダーたち明らかにしてきた、設計の良い考え方、習慣、やり方を、自分の仕事の中に取り入れてきました。

いくつかのプロジェクトは大成功でした。
いくつかは失敗でした。

成功したプロジェクトに共通していたのは、すばらしいドメインモデルの存在です。
反復しながら進化させた、現実世界のよくできた模型(リッチなドメインモデル)こそが成功要因でした。

この本は、設計の考え方の枠組を提供します。
ドメインの設計のやり方を、みんなで議論するための用語集を提供します。
先人たちのさまざまなベストプラクティスと私の経験と考察を統合した内容です。

複雑な問題領域に取り組んでいる開発チームのみなさんは、この本のフレームワークを使って、ドメイン駆動設計を、システマティックに進めることができます。

オフィスの移転プロジェクト スコープ管理

オフィスを移転することになった。

todo list を書き出しているうちにちょっと混乱してきた。

現オフィスからの退去は、退去日が明確で、退去日までにやるべきことを具体的に洗い出せる。

新オフィスへの入居が、問題。

入居自体は、4月1日からなんだけど、さみだれ式に少しずつ準備していく感じ。
ゴールが不明確。

なんか、成功するプロジェクト(退去)と失敗するプロジェクト(入居)の典型例の臭いがしてきた。

対策は、ゴールを明確にすることなんだけど、なかなか todo が固まってこない。

で、思い出したのが、「タイムボックス」手法。

さみだれ式でゴールがあいまいなら、4月30日、完了、というように最初に期日を設定してしまう。

で、4月30日にどういう状態になっているかに注目して、 to do を書き出しはじめたら、だいぶまとまってきた。
混乱の元になったタスク候補は、4月30日までに必須でなければ、割愛。(実際には、他の場所に備忘録としてメモ)

これでだいぶすっきりした。

というか、4月30日までに最低限やることは、
・現オフィスからの荷物の受け入れ
・インターネット回線引き込みだけ

携帯電話と、ノートパソコンがあるので、これでも業務ができちゃいそうな感じ。

さすがに、机と椅子くらいは、用意したいけど、必須ではない。
困ったら買うことにしよう。

ユビキタス言語 どこでも業務の言葉

ドメイン駆動設計(DDD:Domain-Driven Design)でもっとも重要なパターンがユビキタス言語

GoF のデザインパターンとかは、Java での実装サンプルも多いので、パターンとプログラムの書き方が近いと思っている人も多いと思う。

どうやら、むこうの人たちは、パターンというものをもっと広く捉えていて、良い考え方とか、うまいやり方というように、結果(実装)よりも、過程(設計する)に関心の重点があるようだ。

ドメイン駆動設計の「パターン」も、モデリングの良い考え方とか、うまいやり方を整理した感じのものが多い。

ユビキタス言語

結果(実装)を中心で考えると...

ユビキタス言語パターンは、Java のコード、SQL、HTML/CSS、XML、テストスクリプトなど、プログラミング言語に、ドメイン、関心分野の用語を満載すること。ビジネスアプリケーションなら、ビジネスの用語を満載すること。

モデリング言語である UML の図なども、ビジネス用語でいっぱいにする。

過程(やり方)を中心に考えると...

モデリングをやっているときに、チーム内や顧客との会話も、ビジネス用語を満載にする、ということ。
最終的なコードや図よりも、普段のなにげない会話に、できるだけ豊富にビジネスの言葉をちりばめることが、ソフトウェア開発の成功パターンである。それがユビキタス言語パターンの核心でしょうね。

顧客に質問する時は、もちろん、業務の言葉で質問する。
大切なのは、技術的な課題も、顧客に説明が必要なら、「業務の言葉」で説明すること。

サーバー増設が必要でも、技術用語を並べたててはいけない。
そうではなくて、
「顧客サポート担当者が10人同時に会員検索した時に、現在10秒かかっているのが、2秒に短縮できます」
というような説明をする。これなら、相手にも通じる。

機器構成や分散技術方式なんかどうでもよくて、費用(金額)と業務上の効果がわかることが大切。

エバンスが InfoQ のインタビューで話しているように、ドメイン駆動設計(DDD)でもっとも重要なパターンは、ユビキタス言語

そして、ユビキタス言語は、単に、コードを業務の言葉で満載にするだけでなく、開発の現場の、日々の会話を、業務の言葉で満載する。

それが役に立つソフトウェアを開発する、最良の習慣。

ドメイン駆動の単体テスト

ドメイン層を UI や データアクセスから分離すれば、ビジネスロジックに的を絞った単体テストをやりやすくなる。

ドメイン層のオブジェクトは、業務の知識を持つことが責務。

・業務で使う情報を提供できる。
・業務の判断ルールを知っている。
・他の業務クラスと連携する。(処理の依頼や、情報の問合せをする)

分離だけではなく、ユビキタス言語の実践、つまり、業務の言葉で、クラスも、テストも記述することもたいせつ。
そうすると、ドメインクラスとそのテストの記述は、業務マニュアルのように、ビジネスのルールを満載した内容になる。

プログラム経験ゼロの業務の専門家だって、コードレビューができるくらい、業務中心の記述になる。


例:値引きルールのテスト

例えば、DiscountPolicy クラスは、値引きについての業務知識を持っている。
今までの購入金額累計が、値引率に関係するなら、UserAccount クラスに、累計購入金額を問合せる。
シーズン割引料金を設定しているなら、BusinessCalendar クラスに isSummer( BusinessDate reservationDate ) を問い合わせる。

JUnit のテストコードは、あたりまえだけど、こういうビジネスルールを適切に処理していることを検証するテストコードを書く。 setter/getter なんかは、テストコードを書かない。

このテストコードは、ビジネスルールの具体例、こういう場合は、こういう割引率、を表明した、りっぱな仕様書かつ業務マニュアルになる。
業務の専門家がみたら、Java を知らなくても、値引き率、それも、購入金額累計やシーズン割引を正しく計算しているかのチェックができる。

そういう記述をすべき。ドメイン駆動設計(DDD)の「ユビキタス言語」を実践していれば、自然にそういう記述に進化していく。

例:データの検証

入力項目の検証、バリデーションロジックも、たいせつなビジネスルールですね。
特にデータ型、形式、長さチェックや、必須チェックは基本パターン。

このルールは、UIつまり、HTMLコードにも登場するし、データベースにも登場する。そして、ドメインオブジェクトでも実装する。

これは、目的が違うので、それぞれの場所で適切に記述しましょう。
同期をとったり、バイト数と文字数の問題、NULL と空白の扱いなど、HTML, データベース、ドメインオブジェクト間で、不整合のネタはいろいろあるけど、それはまた、別の機会で検討したい。

入力データの検証ロジックは、私たちは、ドメインオブジェクトに記述する方針。
Validator クラスとか作らない。
EmailAddress クラスに、Eメールのアドレスの形式、長さ、携帯メールかどうかの判断、などの知識を持たせるようにしている。

単体テストで、クラスが、 Eメールアドレス の知識を正しく持っているかを検証する。
テストコードも、クラスのコードも、業務の専門家が見れば、ルールの理解にまちがいがないかとか、過不足がないかとか、チェックできるわけだ。

ドメイン : 問題領域? インターネットの住所?

ドメインと言えば、インターネットの住所。ホームページのアドレスというイメージが一般的でしょうか?
分析・設計の世界では(問題の)「領域」とか「分野」とかを指しますね。

日本では、使う文脈によって、まったく違うイメージで使われている感じがします。
外来語(カタカナ言葉)では、よくあることですね。

ドライバ=運転手
ドライバ=1番ウッド
ドライバ=ねじまわし
ドライバ=駆動装置
...

でも、おそらくネイティブの人たちは、同じ言葉とし使っているはず。言葉の感じ、コアのイメージは、ひとつなんだと思います。

ドライバの例だと「力づくで動かす」という感じらしい。どれも、そのままだと動かないものを、無理やり動かしている感じですね。

ドメインの場合は、インターネットにしても、分析・設計用語にしても、日本では、専門分野で使われている言葉なので、それぞれの文脈の中で、特殊な言葉でして使われている感じですね。

でも、ほんとうは、やっぱり同じ意味の言葉。

だって、たとえば、「ベストカンパニー社」の情報システムを作るなら、

インターネットのドメイン は best-company.co.jp になる。
で、分析設計の問題領域は、ベストカンパニー社のやっているビジネスや業務。
それで、実装する時には、クラスのパッケージ名は、jp.co.best-company.business なんてかんじになる。

インターネットのドメイン=問題領域というわけです。

ベストカンパニー社が、インテーネット上でショップを運営しているなら、

インターネットのドメインは、shop.best-company.co.jp 。で、サービスを提供するためのソフトウェア開発の問題領域は、ベストカンパニー社のショッピングサイト。

URL が intra.best-company.co.jp であれば、ベストカンパニー社の社内業務システム、というわけだ。

ようするに、ドメインとは、インターネットの住所であり、問題領域でもある。同じものを指しているわけですね。

ドメイン駆動設計の実践度 簡易診断

ドメイン駆動設計の実践度を簡単に診断する。
ソースコードをざっと見れば、どの程度、ドメイン駆動設計を実践しているか判断できる。

ユビキタス言語がどの程度浸透しているか?

・ソースコードで、クラス名、メソッド名、変数名、パッケージ名が、業務の用語になっている度合。
・テーブル名、カラム名、スキーマ名が業務の用語を使っている度合。
・HTML の id 属性、class 属性に、業務の用語を使っている度合。

もうちょっと細かい話をすると、ビジネスロジックを表現するクラスで、String とか Integer を「使っていない」度合。

たとえば、住所を、String で定義するか、 PostalAddress クラスを作るかの違い。
あるいは、年会費を AnualFee クラスで宣言し、内部で、BigDecimal ではなく、Yen クラスを使う。

PostalAddress クラスは、住所の形式や妥当性の知識を持っている。
Yen クラスは、parse() , format(), validate() などで、金額(円)に関する知識を豊かに持っている。


ドメインオブジェクトと UI / データアクセスから分離しているか?

業務の用語が登場するクラスに、UI( button, session, page, ... ) などが混入している度合。
業務の用語が登場するクラスに、JDBC や SQL が混入している度合。

もうちょっと具体的には、import 文をチェックする。

業務の用語が登場するクラスに、java.sql パッケージとか、java.net パッケージが混入している度合。

ドメイン駆動、オブジェクト指向、モデル駆動

ドメイン駆動とオブジェクト指向

ドメイン駆動設計は、オブジェクト指向設計(OO)の特別な形。

いちばんの関心ごとの領域のオブジェクトを設計すれば、ドメイン駆動設計になる。
それ以外の領域のオブジェクトの設計は、単なるオブジェクト指向設計。

業務用のWebアプリケーション開発は、いちばんの関心ごとはその業務ですね。
だから、実世界の登場人物やモノゴトを、オブジェクト指向で分析・設計するのがドメイン駆動設計っていうわけだ。

Webアプリケーションだから、Webページや、セッション管理、DBアクセスも、もちろん問題の一部。オブジェクト指向の技術を活用する。でも、こっちはオブジェクト指向だけど、ドメイン駆動設計ではない。

いちばんの関心ごとは、「ビジネス」なんだから。

オブジェクト指向でない、ドメイン駆動設計ってあるの?

答えは Yes でしょうね。
手続き型(機能指向?)やデータ指向でも、ビジネスを課題を中心にすえて、設計すれば、ドメイン駆動設計なんだと思います。

ウォーターフォールのやり方は、ドメイン駆動の代表例だと思います。業務の視点を重視しますから。
作業の種類が多く、時間がかかるので、そのうち、いちばんの関心ごとを見失っちゃうことが多そうですが。

Evans は、"Domain-Driven Design" の序文で、ドメイン駆動設計は、オブジェクト指向であり、アジャイルな(軽い)やり方と相性が良いといっていますね。


ドメイン駆動とモデル駆動

Evans は、ドメイン駆動設計は必然的にモデル駆動設計だと書いています。

モデル駆動じゃない設計ってなんでしょう?

イメージとしては、コード駆動設計ですかね。模型を作らず、いきなり実物を作る。

腕のある技術者だと、単機能のツールなら、顧客の話を聞きながら、模型なしで実物を作っちゃうと思います。
頭の中に設計イメージがあるので、わざわざ、模型を作らないでいきなりコードで書いちゃう。

エディタとコンパイラがあれば、仕事になる、とっても軽やかなやり方です。

ただ、これで解決できる問題ばかりではない。現実世界はもっと入り組んでいる。
人間はむちゃくちゃ優秀だから、その入り組んだ世界でも良い仕事ができる。

機械はバカだから、世の中の仕組みを整理して、少しずつ問題領域の知識を教えてあげる必要がある。

入り組んだ問題領域をソフトウェアにするには、まず、模型を作る。
模型と作りながら、現実世界の知識を増やして形にしていく。これがモデル駆動設計。

問題が複雑なら、モデル駆動設計が必然。


モデル駆動でないドメイン駆動設計ってあるの?

答えは、もちろん Yes。

いきなりコードで書いても、問題の解決できれば、それはすばらしいドメイン駆動設計でしょう。

UMLよりメモ書き?

ペアモデリング

若手の技術者とペアモデリングしていた。
まあ、分析・設計のOJTですね。

UMLツール から 手書きに変更

最初は、モデリングツールで UML の図を描いて修正していた。
だけど、きれいな図に完成したがって、ムダな時間とエネルギーを使っていることに気がついた。

で、エディタで記法用語とその用語を使ったビジネスルールを箇条書きする方法に変更。
そしたら、純粋にあやふやな用語の議論に集中できて、効果抜群。

汎化関係など、少し理解がへんだったところは、裏紙に、クラス図もどきを、ささっと手書きして議論。
話をしながら、絵がぐちゃぐちゃになってきた。
だいたい共通理解になったところを確認するために、別の紙に、さっと書きなおして、最終確認。

ツールで、UMLでやっていたときに比べると、体感としては4倍くらいスピードアップした感じ。

エディタの修正もできるだけ少なくした。
印刷して、手書きでポイントを書き込む。
ぐちゃぐちゃしてきたら、いったんエディタで書き直し。
また、手で書き込みいれながら、議論。
最終版は、その書き込み版。電子化はしなかった。

手書きは、ほんとうに効率的。

今回は、売上計上ルールの込み入った部分が問題領域。
どういう商品種類の時は、どういう計上ルールを適用するかを、簡潔に説明する「用語」のセットをペアでモデリングしながら、整理。

すっきり整理できたところで、その用語を、そのままクラス名とメソッド名として使って、コード実装。

ドメイン駆動設計の「ユビキタス言語」の実践ですね。

ユビキタス言語になっている、つまり、コードにドメイン概念がそのまま表現されているので、モデリングの成果物は捨ててしまっても良いわけです。

知っていることをモデルにする

ドメイン駆動設計の三ステップ。

(1)その分野に詳しい人から知識を吸収する
(2)モデル(模型)として形にする
(3)コード(実物)として形にする

この作業の道具は「言葉」です。

(1)知識の吸収

その分野の説明書や解説書があれば、とりあえず、基本の用語は知ることができる。
最初は、意味がわからない、使い方がわからない用語が多い。

その分野に詳しい人と話すことで、用語の使い方や意味がだんだんわかるようになってくる。

「話す」も「読む」も基本は、日本語ですね。
目新しい用語がでてきても、いちおう日本語ですから、まあ、なんとなくは理解できる。

知識の吸収の道具は、「言葉」ですね。

ありがたいことに、日本語。
困ったことに、専門用語は、外国語に近い。
困ったことに、その分野の意味と、一般的な意味が違うことも多い。

いずれにしても、知識の吸収で使う道具は「言葉」です。

聞く・話す
読む・書く

(2)モデルとして形にする

モデルも「言葉(言語)」を使って記述する。

いちばん原始的なモデルは「メモ書き」ですね。
専門家と話したときのメモとか要望事項の箇条書き。

まだ未整理。
だけど、消えてしまう話し言葉ではない。
読み返しができる「書いた言葉」が、モデルの最初の形。

モデル(模型)で大切なのは「形」にして、みんなで評価したり、修正したりできるようにすること。

モデルを記述する道具としては、「言葉」以外に、UMLがありますね。
私は、実際には、あまり正式のUMLを書いたことはありません。

手書きで、四角、矢印、丸、それといくつかのキーワードで、裏紙に落書きすることも多い。

若手の技術者はツールを使うのも速いので、手書きより、いつでもツール派が多い。
その場合では、私たちのチームでは、厳密はUMLの記法にはしたがっていないことが多い。
(ツールに文句を言われるとしぶしぶ従う、という感じ)

目的は、みんなで議論できる模型ができればいいので、あまり、UMLの細かいところにこだわらない。

UMLも構造系のクラス図と、振舞系のアクティビティ図、ロバストネス図、シーケンス図らしきものをいろいろ描く。 状態遷移図も使いますね。

ユーザよりの人たちとは、画面のラフデザイン、ワイヤーフレーム、エクセルの項目定義書、...
他にも、いろいろな模型を作りながら、みんなでわいわいがやがや。

ある程度の形が見えてくると、今度は、わりときっちりツールでUMLを描き出す。
清書のためではなく、Java や、DDL 文をツールで自動生成して、楽がしたいから。

(3)コード(実物)として形にする

ここでも「言葉」を使う。
もっとも、Java とか SQL とか、まあ、人工的で制限の多い言葉ですけどね。

文法制約は厳密だけど、クラス、メソッド、変数の名前は自由につけることができる。
モデリングで見つけた概念(用語)を、できるだけ、そのまま Java のクラス名や、テーブル名にするようにしている。

モデル(模型)をちゃんと作っておくと、ここの作業はほんとうに楽になる。
また、モデルの言葉(名前)と、コードの言葉(名前)が一致しているので、つまらないバグが減る。

コードとモデルが近いので、コードを書きながら、モデルの不備を見つけて、モデルの修正なんてこともよくある。

XHTML の id 属性や、class 属性も、出来るだけドメインモデルと一致させる。
データ交換フォーマットとして XML設計なんかは、ほぼ、そのままドメインモデル。

テストコード、テストスクリプトも、できるだけ、ドメインモデルの言葉を使う。

ドメインの言葉になっているので、その分野の専門家に、Java のコードや、テストスクリプトを読んでもらって、レビューに参加してもらえる。

Java のコードといっても、クラス名、メソッド名、変数名が、その分野の用語なので、ビジネスルールや処理ロジックがおかしい点を、的確に指摘してもらえる。

まあ、徹底的にドメイン指向でコードを書くと、String とかも表には登場しなくなる。
String の変わりに PersonName とか、EmailAddress とか、ドメインの言葉がたくさんでてくるので、Java を知らない人でも、だいたい、何が書いてあるかが、ちゃんと伝わる。

Kent Beck は、コードの価値として「コミュニケーション」を強調している。
良いコードとは、すぐれた「コミュニケーション」手段になっていること。
そのコミュニケーションの相手が、開発技術者だけでなく、業務のプロとか、顧客の代表も含めてコミュニケーションできるコードを書くことは、大きな価値がある。


ユビキタス言語

ドメイン駆動の進め方。

その分野に詳しい人の知識を言葉で整理する。
UML 、画面イメージ、エクセルの表なんかも使いながら、その知識を模型として形にする。
コードにも、そのまま模型(モデル)の言葉、つまり、その分野の専門知識をそのまま使う。

エバンスが言っているように、顧客との会話から実際のコードまで、「あらゆるところで同じ言葉を使う」ことがDDDでは一番たいせつ。
それが「ユビキタス言語」パターン、ということ。

calendar
1234567
891011121314
15161718192021
22232425262728
293031    
<< March 2009 >>
システム設計日記を検索
プロフィール
リンク
システム開発日記(実装編)
有限会社 システム設計
twitter @masuda220
selected entries
recent comment
recent trackback
categories
archives
others
mobile
qrcode
powered
無料ブログ作成サービス JUGEM