責務駆動設計はオブジェクト指向か? [そもそも論]
前のブログでは次回予告として「イベントシステムを扱う」と告げたのだが、それより先に責務駆動設計の文章が降りて来てしまったので、予定を変更してそちらを先にお届けする。
じつは先週の3/5に「ドメイン駆動設計」の勉強会に行ったのだが、そこで責務駆動設計の6つのロールの話が出て来たので、それをキッカケに色々と連想が広がってしまったのだ。この手の文章は書ける時に書いておかないと筆がさらに遅くなるから、イメージが湧き上がっている時に書くのが一番だ。というわけで「イベントシステム」の話を期待してた方はご容赦願いたい。
擬人化設計技法への誘い
というわけで今回は私の好きな「責務駆動設計」の話だ。
ただし、ここで責務駆動設計が何かという説明をするつもりはない。世間にはたくさんの責務駆動設計の解説があるので、ググってほしい。今回の話題は次の一点に尽きる。
「責務駆動設計はオブジェクト指向か?」
答え:責務駆動設計を世に広めた立役者「レベッカ・ワーフスブラックとアラン・マクキーン」がその著書「オブジェクトデザイン」でオブジェクト指向と言っているのだからオブジェクト指向である。以上、終了。
オブジェクトデザイン (Object Oriented SELECTION)
- 作者: レベッカ・ワーフスブラック
- 出版社/メーカー: 翔泳社
- 発売日: 2007/09/13
- メディア: 大型本
.......ま、それで済むなら記事になんかしないわけで、ちょっと引っ掛かっているからこそ、こうして話題にしているのだが、まずは本人たちの意見を尊重しておこう。
ただし、である。
お気付きの方もいるだろうが、このブログでは責務駆動設計のことを、世間のように「オブジェクト指向の主流」あるいは「一種」として扱ったことは一度もない。読み返してもらえば分かるだろうが、すべて「擬人化(指向)設計技法」の一種として扱っている。
とはいえ「オブジェクト指向ではない」と見なしているのかと言うと、そういうワケでもない。
オブジェクト指向という恐竜
皆さんは「獣弓類」と「竜弓類」というのをご存じだろうか?どちらも原始的な爬虫類だが、「竜弓類」は典型的な巨大恐竜に進化し、「獣弓類」は哺乳類へと進化した。「責務駆動設計」はこの「獣弓類」に似ている。
「オブジェクトデザイン」の原著は2002年発行だが、ワーフスブラックらの活動はOOPSLA'89 の論文『Object-Oriented Design: A Resposibility-Driven Approach』まで遡る。これはJavaの1995年より古い。当時もC++などのいくつかのオブジェクト指向言語は存在したが、オブジェクト指向が普及していたとは言えない状況だった。逆に言えばオブジェクト指向の方法論を確立しようと多くの流派がしのぎを削っていた時期だ。
「獣弓類」は恐竜とは違う系譜なのに、姿が似ている「竜弓類」と同じ「原始恐竜」の仲間に入れられた。それと同じように、「責務駆動設計」は「オブジェクト指向」という「恐竜」の仲間に入れられている。いやレベッカ・ワーフスブラック自らが「恐竜」だと宣言してしまっている。これはある意味仕方がないことだ。「じつは別系譜ですよ」なんて後からだから言えることで、始祖の獣弓類だって自分を周りの竜弓類と同類だと思っていただろう。
ただし、私は違いが気になるので、獣弓類は獣弓類と呼ぶし、責務駆動設計は「擬人化設計技法」の一種だと位置付けている。
→ 獣弓類は学問的には恐竜ではない
→ 擬人化設計技法も厳密にはオブジェクト指向ではない(と言われるようになるだろう)
擬人化設計技法の仲間たち
「擬人化設計技法」の見分け方はわりと単純だ。
まず、設計技法であって実装技術には成っていない。それは本来のオブジェクト指向との大きな違いである。例えば、今もネットワーク系や社会シミュレーション系でしぶとく生き残っている「エージェント指向」や私が勝手に提唱している「新エージェント指向」は実装技術を含むので、同じく擬人化を基点としていても、ここで除外される。まぁ、それらの設計技法だけは広義の擬人化設計技法と言えなくもない。(特にうちのはまだ大した実装ではないから設計技法みたいなものだ。苦笑)
それから技法の解説のかなり初期に、そのものズバリ「擬人化」という言葉が出てくる。仮に擬人化という言葉を使ってなくても、それに類することをやっていれば「擬人化設計技法」と言える。
例えば、ここで扱っている「PDC&BSP」をソフトウェア設計にも活かそうという技法(名前はまだない)だと「人のメタファ」という言い方をしている。
また、「ロール(役割)」という言葉が出て来たら「擬人化設計技法」にほぼ確定だ。先の「オブジェクトデザイン」でもロールを説明するために「擬人化」という言葉が登場している。
ロールとは責務の集合であるが、同時にそれは責務を負う存在でもある。ロールには様々なタイプがあるが、人とイメージが重なるものが多い。先の「オブジェクトデザイン」を例にとると「記録保持役、構造役、サービス提供役、制御(頭脳)役、調整役、インタフェース(窓口)役」という6つを基本ロールとして挙げており、他のロールもこれらの基本ロールのいずれかに分類できるとしている。このうち「構造役」だけは人が演じる役として連想できないが、他は何らかな形で人のイメージと重なることができる。(それでも、人と重ねようとしないコンピュータオタクもたくさんいるだろうが(苦笑)それはとりあえず置いておこう。)
6つの基本ロール
・記録保持役
・構造役
・サービス提供役
・制御(頭脳)役
・調整役
・インタフェース(窓口)役
ジル・ニコラ等の「ストリームラインオブジェクトモデリング」にも「擬人化」や「ロール」という言葉が出てくる。例えば2.1.1 オブジェクト思考には「原則7 オブジェクトを擬人化せよ」という項がある。その後も原則13までは擬人化やロールについての原則だ。原則は全部で98個あるので率的には多くないが、その後も人やロールと言うキーワードは随所に出てくる。それに原則1~6が「原則中の原則」だから、それに次ぐ重要度を与えられていると言って良いだろう。だから私は「ストリームラインオブジェクトモデリング」も擬人化設計技法の一種と見なしている。少なくとも擬人化設計技法が大きなウェイトを占めているのは確かだろう。
ストリームラインオブジェクトモデリング―パターンとビジネスルールによるUML
- 作者: ジル ニコラ
- 出版社/メーカー: ピアソンエデュケーション
- 発売日: 2002/12
- メディア: 単行本
原則1 「なぜ」の「どのように」は、「なに」である
原則2 オブジェクトモデリングの視点
原則3 新ビジネスのオブジェクトモデリング
原則4 プロセスエンジニアリングのためのオブジェクトモデリング
原則5 ユースケースの前にオブジェクトモデリング
原則6 オブジェクトモデリングによって複雑さを管理する
原則7 オブジェクトを擬人化せよ
原則8 オブジェクトに責任を与えよ
原則9 オブジェクトの責任
原則10 オブジェクトであるかのように会話せよ
原則11 人の原則
原則12 コンテキストの原則
原則13 ロールの原則
・
・
・
これらの設計技法が生まれた背景は、おそらく、業務ソフトが扱う問題の多くが実社会と密接に関わっており、その実社会の中の「人」を無視できなかったからだ。
最近話題の「エリック・エヴァンスのドメイン駆動設計*」にしてもそうだが、彼らの関心の中心は実装技術ではなくドメイン(問題領域)にある。そして、そのドメインは実社会を写し取ったもので、大抵は人が含まれる。
(*モデル駆動設計が中心の本だが、責務駆動設計が終盤の美味しいところで登場する。また、オブジェクト指向と責務駆動設計を同一視しているフシがある。)
エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)
- 作者: エリック・エヴァンス
- 出版社/メーカー: 翔泳社
- 発売日: 2011/04/09
- メディア: 大型本
つまり、これらを考えた人にとって「オブジェクト指向かどうか?」は正直どうでも良くて「一番、親和性が高かったから」ぐらいの感覚で「オブジェクト指向」を選択したのだろう。
おそらく、オブジェクト指向より社会性に優れた実装技術が出て来ていたら喜んでそちらに乗り換えただろうが、残念ながら、「エージェント指向」や「関数型言語」は乗り換え先に選ばれなかった。
ソウコウ、しているうちに今日では「責務駆動設計こそがオブジェクト指向の中心」という人たちまで出て来たので、さすがにこれから良い実装技術が出て来ても、乗り換えるのは難しいかもしれない。(そうでもないかな?)
ちなみに今日、責務駆動設計が重視される様になってきたのは、ドメインに再び注目が集まっているからでもあるが、同時に、要求が高度化されて従来のオブジェクト指向では対応できないことが増えて来たからでもある。
進化への圧力
iPhoneのSiriのように「強い人工知能」が次第に登場して来ている今日では、顧客の要望もそれに合わせて次第に難しくなって来ている。皆さんにも顧客から「手に余る」高度な処理を要求されて困った経験を持つ人がいるだろう。
こうした時、「伝票」とか「オブジェクト」とかだけで考えていると高度な処理が浮かばなくて困るのだが、人間とは不思議なもので、擬人化して考えると結構色んなアイデアが浮かんでくる。それはおそらく高度に振舞う人間のことを私たちが良く知っているからだろう。
それにしても「擬人化」というのはオブジェクト指向信者にとって何とも都合の良い言葉だ。擬人化思考中に考えているのは、「人」のことであって「オブジェクト」のことではないはずだが、「擬人化」という言葉を使うことで、全てがオブジェクトの範疇内であるかの様にすり替えることができる。
しかし、これはあくまでレトリックだ。
例えが適切か分からないが、エージェント指向とオブジェクト指向の違いは「頭脳」の扱いにある。つまり「知能」と「コントローラ」は類似性はあってもレベルが全く違う。そこまで極端でなくても、同種の違いが擬人化設計技法と本来のオブジェクト指向の間にもある。エージェント指向の問題点は一般のプログラマーが必要とする様な設計論や技術を提供できなかったことだが、今日では普通のアプリ開発者にも高度な処理が求められるようになって来ていて、ちょうどそこにハマったのが責務駆動設計などの擬人化設計技法だ。ではこの先、もっと高度な処理が普通の開発者に求められるようになるとしたらどうなるのか?
さながら恐竜の絶滅期のように、リーマンショック以降の案件激減はソフトウェア業界に少なからぬ爪痕を残した。スマートフォンやソーシャルメディアに活路を見出したところも多いだろうが、それは暖かい地域に逃げ出したことを意味する。それはそれで正しい経営判断だが、厳しい冬を凌いでいる人たちはどうするのだろう?高度な要求に応えるために、獣弓類から哺乳類に進化するのだろうか?仮に進化するとして、その哺乳類が暖かい地域にも進出したらどうなるのだろうか?
擬人化設計技法という「獣弓類」が「哺乳類」に進化するには、実装技術の存在が必要不可欠だ。恐竜(オブジェクト指向)に成れ(慣れ)なかった小さい生き物が、恐竜たちの中で生き抜くために責務駆動設計を「隠れ蓑」として利用するのも悪くないが、せめてDSL(ドメイン制限言語)で良いから「哺乳類」に登場してほしいものだ。今日、哺乳類に相当する様なDSLってどれぐらい誕生しているのだろう?いくつか、あっても良い気がするが。
もちろん、私は哺乳類が誕生することを願っている。というか、自分でも作ろうとしている。それは弊社の「新エージェント指向宣言」を見ても明らかだ。ただこれは私個人の力で何とかなる範囲を大きく超えている。あまりに先走ったことをし過ぎて、逆に私の方が絶滅しそうだ。というわけで現在「お仕事募集中」である。恐竜的案件でも構わないから、試しに使ってやろうと言う方は是非ご連絡をいただきたい。もちろん、いっしょに哺乳類を生み出そうと言う話は大歓迎である。
例え話が過ぎて話が逸れた。
責務の定義からの考察
責務駆動設計についてだが、私や世間の分類がどうであれ、やはり名前の通り、本質は「責務」にある。ロールは無視されることもあるが、責務を無視した責務駆動設計などあり得ない。
その「責務とは何か?」については、第2回で触れた。もう一度ワーフスブラックらの定義を見てみよう。
・オブジェクトが行う行動
・オブジェクトが持つ知識
・オブジェクトが他に影響を与える主要な判断
これを踏まえた上で最初の問いに答えよう。
「責務駆動設計はオブジェクト指向か?」...全ての項に「オブジェクト」と言う言葉が並んでいるから、オブジェクト指向と見なせる。が、同時に旧来の「オブジェクト指向的発想」では抜け落ちてしまう「判断」が含まれる。これは擬人化の証だ。そして注意深く書かれた一文が示すように「判断」は「協調」において効力を発揮する。つまりこの責務の定義はコラボレーションにおける「判断役」を暗示している。これは擬人化設計技法にとって大切な「進化の萌芽」だ。基本6ロールを上手く使えば、この芽を育むことができる。もちろん「PDC&BSP」もそれを助ける。
(私はつい妄想してしまうのだが、擬人化設計技法に実装技術が伴うまでに進化した時、はたして責務の定義に「オブジェクト」と言う言葉は残っているだろうか?....まあ、その答えを出すのはやめておこう。大事なのは言葉じゃなくて進化そのものだ。)
今回はここで終わるが、責務駆動設計は簡単には語り尽くせないテーマなのでこれからも取り上げるつもりだ。次に扱う時にはGRASPパターンと擬人化設計技法を対比しよう。GRASPはオブジェクト指向の文脈で責務駆動設計を行うには外せない重要な概念だが、擬人化とは根本的に相容れない部分もある。そこを深堀して行こう。
さて、次回こそイベントシステムを分解する。執筆速度が遅いくせに、書きたい記事が目白押しで、キツい日々が続くが、あと最低10回分ぐらいは続けたいので頑張って行こう。
MVCのコントローラは頭脳役か? [隠れた頭脳役]
これは非常に重要なテーマだ。
何しろGUI全盛の今日、MVCが絡まないプロジェクトの方が珍しい。
webアプリのフレームワークでも軒並み採用しているし、iOSアプリを作る時にも(Objective-Cネイティブでやるなら)避けて通れない。
そのわりに「そもそもMVCとは・・・」という文章には滅多にお目にかからない。
開発者の中にはワケが分からないけど仕方ないから使っている人とか、面倒くさいから嫌いと言う人も多いと思う。
もちろん原典と呼ぶべき資料はあるが、その手のお堅い資料を初心者で読む人は稀だし
そもそもMVCの概念も時代とともに変化しているから原典を読めば良いと言うものでもない。
だったら新たに書こうじゃないか。
それに加えて「Controller≒頭脳役」が名前にも入っているのだから「ソフトウェア工学には頭脳が足りない」シリーズにとっては格好のネタだ。ソフトウェアの頭脳役とは何かを説明するにはちょうど良い題材だろう。これを書かない手はない。
また、BSP(Brain, Skills, Physical)メタファの適用事例としても打ってつけだ。このMVCとBSPメタファの関係が理解できれば、擬人化設計技法を実務で使える様になるだろう。
さて始めようか。
MVCとは何か?
MVCモデルは大抵の人にとって、今やフレームワークのことを指す。
webアプリケーションですらフレームワーク上で動く様になって久しい。
フレームワークを使えば楽に開発できるが、その仕組みや設計思想を理解する機会はその分減っている。
しかしながら全体の動きを知らずに良い実装はできない。
だから今回はMVCフレームワークの仕組みを覗く事から始める。
知っている人も多いだろうが、まずMVCの定義を復習しよう。
MVCとはGUI(グラフィカル・ユーザ・インタフェース)に統一感を持たせるための概念である。
扱う内容は違っても、扱い方が同じなら、同じ操作感を持たせた方が分かりやすい。
例えばボタンはボタンだし、ポップアップメニューはポップアップメニューだし、スクロールバーはスクロールバーだ。
これを実現するためには、まずGUIを他の実装から切り離して再利用可能なパーツにする必要がある。
他にもMVCの元となった思想はあるが、今回はこの視点を中心に見ていこう。
名前の元となった3要素は以下の通りだ。
V=ビューは文字通り「見た目」だ。
先ほどのボタン、ポップアップメニュー、スクロールバーなどのGUI用のパーツ、ウィンドウ等のアプリの外観を構成する要素のことである。これらは次の「Model」に見た目と操作感を与える役割を持つ。
また、クリックイベント等を内部に向かって発信する。
M=モデルはアプリケーションの本質を表している。
元々、モデルには2つの意味がある。
1つはデータ構造、
もう1つはビジネス特有のロジックである。
これはクラス内に変数と関数があるのと同じで、ある種オブジェクト指向的な発想である。
ただしビジネスロジックにも共通性があって、それらも再利用可能なように作るのが最近のトレンドなので、データ構造のみを指すことも多い。
さて、ViewとModelの役割は分かりやすいので、こんな大雑把な説明でもだいたい分かってもらえるだろう。
問題はControllerだ。
C=コントローラは色んな説明のされ方をしていて、概論からは実体が掴みづらい。
例えば「移植性が低く、再利用ができない、使い捨ての部分」と言われてもピンとこないだろう。
MとVをコントロールしている事だけは確かだが、
何をどのようにコントロールしているのか、今ひとつ掴みきれない人も多いのではないか。
MやVとの関係から想像できるCの責務は
M→V、つまりアウトプットと、
V→M、インプットの制御だ。
実際、この2つはコントローラの重要な責務だが、これだけなら仲介役であって制御役ではない。
アウトプットやインプットの途中で加工をしているとも考えられるが、これも加工役もしくはサービス提供役であって制御役ではない。
ではコントローラをコントローラたらしめているのは何だろう?
推論ではこの辺にして
ここからは具体的なフレームワークの挙動を見ていく事にしよう。
色んなMVCフレームワークがあるが
web用だと分散処理等の問題で話が複雑になるので
まず例としてiOS SDKを取り上げる。
(ちなみにAndroidじゃない理由は私がiPhoneユーザだから。)
例として扱うGUIの見た目はこんな感じだ。
表(テーブル)形式の表示だが、これをiOS SDKではUIKitという標準のフレームワークで実現できる。
以下の図の「TableView(正確にはUITableViewクラス)」がそれだ。
TableViewは「TableViewController」というコントローラを使って制御する。
Viewコントローラは名前が示す通りViewをコントロールするものだ。
ほかにコントローラと呼ばれる物が無い事からMVCのCは実はViewコントローラの事であると分かる。
TableViewに反映される元データで、もっとも単純なのは配列データだ。
配列に格納された個々のオブジェクトがテーブルの一つ一つのセルに相当する。
Viewコントローラの責務
さて、全体像が分かったところでいよいよViewコントローラの内容だ。
Viewコントローラは「元データ(モデル)に対する操作」と「表示の制御」という大きく分けると2つの責務を持っている。これは先ほど述べた「インプット、アウトプット」に相当する。このうち「元データに対する操作」は別にデータ・マネージャ(データ専用のサービス提供役)を立てて、そちらに委譲するのが普通だ。
だからViewコントローラのメインの責務は「表示の制御」である。
だから名前にもViewControllerと付く。
「表示の制御」はさらに「表示プロセス制御」と「インタラクション(ユーザの操作に対する反応)制御」に分けられる。
まずは「表示プロセス制御」だ。
例えばViewであれば、いずれも
「initilaize(初期化)→viewWillLoad(ロード前)→viewDidLoad(ロード後)→viewWillAppear(表示前)→viewDidAppear(表示後)」というプロセスを経て画面要素が描かれる。
プログラマからはプロセスの中のピンポイントしか見えないが、裏ではこの様に手順の決まったプロセスが回っている。
さらにTableViewであれば表を描画したりスクロールさせたりする処理プロセスが回っている。
一方、インタラクション処理も通常はViewからの入力に反応するメソッドが決まっているので、普通の関数(メソッド)との区別が付きづらいが、裏ではイベントが発生し、そのイベントに対するオブザーバ(イベントリスナーとも言う)を呼び出す処理が行われている。
この、外にはピンポイントでしか見えない「表示プロセス制御」と「インタラクション制御」がViewコントローラの実質的な二大責務であり、コントローラをコントローラたらしめている要素だ。この2つを一般化すると「プロセス制御」と「イベント処理」ということになるが、これらは常にコントローラ(制御役)と呼ばれる物の二大責務である。
余談だが私はプロセス制御が苦手だ。処理が複数のメソッドに分散されていると実行順を間違えてバグを仕込む事がよくあるが、時々、同じメソッド内でも順番を間違えて凹む。静的モデルや並列処理の方がよっぽど楽だ。こうした得手不得手は誰にでもあると思うが、昔に比べるとプロセス制御が苦手な人が増えているのではないだろうか?
BSP視点でMVCを捉える
次にようやくBSPの登場だ。これまで何度も出てきた様に、BSPは人のメタファであり、
「Brain(頭脳)、Skills(技術)、Physical(フィジカル)」の略で
ソフトウェアの各要素をこれらに当てはめて考えるための思考用フレームワークだ。
MVCではコントローラがBrain、つまり頭脳役と思うだろうが、話はそんなに簡単じゃない。(だからこそ面白い)
まず、これまでほとんど取り上げてこなかったPhysicalについて述べよう。
MVC中のPhysical要素とは何だろうか?
名前からしてコントローラではなさそうだが、M?V?どっちだろう?
これまでの回を読んでいれば気付くと思うが、じつは両方ともPhysicalだ。
Mはファイル化して持ち運べるし、Vは見たり触ったりできる外観を提供する。
だからどちらもPhysicalだし、むしろ両方揃ってこそPhysicalであると言える。
この混同こそがPhysicalの面白さなのだが詳しくは後程述べる。
つぎはS要素に行ってみよう。
結構ありがちなのがS(スキル、サービス)をコントローラ内に書いてしまう事だ。
これが一番手軽なので、単純なアプリを手早く作るのには向いているが
画面間で重複が出たり(ViewControllerは画面別に書く)
プログラムの見通しが悪くなったりするのでS要素は独立させるべきである。
大抵のフレームワークはそのための仕組みを持っていたりするので、それを有効に使った方が良い。
かつてはModelにビジネスロジックを持たせる事も多かったから、S要素をModelに書き込む事も多かったが、今日ではサービスとして独立させることは常識に成りつつある。
例えば先ほど出てきたデータ・マネージャは(広義の)Modelでありサービス提供役(=S要素)でもあるが、これに他のビジネスロジックが混じっていたらどう思うだろうか?たぶん気持ち悪く感じることだろう。
SをMVCから分離して書いたとして、さて、残るはBだ。
Brain要素はViewコントローラと同様に「プロセス制御」と「イベント処理」を責務とするが
それ加えて「推論」や「履歴管理」を行うことがある。「テキスト入力予測」などが身近な「推論」の例で、上手く使えばソフトウェアに大きな付加価値を付けてくれる。「履歴管理」は「操作の取消や再実行(アンドゥ、リドゥ)」に使われるし、商取引などで証跡を残さなければならない時にも使う。
さて、これらをどこに書こうか?
例えば、先ほどの「テキスト入力予測」や「履歴管理」だと処理の規模が大きいので「サービス提供役」に実際の処理を委譲するだろうが、ではその委譲のコードはどこに書くのだろうか?
ありがちなのはこれまたViewコントローラに実装する事だ。
でも思い出してほしい。ViewControllerはビューのコントロールのためにある。
目的を限定する意味で、BはViewコントローラと分けるべきだ。
でもまぁViewControllerに書くのが手っ取り早いからアプリが小さいうちはそれもアリだろう。
ただし、ViewControllerにアプリの頭脳役を任せたとしてもBrain要素の中心はMVCの外にある。
iOSアプリならApplicationDelegate やNotificationCenter と言った、もっと上位の機構があるし
他のフレームワークでも隠れている上位機構がたくさんある。
これらも立派なBrainである。
例えば自分で独自イベント処理を実装する場合、イベントループやイベントキューなどを司るシステムに支えられているし、
ネット環境で分散処理をするならロードバランサーなどたくさんの高度なシステムが裏で支えている。
こうした物を直接触る機会はほとんど無いだろうが、これらを意識しないとシステムのBSPを捉える事はできない。
過大評価されがちなMVC
さて、全要素が出揃ったところでもう一度MVCとBSPの関係について考察しよう。
以下の図はアプリのBrainにNotificationCenterと独自イベントを使い、Service(Skills)にObserver(イベントリスナー)を利用した例だ。
この構造がMVCモデルを使ってアプリを実装する際の基本パターンである。
MVCがPhysical内に閉じ込められているのに驚いたかもしれない。
でもViewControllerは本来Viewとセットであり、アプリのBrainが他にある以上、「ViewControllerはViewと関連データを従えて、1つのオブジェクトとして振舞う」と考えた方が全体がシンプルになる。この場合ViewControllerはPhysical内にできた「BSPの入れ子」のBrain要素である。「BSPの入れ子」内のService要素にはDataManagerやViewController内のメソッドが相当する。ViewやDataは相変わらずPhysical要素だ。
どうだろうか?MVCが実は「2種類のデータ」を「1つのオブジェクト」としてまとめるための技術だと言われた感想は?実際にコーディングしてる時の感覚とズレるのではないだろうか?
自分もかつてMVCはアプリケーションのメインストリーム(主幹)を占めていると思っていたが、その考えが当てはまるのは、画面数が少ないソフトウェア、もしくはユーザとのインタラクションが主体のソフトウェアに限られる。もしかしたら、その手のソフトばかりを手がけているのかもしれない。
あるいは単にコーディング作業が大変なので、そう思い込んでいただけかもしれない。
でもMVCのControllerの難しさは、それがメインのBrain要素である事から来るのではなく、「クラス」の継承や仮想関数の仕組みでは裏に隠されていたBrain要素を、自分でハンドリングしなければならない事ことから来ている。クラス・インスタンスの自動処理よりViewControllerの自動処理の方が自由度が高いし、できる事も高度だが、その分プロセスを学んだり実装したりが大変なのだ。
いずれにしても複雑な心境だと思うが、Physicalをまとめ上げるBrain役も大役だから頑張って実装しよう。ただし、それがPhysical内で閉じていて、アプリケーションのメインのタスクと違う事は意識しておこう。
MVCモデルを使わないケース
web系やらGUI系のフレームワークでは今や常識と言えるMVCモデルだが、これらを使わないと言う選択もあり得る。それはグラフィックが中心だったり、Viewの再利用率が低い場合などだ。例えばゲームやビジュアルアートでは表示用データが中心でModelとViewを分ける意義が低い上に、表示部品の使い回しが少ないのでViewとViewControllerを分ける意義も低い。
事実、FlashのActionScript3.0ではDisplayObjectの派生クラスが「ViewとViewController」の両方の役割を担っている。DisplayObjectの派生クラスにも独自の変数やメソッドを追加できるのでModel役やサービス提供役を兼ねることができる。つまりやろうと思えば1つのクラスでMVCの全要素(Physicalそのもの)を表現できる。これはゲームやビジュアルアートに使われるActionScriptらしい仕様である。MVCを分ける大義名分として「異なるプラットフォーム間での移植性を高めるため」というのがあるが、そもそもFlashはほとんどのプラットフォーム上で動くからそれを気にする必要もない。
最近話題のUnityというゲームエンジンもMVCモデルではない。グラフィック・オブジェクト中心に全ての仕組みが回っているが、そのグラフィック・オブジェクトの再利用には「Prefab」という独自の機構を使う。
将来的にはこうしたグラフィック中心の流れがメインストリームになる可能性もある。単一オブジェクトの表示に複数のグラフィックを使い分けることも多いからMVCの考え方が全く無くなることはないだろうが、上級者しか知らなくなる可能性はある。
なお、BSPについても規模が小さいうちは無視できる。もちろん規模が大きくなれば、モデルを分けたりBSPを考慮したりする必要が出てくる。
分散システム上のMVC
さて次にwebフレームワーク上のMVCについて触れておこう。
webの場合は技術が複雑に絡んでおり、私自身も正確に把握していない部分が多いので、厳密な定義がやりにくいのだが、イメージだけでも掴んでおこう。
webシステムの最大の特徴はクライアントのwebブラウザとサーバサイドで処理が分かれている点にある。
ブラウザ側で面白いのは内部構造が表示用と永続用で分かれていない様に見える点だ。厳密にはViewは「ブラウザやシステム標準のUI」及び「CSS」を使って表現され、ブラウザがそれをコントロールしている。が、JavaScriptやCSSなどの各処理系からは、ブラウザ上のデータはDOMを通して同列に扱われており、MVCをプログラマーが意識する事はない。
サーバサイドにはそもそもViewが存在しないので表示用に分けようがない。ただしシステム全体で見るとブザウザ側にView、サーバ側にModelとControllerを持ったMVCモデルとなる。サーバ側のControllerはブラウザに転送するデータを制御しており、プロセス管理としては主にページ遷移、イベント処理としてはHTTPコマンドに対するレスポンスを処理する。
今度はBSP視点で見ていこう。
BSPモデルではクライアント側をPhysical、サーバサイドのインフラをBrain、サーバをServiceと大きく捉えることができる。また、Webアプリの場合はクライアントだけでなくサーバ側も入れ子になる。先に述べた様にサーバ側にはMとCがあるので、それがPhysicalとBrainとして入れ子を構成するのだ。これでMVCとBSPの対応は一通り取れた。しかしながら、実際には図上のBSPの体裁が整ってなくて、見れば見るほど疑問が涌いてくる。
BSP擬人化原則
ここで一つの原則を設けよう。
原則としてBSPを入れ子にする時には、必ず中にBSPの3つが揃っている事とする。
私はシステムを俯瞰する際にこの原則から外れている事例をまだ知らない。だから今までの話に出てこなかった要素でも混同等の何らかの形で存在しているはずである。今度の図はこの原則に基づいてBSPの各要素を割振ってある。
BSPは人の活動の基本要素であり、人のメタファだからBSPが3つ揃うと擬人化ができるようになる。擬人化は理解を助ける効果がある。脳内のミラーニューロンが共鳴するからとか、そんな理由らしいが、とにかく「Skillsだったらサービス役、Physicalだったら記録役/窓口役」という感じで擬人化しながらBSPを割振ってみよう。MVCモデルだけで捉えていた時には見えなかったことがたくさん見えて来るはずだ。
先の原則は擬人化のための原則だから「BSP擬人化原則」と命名しよう。
「BSP擬人化原則」は色んなところで、隠れているBrain要素を見つけ出す手がかりになるはずだ。また、MVCと組み合わせればMVペアを見つけ出す役にも立つだろう。何より各ブロックの役割がイメージしやすくなるはずだ。
ところで先ほどの図だが、かなり厳密になったし、これまで見てなかった要素が見えてきて興味深い。が、いささか情報過多な気がしないでもない。意識しなくて良いことは図に描かないという割切りも大事だから、「原則」は必要に応じて適用するといいだろう。
MVCからMVCSへ
ところで「BSP擬人化原則」とMVCを組合わせて使うには一つ問題がある。それはビジネスロジックの扱いが中途半端である点だ。これまでにも述べた通り、ビジネスロジック=サービス要素には汎用に使えるものもあり、SOAに代表される様にモデルから独立して扱われる様になって来ている。つまりModelが変質してきている。その現状を踏まえるとMVCにServiceを加えて「MVCS」と表記した方がシックリ来る。それにMVCSであれば「Model・View≒Physical、Controller≒Brain、Service≒Skills」とBSPとの対応も取りやすい。
これらを踏まえて「MVCSとBSPの基本パターン図」を作ると以下の様になる。
太枠が「MVCS」だ。だいぶイメージしやすくなったと思うが、どうだろう?
MVCSとBSPの使い分け
さて、これまでMVCを様々な視点から見てきた。特にBSPとの比較が多かったがいかがだっただろうか?
MVCを拡張したMVCSであればBSPとの互換性もあるが、両者にはそれぞれ一長一短があり、使い分けが必要である。
MVCSの長所は実装に即している事が多いことだろう。特にMVCアーキテクチャのフレームワークを使っているならそのまんまだ。また、MとVが分かれているのでインプットとアウトプットの処理が大きく違う場合には挙動を把握しやすい。
BSPの良さは何といっても擬人化で考えられる点だ。また、入れ子の原則がハッキリしているので複雑なシステムを分解するのにも向いている。また、表示等の詳細に惑わされず、本質的なデータのみについて考えることにも向いている。
Physicalというメタファの意義
Physicalでデータと表示を混同していることにMVCに慣れている人はかなり違和感を覚えるだろう。だが、先のActionScriptの様に1つのクラスで両方実現できる例もあるし、webブラウザの様に「コンテンツとDOM」を中心に別々の技術を組合わせてMVCを上手く隠蔽している例もある。そこにはMとVの2重持ちと言うイメージはない。
こうした場合、データこそが本質であり、それに特有のサービスやら見た目やら制御が加わるとBSP群としてのPhysicalが形成される。この一塊のPhysicalはクラス・インスタンスにそっくりだ。また前々回のユースケースでも取り上げた様に「アクター」と呼ぶこともできるし、独立した「システム」と見る事もできる。自律性が高ければ「エージェント」と呼ぶこともできるだろう。MとVを分けて考えていてはこうした広がりが見えてこない。
まさにPhysicalならではの面白さだ。
編集ツールとMVCの隠蔽
最後にちょっとだけ「そもそも」話をしよう。
そもそもMVCの「MとC」を統合しようなどと私が考え始めたのは、立続けに編集ツールばかりを作ってきたからだ。
利用者のリクエストに応える普通のアプリなら、インプットとアウトプットは大きく違っているのが普通だ。そうした状況では「MとCの統合」などという発想は浮かばないだろうが、編集ツールだとインプットとアウトプットはほとんど同じである。当然ながら、入力した内容を確認のために画面に描き戻す処理が頻発する。これをいくつもの言語、いくつものアプリで続けてやれば、さすがに嫌になる。言ってみればこれは定型処理なわけで、隠蔽するのがセオリーだろう。MVCの枠組みで考えていたらこの隠蔽は不可能だが、あいにくOS標準のAPIもMVCフレームワークとして提供されている。だったらMVCごと隠蔽すれば良い。
Physicalはインタフェース役となり、ユーザの操作情報をイベントを通じてBrain要素に上げる。Brainは操作内容に応じたSkills(Service)を使ってPhysical(データ)を編集する。Physical(データ)は自動的に表示に反映される。これはwebブラウザの挙動そっくりだ。
もちろん、こうしたことは他の種類のアプリではあまりない。だからMVCSを使い続けるという選択肢もアリだ。ただしBSPには擬人化などMVCの隠蔽以外のメリットもあるので、それは試して見てほしい。
さて、今回は随分長くなったがこれでおしまい。
次回からはイベントシステム等の既存のプログラミング言語で広く使われている技術について扱おう。
具体的には各技術で行われている「自動処理の隠蔽」について考察する。
つまり「どれだけ頭脳を隠しているか調べよう」って訳だ。
これらを理解する事は基礎固めにはなるし、使った事がないプログラミング言語を理解する際の道標になってくる。
そんなわけで次回もお楽しみに。
このシリーズを始めた動機と意義 [そもそも論]
そうする理由はゴールを明確にするためだ。
このシリーズは既存のソフトウェア工学にケンカを売る事が目的ではない。
5年後、10年後の未来のために今すべき事を明らかにすることが目的だ。
とは言えケンカを売りたい気持ちもゼロじゃない。
だから、頭と気持ちの整理をしたいと思う。
細かい話に付き合う気が無ければ、最後に「まとめ」を書いてあるので、そこだけ読んでもらえば良い。
おそらく読みづらいところもあるだろうし、この回を読まなくても話が分からなくなると言う事もないから、人が怒っているのを見るのが嫌いな人はパスしたほうが無難だ。
でも、もし、そういう事を気にしないなら、しばしお付き合い願いたい。
キッカケ
薄々感じている人もいるだろうが、このシリーズは私の個人的な「憤り」から始まっている。
何しろ、元はユースケース図等に憤慨して、一気に書いたブログがキッカケだ。
だからこのシリーズを私の個人的な不満をブチマケタだけの矮小なものだと判断している人もいるだろう。
まあ、万人に届く言葉など無いのだから、これはこれで仕方が無い事だ。
ただし、これだけははっきり言える。
私は怠け者で情報発信が正直言って苦手だ。
だから、単なる私憤であれば、せいぜいtwitterで愚痴って終りだ。
マトモなブログなど書くはずが無い。
つまり、このシリーズは少なくとも私が義憤だと思っているからこそ始まっている。
(CGソフトShadeのコミュニティに出没していた頃から私をご存知の方ならお分かりだろう。苦笑)
今回はそうした事を俯瞰的に眺めてみよう。
REAモデルにツマズいた
まずは憤りの原因から。
直接的なトリガは、ユースケース図の定義を確認して改めて不満を憶えた事だが、(これは前回書いた)
噴火するほど不満を大きくした原因は、REAモデルが想像と違っていた事だろう。
そもそも、それ以前に(責務駆動設計以外の)オブジェクト指向やデザインパターン、UMLと、それらを有り難がっているソフトウェア工学の関係者にも違和感を覚えていたが、そのストレスを限界スレスレまで高めてしまったのがREAモデルである。
REAモデルはまだテーマとして取り上げていないが、私が知る限り、ソフトウェア工学界、最大の「判断と実行の混同」が見られる。
日本では関連書籍も「ビジネスパターンによるモデル駆動設計」1冊しか無く、情報が不足してるREAモデルだが、Eコマースの国際標準規格を決める際にベースになったほど有力な概念だ。
しかも弊社の「ReTeMoモデル」や、武道の「心技体」によく似たモデルだから、きっとこれらはつなげられると思っていたのだが、実際には「心技」が混同していた。それも徹底的に。
こうした場合、欧米の徹底ぶりは実に見事だ。
REA、即ち「Resource, Event, Agent」は基礎概念なので、書籍に載っている25パターンのどれを見てもREAの定義に則っていて、当然のことながら「判断と実行の混同」が見られる。
混同が起きているのはEventだ。
イベントには「キッカケ」と言う意味と「出来事」と言う意味がある。
GUI等で使われるイベントシステムは前者の意味だが、REAでは一貫して「出来事」のことを意味している。出来事には「キッカケ」も「起った事」も含まれるから、その中には当然「判断と実行」も含まれる。
もちろん言葉の使い方としては間違ってないし、REAモデルの方が大抵のイベントシステムより古いのだから、普通ならこれぐらいの混同は看過されるべきだ。それは分かっているのだが、「判断と実行の混同」がREAモデルの抱える「分かり難さ」等の原因になっているのは事実だし、何より私はREAモデルがPDC(Rlan, Do, Check)プロセスと統合できる事を期待していた。
そう、そもそも私の期待値が大き過ぎたのだ。
PDCプロセスが「ビジネスの基本」と言われているのは多くの人がご存じだろう。前回のユースケースの回で述べた様に、これらは行為であって、PDCには仕掛けや結果が必ずセットになっている。武道の「心技体」はその仕掛けを表している。もし心技体とREAが同義なら、PDCとREAをセットにすればビジネスの動的な面と静的な面の両面がカバーできることになる。イベントが「心(頭脳)」役というのが納得できない人もいるだろうが、「決定を下す要素」だと思えば少なくともメタファとしては許容できるだろう。
そのイベントが「キッカケ」なら、上の「私の想像」のほうの図にあるように、エージェントが「人」と「技」を兼ねることになるが、この混同は現実に即している、そう思っていた。エージェント=人は何と混同しても現実社会とのシンクロを強め、問題になるどころかイメージを強固にしてくれる。でも実際には混同が起きていたのはオブジェクト指向と同じ「判断と実行」に於いてだった。これだとPDCとシンクロしない。
もっと遡ればCGアニメーションシステムに対する不満が原点にあるのだが、今回はこの話はやめておこう。
若者には最新の英知を
噴火の直接的なキッカケを作ったのは弊社で企画した上流工程セミナーだ。上流工程をテーマとして扱うならユースケースは外せない。例え不満があるとはいえ、他人に教える以上は基本に忠実であるべきだ。だからUMLでのユースケースの記法を改めて確認したのだが、結局は「こんな物を教えてどうするんだろう?」とゲンナリさせられた。
前回のユースケースに関する記事を読んだ人はお分かりだろうが、私はむしろユースケース駆動開発信者であって、問題視しているのはユースケース図だけである。まだデザイナーだった頃にダリル・クラク等による「ユースケース導入ガイド 成功する要求収集テクニック」を読んで感銘を受け、デザイナーの先輩には注意されながらも導入して以来、上流工程では使わなかった事がないから、かなり筋金入りのユースケース駆動信者の部類に入ると思う。
それからオブジェクト指向やUMLにもお世話になった。C++を学び始めた当初こそ苦労させられたが、元々はデザイナーだった私がここまでソフトウェア技術に詳しくなれたのは間違いなくオブジェクト指向やUMLのおかげである。しかし、そんな私でも擬人化設計技法について考える様になった後ではオブジェクト指向やUMLの副作用が気になる様になってしまった。副作用を極力排してオブジェクト指向やUMLの良いところだけを抜き出そうと頑張っているが、上流工程に関していえばそれはかなり難しい。
上流工程だと「顧客」や「管理職」など所謂"素人さん"を相手にする事が増えるが、オブジェクト指向のノウハウの多くは実装からのボトムアップで、そのまま伝える事が難しいし、第一、技術者自身が下流工程の考え方から脱せない。つまり上流工程的な発想に切換えられない。使用する言葉は思考に大きく影響するのでこれは看過できない。上流工程ではドメイン(問題領域)の人や会社等の組織を扱うことが増えてくるから、それらを直接扱う思考(及び言語)を身につける必要がある。
責務駆動設計などの擬人化設計技法が素晴しいのは、それが上流工程でも下流工程でも使えることだ。詳細設計を高度化しようとして擬人化設計技法に取り組めば、人間社会のシステムについて考える時でも同じ思考回路が使える。ただし、自分の思考(つまり旧来のオブジェクト指向)に合わせて擬人化設計技法の言葉を取り入れると、第二回に取り上げた様に「判断と実行の混同」という副作用が残ってしまう。
逆に上流工程向けに擬人化設計技法を憶えても、それは下流工程でも活きてくる。例えばオブジェクト指向設計には「コマンドとクエリ分離原則」とか「Tell, Don't Ask(求めるな、命じよ)」という教えがあるが、これらは「判断と実行の混同」がなければ、わざわざ原則にする必要がない。
もちろん擬人化設計技法を下流工程で使う際に副作用が無い訳ではない。ただし、それは人とコンピュータの違いに由来するのでノイマン型コンピュータを使う限り避けられない物がほとんどだろう。つまり設計技法では根本解決しようがない問題だ。ITに関わる人間は、例えビジネスパーソンであってもこの違いを認識しておかなければならない。
話を元に戻そう。
私は上流工程と下流工程で極力同じ言葉が使われる事を望んでいる。これは決して私だけの望みではない。そしてそれがある程度可能である事は「ドメイン駆動設計」や「責務駆動設計」を知ってる人ならご存じだろう。
話を図に限定すれば、確かに「ドメイン駆動設計」や「責務駆動設計」を世に広めている先生たちも図にはUMLを使っている。でも、それはUMLが標準だからであって、最も優れているからではない。事実、もっと良い記法があるならそれを使う事を推奨している。
このシリーズではPDCとBSP(Brain, Skills, Physical)をよく扱うが、それはこれらが擬人化設計技法の本質だからだ。それに加えて問題領域ではこれらの思考フレームワークが汎用的に使える。そして「PDCとBSP」と「組織に属する人間」には「判断と実行の混同」が許されない。(少なくとも建前上はそうだ。)一方、旧来のオブジェクト指向をベースにしているUMLには「判断と実行の混同」が発生するリスクが常につきまとう。であれば「PDCとBSP」の考え方をベースにした作図ルールを定めた方が理にかなっている。
BPM(とSOA)の例を見れば分かる様に、近未来では上流工程がソフトウェア開発の中心になって行くだろう。そうした時代に活躍するはずの若手に向けて旧時代の遺物を教える気にはなれない。それをやったら今度こそ日本のソフトウェア産業は世界に大きく遅れを取るだろう。
以上、まとめると
私のストレスの増大原因は「REA」と「PDC」がシンクロしなかったこと。
私は筋金入りのユースケース駆動開発信者だ。
オブジェクト指向やUMLが無ければ今日の自分はない。
それでもUMLを今更使ったり教えたりするのは問題だ。
擬人化設計技法とドメイン駆動設計がこれからの時代の礎であるべき。
オブジェクト指向には「判断と実行の混同」のリスクが常につきまとう。
(「コマンドとクエリ分離原則」がそれを象徴している。)
図だけオブジェクト指向と言った一貫性の無い事は推奨しない。
ビジネスパーソンを巻き込むべきだし、そのためには「PDCとBSP」を使いこなすべき。
つまり
擬人化設計技法やドメイン駆動設計をメインストリームに据える。
旧来のオブジェクト指向を下流工程の一部に封じ込める。
上流工程向けの作図ルールを刷新する。
「PDCとBSP」モデルを広める。
それらが実現できたら、このシリーズにも意義がある。
さて、今回はここまで。
次回はMVCモデルを扱う。
前回述べた様にMVCとBSPは大きくモデルが違うが、だからこそ補完し合う関係にある。
両者を合わせて考える事でようやくシステムの全体像が見えてくるだろう。
MVCの不完全性や複雑さに納得できない人や、MVCを違う視点で捉えたいと思っている人は必見だ。
というわけで、次回もお楽しみに。
エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)
- 作者: エリック・エヴァンス
- 出版社/メーカー: 翔泳社
- 発売日: 2011/04/09
- メディア: 大型本
オブジェクトデザイン (Object Oriented SELECTION)
- 作者: レベッカ・ワーフスブラック
- 出版社/メーカー: 翔泳社
- 発売日: 2007/09/13
- メディア: 大型本
ユースケースのケースって何? [頭脳役の不足]
今回こそ、ユースケースについてである。実を言うと私がUML関連の中で一番使うのがこのユースケースだ。そういう意味ではユースケース駆動開発信者と言えるが、実のところ、あまりユースケース図は描かない。少なくとも自分の推敲用に図を描きたいと思う事は滅多にない。とは言え、図の方が分かりやすい時もあるので、使わないというのも勿体ない話だ。なので最近になってユースケース図の改善に取り組み始めた。今回はその話をしよう。
そもそもユースケースって何?
ユースケースとは直訳すれば「使用事例」だが、事例と言うと語弊がある。「使われ方」と言えば良いのだろうか?正直、上手い日本語が見つからない。「事例」というと実際にあった事を連想するが、ユースケースは実際にはまだ起ってことを扱う。ソフトの「ある使われ方」を中心にして、ソフトウェアを作るために必要な情報を集約するのがユースケースだ。
ユースケースはふつうユースケース図とユースケース記述から成っている。
ユースケース図は簡単に言えば「誰が何をするのか」のみを示す。
ユースケース記述は「誰が何時どうやって何をするのか、問題が起きたとにはどうするのか、準備すべき事は?成果物は?関連する規則は?」と、関連するあらゆる事を記載する。
分類 |
要素名 |
説明 |
サマリー |
種類 |
ビジネス or システム等 |
ユースケース名 |
|
|
要約 |
|
|
図要素 |
アクター |
ユーザもしくは他システム |
システム |
自システムの境界 |
|
ユースケース |
機能やサービス |
|
フロー |
基本フロー |
使い方の代表例 |
代替 |
その他の使い方 |
|
例外 |
正常に処理されないケース |
|
拡張 |
プラスアルファ |
|
詳細 |
トリガ |
始まるきっかけ(必要ならガード条件も書く) |
仮定 |
装置外・システム外で成立しているべき条件 |
|
事前条件 |
始まる前にシステム内で成立しているべき条件 |
|
事後条件 |
次のステップのために成立させること |
|
関連するビジネスルール |
業界・ユーザ特有の規則・慣習 |
|
シグネチャー |
日付 |
|
記録者 |
|
|
バージョン |
|
今回はそのうちの「ユースケース図」のほうを主に取り上げる。
ユースケース「図」の欠点
まずは、初回の反省から。
初回では現行のユースケース図について以下の様に述べている。
「…ユースケース図ではやはり頭脳に相当するのはアクターだけであり、判断を行う要素がシステムの外部にしか記述できない。つまり頭脳が足りない。」
自分で言うのもナンだが難しい。というか「頭脳が足りない」というお題目に引っ張られたせいか論点が少しズレている。
先程述べた通り、ユースケース図は「誰が何をするのか」のみを示す。上記の難解な文章はシステム内に頭脳を記述していない事を問題視しているが、それ以前に「なぜ?」という“理由やキッカケ”が表現されていない事を問題視すべきだろう。つまりユースケース図では人が脳みそを使って考えた事や判断した事が図のどこにも表現できていない。
ピンと来ない人も多いだろうが、これには大きな問題が含まれている。人は間違いを犯すが、結果だけを見ていては、それが間違っているのかどうか判断できない。つまり検証ができない。だからユースケース図からは正しく動くシステムを作る事が思いの外、難しい。
ユースケース・ドリブン(駆動)に似た手法に「マニュアル・ドリブン」と言う技法があるが、これは取扱説明書(マニュアル)を最初に作ってから、それに基づいて設計を進めるやり方である。プロダクトが無いうちに取扱説明書を作成するのは苦行だし、システム化が難しい要件を取込む可能性もあって、マニュアル・ドリブンは万人向けではない。が、使いやすい良いユーザーマニュアルは「状況別」に使用方法が書かれている。こうしたマニュアルを元に開発できれば確かに問題は起きにくいだろう。
(おまけ ユースケース「図」のいやなとこ UMLのユースケース図の何が嫌って、図内の楕円に付けられた「ユースケース」という名前だ。ユースケース図でユースケースと呼ばれている楕円はどう見ても「機能」か「サービス」である。「使用者とサービス」の組合せを「使用事例/使用法」と呼ぶのは百歩譲って許せても、「機能やサービス」をなぜ「ユースケース」と呼ぶのか理解し難い。これは私の想像だが、たぶん、問題領域のユースケースでは楕円に「行為」を書くので、「行為」と「サービス」の両方の意味を含む言葉を探して「ユースケース」に落ち着いたのだろう。でも、これが自然な英語なのだろうか?とてもそうとは思えない。まぁ、私も「頭脳と方法の混同」と言う不思議な日本語で読者を混乱させているから、言葉の問題について他人のことはああこう言える立場ではないが。(苦笑))
ぶっちゃけ話
でも、ホントはそんなお堅い話ではなくて、個人的に気になっているのはユースケース図には「ケース」が書かれていないことだ。(ご想像通り、これはダジャレ・レベルの話である。)やっぱりユース「ケース」というなら「どういうケース(状況)で、誰が、どう使うのか」の3点ぐらいは図で表現してほしい。「誰に対するサービスなのか」を明らかにするだけなら「サービス図」と呼ぶべきだと思うのだが、いかがだろうか?
ちなみに図ではない「ユースケース」では「トリガ」等を記述することがデファクト・スタンダードになっており、これらが「状況」を補完している。だからユースケース記述まで合わせれば現状でも体裁は整っている。だからこそユースケースの推進者の多くはユースケース図よりユースケース記述を重視しているし、図の事はアイキャッチぐらいに考えている。
話を「図の改善」に戻そう。
イベントを入れよう
前回で「ユースケース図にも「イベント」を入れてほしい」と(括弧書きで)書いたが、先ほどの「トリガ」とこの「イベント」は"ほぼイコール"だ。でも少しだけ違う。人工知能の一種で、UMLの図にもなっているステートマシンでもイベントを扱うのでそちらを使って説明しよう。
ステートマシンでは「トリガ」と「ガード条件」がそろうと、イベントが発生し、状態が遷移する。言換えると、判断は「トリガ」から始まり「ガード条件」で絞り込まれ「イベント」で結実する。つまりトリガは「状況の一部」に過ぎない。それに対してイベントは前回述べた様に「判断」のシンボルだから、その判断の元となった状況も内包している。だから、「イベント」はユースケースとステートマシンをつなげるのに最適な要素だ。
ユースケースはステートマシンの「遷移」に相当する。だから、ユースケース図にイベントを追加するとステートマシン図と対にしてフローを追掛け易くなる。ただしフローも図に書かれていないので結局はユースケース記述が必要になる。(苦笑)
まあ、イベント入ユースケース図のメリットはこれだけには留まらないので、気を取り直して今度はそれを見ていこう。
PDCの対要素「BSP」
さて、今回もまたPDCが出てくる。PDCプロセスではそれらを遂行するために「頭脳、スキル、フィジカル」を使用すると前回書いた。今回はこちらも頭文字を取って「BSP」と呼ぶことにしよう。イベント入ユースケース図の3要素「イベント、サービス、アクター」はBSPに相当する。イベントは「判断のシンボル」なので背後の頭脳を指し示しているし、スキルが表に出る時にサービスに変わることは前回書いた。アクターがフィジカルなのは感覚的に分かるだろう。正確にはフィジカルに相当するのはアクターではないが、それについては後程述べる。
私はこのBSPに対応していると言う性質こそが「イベント入ユースケース図」の良さだと思っている。
さて、本番はここからだ。今まで以上に抽象的な話になるが、ガンバって付いてきてほしい。
イベント入ユースケース図がBSPに相当するなら、これを使ってPDCプロセスを回すことができることになる。イベントを介してステートマシン(=人工知能)と繋げられることは書いた。つまりB=頭脳を使ってPlanningができる。また、サービス(=関数群)を使って処理の実行ができる。チェックはアクターとやり取りするデータを使って行う。
このようにイベント入ユースケース図はPDCプロセスに対応している。PDCは業務プロセスなどでビジネスパーソンも馴染み深いものだから、イベント入ユースケース図はビジネスパーソンでもちょっとの訓練で思考の道具として使える様になるだろう。例えば「判断要素が足りているか」、「判断と実行内容に齟齬が無いか」「業務プロセスの最後に誰が何をチェックすれば良いのか」と言ったことを考える材料になる。それも個別に考えるのではなく、ユースケース毎に集約的に考えることができる。これこそがユースケース図にイベントを入れることのメリットだ。
BSPを入れ子化する
さて、実を言うと先ほどのイベント入ユースケース図とPDCの説明にはいくつかの穴がある。例えばユーザ(=アクター)はどうやって意志をシステムに伝えるのだろうか?またチェックすべき実行結果はどこにあるのだろうか?これらはユーザ・インタフェースの問題で、ロバストネス分析を使ってこれらを表現することもできるが、ここでは「イベント入ユースケース図」をロール(役割)別に固めて入れ子化する方法を用いて表現してみよう。
でもその前にまず「イベント入ユースケース図」を使うをやめよう。元々私が「イベント入ユースケース図」を考えた理由はBSPに対応付けるためだったのだから、ここからは「イベント入ユースケース図」の代りにBSPそのものを表現した「ユースケースBSP図(仮称。他の候補は“BSP要素図”)」を使うことにする。B要素には頭脳(≒人工知能)とイベント(=判断結果)が入る。S要素はサービスや行為や「スキル」とする。F要素はアクターではなく、アクターとやり取りするデータとする。そしてBSP3つを内包する「ロール(役割)」をアクターとする。BSPは元々人の構成要素のメタファだし、アクターも人のメタファだからこの定義は矛盾しない。コンピュータシステムもBSPで表せるからアクターとして扱える。それからBSPは入れ子にできる。例えばB要素をBSPに細分化したりすることができる。
BSPは前回述べた様にPDCに対応する。PDCが入れ子になればBSPも入れ子になる。一連のPDCサイクルに対応するBSPは1つのロールとして括ることができる。また、BSPには仕掛けと結果の両方が含まれる。言換えればBSPを使ってPDCを行うが、PDCの結果もBSPとなる。例えばBrain要素には頭脳と判断結果の両方が含まれるし、Skillsにはスキルと行為が含まれる。Physicalには入力フォームも出力データも含まれる。本来両者は別ものだが後行程から見ると「結果」だけが見える。だから両者を同一視する。これは「関数」と「関数の戻り値」を式の中で同一視するのと同じ事だ。
さあ、準備はできた。新しい道具、ユースケースBSP図(仮称)を使ってユーザ・インタフェースを「見える化」しよう。以下の図がユーザ・インタフェースの「ユースケースBSP図(仮称)」だ。(そろそろ仮称は取ろうか。)見た目が洗練されていないのは考察中の図法なのでご容赦いただきたい。
まず、ユーザは相変わらずアクターだ。ただし大きなBSPの"P要素"も兼ねている。これはユーザの意図がB要素として表に出て、かつ、システムがサービスとして振舞っているからだ。大きいBSPをロールとしてみる必要はない。システムの中はBSPに分かれていて、PにはGUI、Bにはイベント、Sには関数等が割り当てられる。システムの外から見るとPは常にインタフェースだ。システムのロールがサービスの時はPは大抵GUIになるが別にCUIとか他のインタフェースでも構わない。一方、システム内から見るとPは操作対象であり、データだ。つまりP要素は外から見るとGUIでうちから見るとデータという2面性を持っている。
GUIとデータが「MVCモデル」や「PBD層モデル」では全く別物なのはご存知の通りである。このため、MVCモデル等とBSPの相性はあまり良くない。でも忘れないでほしいのは「MとV」、「PとD」の内容は必ず同期しなければならない事だ。これがズレたシステムは使い物にならない。そういう意味ではMVCモデル等とBSPは補間し合う関係にあると言える。
それでもやっぱりユースケース
さて、ユースケース図の拡張のはずが「ユースケースBSP図」という新しい図になってしまった。いや、正直に言おう。最初からユースケースBSP図に持っていくつもりだった。「頭脳が足りない」というシリーズ名からはイササか外れるかもしれないが(笑)、元々やりたいことはPDCプロセスとBSPを使って、新しい時代にふさわしい設計パラダイムを考える事にある。イベントなどは旧時代の設計パラダイムからはみ出した技術要素であって、それらをオブジェクト指向をベースにしたUMLに付け足す事は初めから本意ではない。「頭脳とスキルの混同」もオブジェクト指向で顕著に起きている現象であって、いわばオブジェクト指向を否定するための道具だ。もちろん、PDCやBSPでも表現できない事が沢山あるから、「頭脳とスキルの混同」を問題にする事は天にツバする行為だろう。つまりユースケースBSP図もいずれ否定される運命にある。でもだからって、それが足踏みする理由にはならない。少なくとも私には目の前の道具が物足りなく思う。だから改善するし、そのことを伝えるためにキツい表現も使う。
話をユースケースBSP図に戻そう。
図は大きく様変わりしたが、それでもセットになるのは「ユースケース記述」で、こちらはあまり変わらない。トリガがイベントになり、必要なら親や子のBSP(=ユースケース)とロール(親ユースケース内での役割:Plan, Do, Check等)を記述することになるが、その他は変わらない。相変わらず、どのフローを基本に据えてどれを代替にするか悩むだろうし、関連するビジネスルールを探すのに四苦八苦するだろう。それでもB要素やロールの明示、ロールの入れ子化、PDCとの対応はユースケースの役割をより明らかにしてくれる。
責務駆動設計やPDCへの広がり
「ロール」という言葉からピンと来た人もいるだろうが、ユースケースBSP図は前回も話題に上った「責務駆動設計」に呼応している。「責務駆動設計」と言うのはレベッカ・ワースブラック等による著書「オブジェクトデザイン ロール、責務、コラボレーションによる設計技法」に記された、複雑なシステムをシンプルに分解する設計手法だ。「オブジェクト・・・・」というタイトルなのに徹底した擬人化手法が特徴で、難しいシステムを設計する人たちの間ではかなり名前の通った設計手法である。「責務駆動設計」というとCRCカードのイメージがあるが「ロール、責務、コラボレーション」に留意しながら設計すれば、それは「責務駆動設計」と呼んで良いだろう。ユースケースBSP図では「ロール、責務、コラボレーション」を表現できる。
この様にユースケースBSP図は責務駆動設計のおかげで詳細設計との対応が明確だし、PDCのおかげで要件との関係も明確になる。だから従来のユースケース図に混乱していた技術者でも少しは使いやすいだろう。ま、「責務駆動設計」を勉強しなきゃならないのは仕方がない。「責務駆動設計」は抽象的でプログラマーがいきなり習得するのは骨が折れる事は申し添えておく。でも、それはオブジェクト指向思想だって同じ事だ。
ちなみに「責務駆動設計」はUMLより古くからある設計手法だが、ロールには基本となるステレオタイプがあって、その中には「判断と指示」を行う「制御役(=頭脳役)」もある。何という先見性だろう。だから私は「責務駆動設計」が好きだ。
ロールの基本ステレオタイプには「情報保持役、構造化役、サービス提供役、調整役、制御役、インタフェース役」の6つがあって、「BSPおよびアクター」とピッタリ符合するモノも、しないモノもあるが、どれがどれに相当するのか自分で考えてみてほしい。ヒントを出すと最初の2ロールはどれにでも当てはまる。
最後にユースケースBSP図に対応したユースケース記述の項目例を挙げておく。
「ユースケースBSP図に対応したユースケース記述の項目例」
分類 |
要素名 |
説明 |
サマリー |
種類 |
ビジネス or システム等 |
ユースケース名 |
|
|
要約 |
|
|
図要素 |
ロール |
アクターもしくはシステム |
ブレイン |
イベント、判断結果 |
|
サービス |
UMLではユースケース |
|
リソース(フィジカル) |
サービスの操作対象。必要ならGUIも含む。 |
|
位置付け |
親ユースケース(存在するなら) |
|
役割 |
親ユースケース内での役割:Plan, Do, Check等 |
|
子ユースケース(必要なら) |
|
|
フロー |
基本フロー |
使い方の代表例 |
代替 |
その他の使い方 |
|
例外 |
正常に処理されないケース |
|
拡張 |
プラスアルファ |
|
詳細 |
トリガ |
始まるきっかけ(必要ならガード条件も書く) |
仮定 |
装置外・システム外で成立しているべき条件 |
|
事前条件 |
始まる前にシステム内で成立しているべき条件 |
|
事後条件 |
次のステップのために成立させること |
|
関連するビジネスルール |
業界・ユーザ特有の規則・慣習 |
|
シグネチャー |
日付 |
|
記録者 |
|
|
バージョン |
|
さて、今回はここでオシマイ。
次回は「このシリーズの意義について」ちょっと畏まった話をする。
できるだけ分かりやすく書くつもりだが、何分、かなり先で取扱う様な話も含まれているので、理解するのに苦労するかもしれない。まぁ、読まなくても先で同じ事を詳しく扱うから、次回はお休みでも構わない。
まあ、ともかく次回をお楽しみに。
オブジェクトデザイン (Object Oriented SELECTION)
- 作者: レベッカ・ワーフスブラック
- 出版社/メーカー: 翔泳社
- 発売日: 2007/09/13
- メディア: 大型本
「実践UML 第3版」と責務駆動設計 [判断と実行の混同例]
それでは始めましょう。
今回は前回にちょっとだけ触れた「ユースケース図」について取り上げる予定でしたが、予定を変更してUMLのバイブル本の一つ「実践UML 第3版」を吊るし上げたいと思います*。(おいw)語尾も今回だけ「ですます」調に変わりますが、よろしくお付き合いください。
さて、いきなりですが私は責務駆動設計の思想が大好きです。責務駆動設計自身についてもいつかこのシリーズで取り上げたいと思っていますが、なんで好きかというと「擬人化」を核にしているからです。擬人化を使った高度な設計技法の開発に20年以上前から取り組んでいるなんて、まさしく敬服するに値します。渡航費用を持っていたら行って考案者のほっぺにキスしたいぐらいです。
そのぐらいお気に入りなんですが、じつは恥ずかしながら、昨年日本語版が発売された「エリック・エヴァンスのドメイン駆動設計」に関する記事をネットで見かけるまで「責務駆動設計」のことを知りませんでした。当然、方々に影響を与えている事を知る由もなく、今頃になって関連書籍を読み漁っています。
今回取り上げる「実践UML第3版」もその中の一冊です。これでも昔はUMLに熱中していたのですが「実践UML」は高過ぎ・分厚過ぎでチェックしていませんでした。本を開くと、いきなり見返しにGRASPパターンの一覧表が出てきて期待が膨らみます。GRASPとは責務駆動設計での原理・原則です。他の記事は飛ばして「第17章 GRASP: 責任駆動のオブジェクト設計」(「責任」と訳されているが元は同じresponsibilites)を読み始めたのですが、いきなりつまずきました。なぜ?って、それは「判断と実行の混同」に出くわしたからです。
ここで「判断と実行の混同」について解説しておきましょう。人は「認識もしくは判断」によって意思決定し、「行動」によってその意思をアウトプットします。ただし他人から見ると「行動によって意思がもたらされた」ように見えます。これが典型的な「判断と実行の混同」です。結果を利用するだけならばこの混同は省力化につながるのですが、プログラムの設計をするには「判断」と「実行」を区別しないとまずい場合が多々あります。我々は「判断と実行の混同」に慣れ過ぎているので、この区別は意識的に行わなくてはなりません。それがこのブログのテーマです。ちなみにソフトウェアの実行はサービスとして行われる事が多いので「判断とサービスの混同」と表記することもあります。これらは前回「頭脳とスキルの混同」と呼んでいたものと同じです。ただ、「頭脳」も「スキル」もメタファ(比喩)なので、より直接的な表現に変えました。さて、話を元に戻しましょう。
「実践UML第3版」の「17.3 責任と責任駆動設計」では、
責任(責務)は「実行と情報把握」に分けられるとして、次の様に述べています。
オブジェクトの実行責任には以下のものが含まれます。
○オブジェクトの生成や計算の実行など、何かをそれ自体で行う
○他のオブジェクトのアクションを始動する
○他のオブジェクトのアクティビティを制御し調整する
オブジェクトの情報把握責任には以下のものが含まれます。
○カプセル化されたプライベートなデータを把握する
○関連するオブジェクトを把握する
○導出または計算可能なものを把握する
さて、どこで「判断と実行の混同」が起きているか分かりますか?
「実行と情報把握」に「判断」が含まれて無いのは一目で分かりますね。では、どこに紛れ込んでいるのでしょう?
先の短い箇条書きからは推測が難しいのですが、おそらく「他のオブジェクトのアクションを始動する」という項です。あるいはその下の「他のオブジェクトのアクティビティを制御し調整する」にも混ざっているかもしれません。どちらも他のオブジェクトに「命令」もしくは「メッセージ」を送って相手を動かしているのですが、「命令」と「メッセージ」では全く性質が違います。命令は自分が判断した事を暗示します。メッセージ送信は相手が判断する事が前提です。その区別がつかないと言う事が混同の証拠です。
ちなみに本家「オブジェクトデザイン ロール、責務、コラボレーションによる設計技法」では「責務とは何か」という項で微妙に異なるまとめ方をしています。
・オブジェクトが行う行動
・オブジェクトが持つ知識
・オブジェクトが他に影響を与える主要な判断
さすがは本家本元!擬人化のツボを押さえて、「頭脳」と「サービス」をきちんと区別しています。
ちなみに擬人化設計技法の基本メタファ「心技体=頭脳、技術、フィジカル」と、どう対応するかというと
「オブジェクトが行う行動」が「技術(というか、Plan-Do-CheckのDo)」
「オブジェクトが持つ知識」が「フィジカル」
「オブジェクトが他に影響を与える主要な判断」が「頭脳」です。
まぁ「行動⇔技術」「知識⇔フィジカル」は結構強引ですけどね。知識(≒データ)はプログラム中では普遍的な存在ですが、あえて一つに当てはめると消去法で「フィジカル」になります。知識と聞いて「頭脳かな?」と思った人も多いでしょうが、頭脳役は「判断するのがお仕事」ですからすでに埋まっています。「フィジカル」は典型的なメタファなので具体的にイメージしづらいのですが、大雑把に「仮想世界のフィジカル(身体+道具)=データ≒知識」と思ってもらえばいいです。当然、重要な情報はフィジカルに集積されます。
いずれにしてもオブジェクト指向の枠内で活動してきたはずのに「頭脳」と「サービス」をきちんと区別しているのですから、やはり流石と言うより他にありません。思わぬところで「責務駆動設計」本家の素晴しさを再認識することになったのですが、この「ソフトウェア工学には頭脳が足りない」シリーズではこうした「判断(頭脳)と実行(スキル)の混同」を見つけたら随時取り上げていきたいと思います。
最後に一つ、演習問題です。
「オブジェクトが行う判断」ではなく「オブジェクトが他に影響を与える主要な判断」を責務としている理由は何でしょうか?
答えは責務駆動設計について取り上げる時に載せます。それまで待てない人は「オブジェクトデザイン ロール、責務、コラボレーションによる設計技法」を読んでみてください。
さて、次回は予定通り「ユースケース」を取り上げ、語尾も「である」調に戻します。
その後は「MVC」とか「REAモデル」とか「過去のプログラミング・パラダイム」とかを取り上げる予定です。
ディープなネタが続きますので、お楽しみに。
ではまた。
*注
この記事は「実践UML 第3版」の価値を貶めるものではありません。「判断とサービスの混同」はオブジェクト指向設計全般でよく見かけますし、「実践UML 第3版」にはGRASPのコントローラ・パターンも載ってますから、勘の良い設計者なら正しい設計に気付くでしょう。また、オブジェクト指向設計にも素晴しい点はたくさんあります。責務駆動設計を取り入れたものなら尚更です。「実践UML 第3版」のGRASPについての記述は詳細設計において大いに役立つ事でしょう。
実践UML 第3版 オブジェクト指向分析設計と反復型開発入門
- 作者: クレーグ・ラーマン
- 出版社/メーカー: ピアソンエデュケーション
- 発売日: 2007/11/12
- メディア: 単行本(ソフトカバー)
オブジェクトデザイン (Object Oriented SELECTION)
- 作者: レベッカ・ワーフスブラック
- 出版社/メーカー: 翔泳社
- 発売日: 2007/09/13
- メディア: 大型本