2015年6月21日日曜日

[大規模システムの設計]管理単位の決定とメンテナンス

 大規模システムの序盤で考慮しなければならない点について、さらに記述していく。設計者は業務も知り、なおかつソフトウェアの管理についても分かっていなくてはならない。今日のシステム開発においては、経理でも生産管理でも物流でも、ほぼ例外なく業務ロジックに従って永続化データを作成・変更するのが原則である。業務を行った結果のデータを永続化データとしてデータベースに登録し、ステータスの変更を管理したり、大量のデータを元に集計を行ったりする。これは従来電子計算機システムを使わずに行っていた業務を電子計算機によるシステムに置き換え、更にデータ集計など電子計算機を使ったシステムならでは実現できる機能を追加して、よりよい業務の運営を図るものである。あくまでも業務を中心に置き、業務の視点から機能を検討しなければならない。
 使う側にとって分かりやすいように、システムを業務として可視化することが設計者にまず求められる。それゆえ前述したような機能相関図を見やすく、分かりやすいものとして提示しなければならないのである。上位設計での成果物はあくまでも業務に特化したものであり、各機能単位がどのような業務を実現するものなのかは業務ロジックとして記述しなければならない。そのための1つの手法として、オブジェクト指向設計のユースケース図及びユースケース記述がある。
 ユースケースはシステムが受け持つ機能がどこまでかはっきり見えるよう境界線を引くためのものである。こと大規模システムともなれば、ユーザがシステムを操作することはもとより、他のシステムとの連携も考慮しなければならない。ユーザや他システムをアクターとして表現し、システムの各機能をユースケースにまとめていく。これによって、システムが受け持たなければならない責任範囲がどのようなものかを明確化する。たとえば経理データをユーザが手入力しなければならないのか、それとも別のシステムが作ったCSVデータを一定時間ごとに自動で取り込み、エラーが起きた場合だけユーザに入力を促すのか、一口にシステムといっても責任範囲や役割は様々である。システム境界線の明確化は、非常に重要なのである。
 ユースケースを用いない場合でも、システムを大まかな機能単位に分けるのが最上位の設計である。このとき、設計者が注意しなければならないのは、業務として機能分割を考えるということだけではない。メンテナンスと将来拡張についての考慮も行う必要がある。業務ロジックはユーザ入力や他システムからの入力を待つものであってはならない。システムとは「変わっていく」ものである。ユーザの手入力を想定していた機能が「そんな面倒なことやってられない」となって、自動入力に切り替わることは日常茶飯事なのだ。業務ロジックの中で入力待ちを行ってはいけない。業務ロジックとは、ユーザ入力や他システムからの入力があった後に走るロジックのことである。「ユーザは経理データの必要項目を画面で入力する」 → 「システムは仕訳を行う」となり、業務ロジックとして「仕訳を行う」「仕訳」といったものが出てこなければおかしい。全ての業務の流れをそのまま業務ロジックにしてしまうと、硬直化した変更しづらいシステムになってしまう。仮に業務の流れ全てを1つのサービスにするとしても、その中でサブ機能呼び出しを行うように設計しなければ、ちょっとした変更にも耐えられないシステムになってしまう。

 (1) ユーザは、経理データを入力する。
 (2) システムは、仕訳を行う。
 (3) システムは、仕訳結果を表示する。
 (4) ユーザは、仕訳結果を確認し、問題なければ仕訳の確定を行う。
 (5) システムは、仕訳結果を保存する。

 たとえばユースケース記述がこのようになっていた場合、(2)(3)(5)は全て異なる業務ロジックとすべきである。(2)と(3)を分けないと仕訳をバッチ機能から使えなくなるし、(2)と(5)を分離しないと業務ロジックとしての「仕訳」と永続化層への保存(データベースへの登録)が同じ業務になってしまう。間違いがあった場合に問題となるため、分ける必要があるだろう。
 システムを使う側が電子計算機の技術者でなければ、(2)(3)(5)の違いは分からない。だからこそ、そのような内部構造を知らない人にも分かりやすいよう、業務ロジックを分解しておく必要がある。上記のような記載を行って初めて、(4)の段階で操作を中断したら仕訳結果がデータベースに残らないことが分かるのである。
 またこのように業務ロジックを策定していくに当たっては、常に「管理単位」を意識すべきである。業務ロジックは、システムの内部を知らない人にも分かりやすく分割するものであり、かつシステムとして今後メンテナンスしていく単位でもあるからである。前述した通り、数千数万にも及ぶサブルーチン(クラス、メソッド、マクロ等)が存在する大規模システムが管理可能性を失わないためには、全ての機能単位でテストを自動化しておく必要がある。
 上記(1)~(5)のユースケース記述を見て、自動テストを組む単位(管理単位)を考えておかなければならない、ということである。この場合、ユーザ入力の(1)と(4)を自動化しないと、テストを自動化することは不可能である。ユーザ入力は、呼び出す業務ロジックに対する入力に置き換えることができるので、このような場合は次のような自動テストケースを想定する。

  A. ユーザが正しい経理データを入力した想定で、(2)の仕訳を実行する。
  B. ユーザが不正な経理データを入力した想定で、(2)の仕訳を実行する。
  C. ユーザが仕訳を確定した想定で、(5)の保存を実行する。
  D. ユーザが仕訳を確定しない想定で、(5)でも保存を実行しない。

 (2)と(5)の業務ロジックの入力データをあらかじめ用意しておくことで、ユーザ入力がなくても自動でテストを実施することができる。上記D.により仕訳結果の保存だけでなく、ユーザによるキャンセルも機能として必要であることが分かる。このような場合はユースケースなら例外処理の項に記述する。
 以上、大規模システムの設計について具体例を交えて概説してきた。ポイントをまとめると、次の通り。

   (A) システム化対象の業務全体を7~10程度の機能単位に分割する。
   (B) 必要に応じて階層的に更に機能単位を分割する。
   (C) 各機能単位では業務の観点で、業務ロジック及び永続化データを策定する。
   (D) 全ての機能単位において、テスト自動化等のメンテナンス性を考慮する。

 どのように規模が大きく複雑なシステムであっても、最終的には管理可能な、そして理解可能なコードの集合体として管理・運営されるものであることを忘れないようにしたい。それは上記(A)~(D)のような、当たり前の手続きを丁寧に行っていくことで、必ず実現することができる。設計者が最も注意しなければならないのは、管理可能性を失っていないか常に確認することである。

0 件のコメント:

コメントを投稿