トップ «前の日記(2014-03-10) 最新 次の日記(2014-03-16)» 編集

日々の破片

Subscribe with livedoor Reader
著作一覧

2014-03-11

_ 詳細設計書は死んだ。とっくの昔に死んでいる。でも生き返る必要はある

流儀や呼び名はいろいろあるだろうが、ここでは3種類あることにする。

・要件定義書

要件を定義したもので、ユースケースについて記述したものだ。

・機能設計書

要件を機能として記述したものだ

・詳細設計書

機能を実装に落とし込むものだ

で、詳細設計書って何それおいしいの? ということだが、もちろん不味い。むしろ毒だと言うべきで、そんなものを記述するよりさっさとプログラムを書けば良いし、その時間を使ってテストプログラムを書けばさらに良い。

特に、1990年以降、オブジェクト(あるいはクラス)ライブラリが拡充され、APIがほとんどなんでもやってくれて、コンポーネントがそこら中に転がり始めてからは、単にそれらをグルーでつないでいくのがほとんどなのだから、そんなものを書いてもまったく意味がない。

しかし、実はそう単純でもない。

問題は詳細なビジネスルールにある。本来ビジネスルールは要件なのだが、ユースケースで考えると、詳細なビジネスルールはユースケースレベルとして記述するのが難しい。

例として、ある商店では、以下のように買い物客からの買い上げ額を計算するとする。

・商品は総額表示されていたとしても、消費税を抜いた額とする。

このとき、式として総額表示*100/(100+消費税%)を利用する

・ただし、同一商品を複数購入した場合は、(総額表示×個数)*100/(100+消費税%)を利用する

・もし割引販売した場合は、総額に対して割引、その結果の額から……

・もし買物券を出されたら、合計金額(税込)に対して一度消費税を抜いた額を求めて……

・3個で幾らという売り方をした場合は、3で割り切れない場合に、どう消費税を割り当てるか。同様に割引した額をどう割り当てるか。

こういったことは要件としては実は明らかにならず、いざ機能を定義する時にわかることがあり、しかも、機能を定義した後に、実際にコード化する時に相互に矛盾を発見することがある。

粒度の問題なのだ。そして、機能の定義にすらあてはまらないほど細粒度となることがある。

いや、それはプログラムするからいいじゃん。

というのは、一面の真実でしかない。

上のような計算を行うメインフレーム上のCOBOLのプログラムが1980年代に造られて(消費税は無いけれど、代わりに物品税のようなものはあったりする)、案の定、あまりに細かいビジネスルールは要件にも機能にも出ていないとする。というか、出ていない。

それを21世紀になって、Javaで書き直すとする。

30年経過したのだから、ゼロベースで考えるか? というと、そうはいかない。会計上のビジネスルールには基準としての継続性があるからだ。

そこで、COBOLを……読めない。

COBOLならばまだ良い。PL/Iで書かれていたら? 当時の流行の4GLで書かれていたら?

会計は長く、プログラミング言語の流行(生存期間)は遥かに短い。会計の長さとためを張れる寿命を持つのは自然言語だ。

今、Javaで記述したシステムが20年後に動いていることをおれは想像できない。

しかし、細粒度のビジネスルールが20年後でも同じことは想像がつく。

そして20年後(希望としてはもっと早いほうがSIビジネスには良いわけだが)システムは更新されるだろう。

そのとき、Javaを解読できる開発者が生き残っているだろうか? それが問題だ。Javaならだれでも読める? 20年後のプログラミングパラダイムに慣れきった開発者に解読できるのか?

(粒度の問題ともうひとつある。システム更改というときに、既存のシステムの要件と機能については、基本的におざなりとなることが多いことだ。これは予算と時間の問題だろう。システムを更改する場合、現在を100とすると、40を捨てて、60を残し、80が追加となるということが行われる(100→100なら余程のことがなければ更改は行う意味がない)。40の選別と80の設計に比重がかかり、60は今ある資料が出てきて終わってしまいかねない)

詳細設計書は不要だが、機能の定義よりは1段低レベルな仕様書はやはりあったほうが良い。

まとめると、要件定義はユースケースベースとなるため、アルゴリズムのレベルでの記述を入れる余地がない。

機能定義はアーキテクチャとモジュールの定義が主眼となり、詳細レベルの記述まで落とし込むことは難しい(難しいのは、記述方法が確立していないからとも言えるし、機能定義に、計算順序のような詳細レベルの記述が混ざるとスコープが失われることが問題となる)。

プログラミング言語の寿命は短い。

そのくらいスコープを取って考えないと意味ないよ。

_ 続き

では、どうすれば良いかだが、そんなもの自分の飯の種なんだから自分で考えれば良いわけだ。別におれの知ったことではない。

ただ、今はわかっているが、10年前にはわかっていなかったことがあって、それがちょっともったいなく感じている。

詳細なビジネスルールというのは、2種類に分けられる(もっと多いかも知れないが、少なくとも2種類はわかっている)。

1つは、上でもあげたが、計算式だ。どういう順序で計算するか(お金は最低が1円になるのにもかかわらず、割合を使うことがあるので、どうしても小数点以下となり、それを四捨五入するのか、切り捨てるのか、切り上げるのか、1個単位でそれをやるのか、累計してからそれをやるのか、といったことがルールとなる。結局、それはその企業に固有なのだ。もっとも全く新規ならパッケージに合わせれば済むのだが、次の更改時に別業者がRFPに勝ったりすると、現在のパッケージの式に合わせる必要が出てくるので、長期で見れば、結局はルールが明かになっている必要がある)。

もう1つは、データの組み合わせ方法だ。

そこでわかることがある。後者は実際問題としてそれほど問題とならない。SQL Serverでやっていたのを、Oracleにリプレースしたりその逆だったり、Postgresに変えたりといった、RDBの交換でも、よほど小汚いストアドプロシージャが山ほど作られたりしていなければ、ビューを既存の形式に合わせてやると大抵同じルールを適用できる。正確には、同じSQLを適用できる。パフォーマンスチューニングは別の話だ。

同じことを前者に適用することを考える。

COBOLはともかくとして、VBもともかくとして、現代のモダンな言語(最悪でもJavaを想定してみよう)以降であれば、仮に20年後、30年後であったとしても、DSLが利用できる。

要は、多倍長数の算術演算が記述でき、関数を組めて、開発に利用するプログラミング言語とのインターフェイスにオーバーヘッドがかからないDSLがあれば良い。つまり、すべてのビジネスルールをそのDSLで記述し、それを仕様とする(どうせDSLなのだから、きれいな文書の清書機構も組み込めば良いね)。

DSLといっても、実現方法はいろいろあるのだから、仮にJavaで実装するのであれば、地の部分(SOAで組むか、Webアプリケーションで組むか、Swingで組むかといったことは、ビジネスルールのレイヤーではないから、要件に合わせれば良い)はJavaで普通にプログラミングすれば良く、ビジネスルールについては、専用の簡単な(というのは、機能は限定されているのだから)インタプリタか、速度が必要ならばコンパイラを作れば良い。仮にLISPで組むのなら、マクロにするのだろうな。

そのようにして、ビジネスルールをシステム(機能仕様によって規定される部分をここではシステムと呼んでいる)そのものの実装から切り離せば、システムの主となるプログラミング言語がJavaから別の言語に移行したとしても、システムのアーキテクチャがWebではない20年後の何かになろうが、ビジネスルールを記述したDSLの実行エンジンをその言語で実装すれば良いのことになる。

同様に、別のSIerに乗り換えたとしても、納品物であるDSLの記述仕様と、記述されたビジネスルール集をシステムの変更されない箇所の仕様として提供して、適用させれば良い。当然、新規開発されるもののうち、ビジネスルールに属するものは、すべて同じDSLを適用させる。もっとも、力づくでDSLで記述したビジネスルールを開発に利用するプログラミング言語ネイティブに変換されてしまうと、何の意味もないので、そこがプロポーザルで守らせる肝となる。

ビジネスルールとシステムをDSLを介して疎結合させることが、最も優れた解だろう。

20世紀の最後は、コンポーネントを作るプログラミング職人と、そのコンポーネントを使ってグルーでビジネスロジックを組むということが語られていた。しかし実際にはそんなにうまくいかなかった。というのは、グルーといってもプログラムはプログラミング言語であり、どれだけコンポーネントがあっても、システムを組むためのロジックが山ほど必要となるからだ。MVCに単純化すれば、Vの相当数が既存のコンポーネントで提供されていても、それを組み合わせるプログラミングが必要で、Mを固めるプログラミングが必要で、コントローラにもプログラミングが必要だからだ。

ジェネレーティブプログラミング (IT Architects’Archive CLASSIC MODER)(クシシュトフ・チャルネッキ/ウールリシュ・W・アイセンアッカ/津田 義史/今関 剛/朝比奈 勲)

ビジネスルールは変わらないのだから、そこをシステムの実装非依存なDSLとして分離することが、詳細仕様書を切り捨てるための正当な道だとおれは考える。

本日のツッコミ(全2件) [ツッコミを入れる]
_ Tambourine (2014-03-12 19:02)

「そのDSLをSQLとしてしまえ。どうせ今後もRDBはあるのだから実行エンジンはあるのだ。移行時もきっとどうにかなる」という思想のシステムを見たことがあります。

_ arton (2014-03-12 19:11)

すげえ。良く割り切ったものですね。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|

ジェズイットを見習え