Enterprise Watch
連載バックナンバー
目次・内容

はじめに・この本が目指すもの
[2003/11/28]


「課題・仕様・設計」「課題と仕様」
[2003/12/1]


「仕様と設計」「課題・仕様・設計の関係」
[2003/12/2]


「例題:病院予約会計システム」「課題探求」
[2003/12/3]


「システム仕様(System Specification)」
[2003/12/4]


「設計実装」
[2003/12/5]


 「こんなシステムが欲しかったんじゃないよ!」- システム開発にあたって、いきなりユースケースを書こうとして悩む前に、まずは必要となる3つの視点を整理してみよう。弊社より12月2日に発売される書籍『「課題・仕様・設計」-不幸なシステム開発を救うシンプルな法則-』より一部を抜粋して、全6回にわたりお届けします。 (編集部)

「課題・仕様・設計」
-不幸なシステム開発を救うシンプルな法則-
著者 酒匂 寛 (さこう ひろし)
 1958年生まれ。東京大学農学部獣医学科卒。同大学院修士課程中退。大手SIベンダーにて、開発支援ツールの開発、事務アプリケーション開発、ワークステーションのシステムプログラミングなどを行い、オブジェクト指向言語ならびに開発方法論に出会う。
 1996年に独立し、以来コンサルタントとして、リアルタイムシステム、大規模分散オブジェクト指向システム、クライアントサーバーシステムの改善、要求定義、分析、設計、開発、管理、環境構築等に携わる。最近のテーマは形式手法を取り込んだ高信頼性・高生産性開発手法の研究。
 現在、有限会社デザイナーズ・デン代表取締役。

設計実装

システム仕様と設計実装

 システム仕様が定義されると、システムがどのようなものかがはっきりします。すなわち誰がどこでいつこの「システム」を使って、もともとの課題を解決するかがわかったことになります。

 でももちろんこのままでは、文字通り画に描いた餅に過ぎません。定義した「システム」をすべて手作業で稼動させることもできますが、この本のテーマは計算機(を含む機械一般)によるシステム化です。

 システム仕様はこれから構築しようとするシステムが「何」をするものかを定義したものです。この「何」というのは曖昧な表現ですが、あくまでもシステムの外部的な振舞いだけを記述したもので、その内部の具体的な構造に関しては述べないというのが基本です。

 本書では、具体的な設計実装技法については解説しません。すでに世の中にはそのための本が数多く出回っているからです。代わりにここでは、ここまで述べてきたシステム仕様と設計実装との関係を述べることにします。

 そもそもなぜ設計という作業が必要なのでしょうか。外部的な仕様をそのまま素直に実現するのでは何か困るのでしょうか。

 たとえばある銀行口座の残高を求める業務論理があったとしましょう。以下に示すのはOCLを用いた仕様です。

 
context 業務論理_口座残高(a : 口座): 金額
 postcondition:
result =(a.入金記録()→collect(金額)→sum())
    -(a.出金記録()→collect(金額)→sum())


 この仕様は、「口座残高は口座の入金記録の金額の総和から、出金記録の金額の総和を引いたものに等しい」ということを述べています。  

例:Rubyでの実装

 さて、もちろんこの仕様を実装するに際して、仕様に書かれている定義を素直に実現することも可能です。すなわち口座からたどれる入金記録群、出金記録群からそれぞれ金額を抽出して合計の差を求めるという実装です。たとえば以下にプログラミング言語Rubyでの実装を示してみます。

 口座の残高を求める業務論理クラスをAccountBalance とし、実際の残高計算を行うメソッドをapplyとしています。

class AccountBalance < BusinessLogic
def apply(account)
 sum_amount(account.deposit)
 - sum_amount(account.withdraw)
 end
 def sum_amount(c)
  c.collect {|r| r.amount }.inject(0){
|sum, item| sum + item }
 end
end


 このような実装は、論理的には問題ありませんし、学校での練習問題としては申しぶんありませんが、実際には受けいれにくいものです。

 なぜなら残高が繰り返し参照される場合には、この実装ではあまりにも効率が悪いからです。特に入出金記録がデータベースの中に格納されていて、それらをいちいちデータベースから呼びださなければならないとしたら、その性能劣化は目を覆いたくなるようなものになるでしょう。

 たとえばこうした場合によく使われるのは「導出属性」です。すなわち設計時には、各口座オブジェクトに「残高」という属性を用意しておき、入金記録、出金記録が増える際に同時に口座オブジェクトの残高属性を更新しておくことにします。こうしておけば、残高を問い合わせられたときには残高を素直に返すだけなので実行効率的には問題は少ないといえるでしょう。

 しかし、こうした設計実装は情報を重複して持つことになりますから、入出金記録の増減と残高の属性値がきちんと同期し続けるようにする配慮が別に必要となってきます。Javaなどの場合、同じオブジェクトに内包されるリソースならsynchronize を使って簡易な排他制御を行うことができますが、この例のように口座と複数の記録といったように多くのオブジェクトが関わるようになった場合、一段と制御が難しくなります。

 話は少し詳細に入り込んでしまいましたが、このようにシステム仕様で決められた「外部的にはどのように見えるべきか」という定義を、「内部的にいかに効率よく実現するか」を決めて行くのが設計実装の目的です。またシステム仕様で決めた「仕様」は、設計実装の検証(verification)を行う際に使われるものになります。

 さて、システム仕様を決める際に、本書では4WD の中で、どのような「システム界面」を用いるかを指定して、ユースケースアプリケーションの定義を行いました。システム界面としては、Web クライアント、リッチクライアント、PDA、特殊デバイス、プリンター、専用表示装置、プログラムインターフェイス、その他まだ見たこともないようなものも考えられるのですが、設計実装段階では具体的にどのようなやりかたで実現するかを決めていかなければなりません。

 ソフトウェアだけで決められることもありますが、まずはどのようなシステムとして構成するかを先行しないと全体像は決まりません。

(書籍 174~177ページより抜粋)


URL
 「課題・仕様・設計」-不幸なシステム開発を救うシンプルな法則-
  http://internet.impress.co.jp/books/1866/

 こちらより書籍の購入が可能です


(酒匂 寛)
2003/12/5 0:00

Enterprise Watch ホームページ
Copyright (c) 2009 Impress Watch Corporation, an Impress Group company. All rights reserved.