連載
» 2006年08月10日 00時00分 公開

Spring Frameworkで理解するDI(4):なぜDIコンテナを使うのか (2/3)

[山本大, 阪田浩一,クロノス]

DIコンテナによる開発効率向上の事例

 さてここからは、開発現場で実際にSpring Frameworkを利用しているエンジニアへと、執筆の担当をバトンタッチして、Spring Frameworkのメリット、デメリットについての実体験を語ってもらいましょう。実際のプロジェクトでは開発効率の向上とともに、アプリケーションの柔軟性に対するメリットが大きく感じられるようです。

 システムの開発プロジェクトで、フレームワークを使う目的の1つは「開発効率の向上」です。多機能かつ、良い設計のフレームワークであっても、開発のスピードを落としてしまうものであれば、導入の効果としては疑問が残ってしまいます。以下では、筆者がSpringフレームワークを採用したプロジェクトに参画した経験を基に、Springを利用するとどのように開発効率を上げられるのかを紹介します。具体的には、以下の3点について事例とともに紹介します。

  • 仕様変更へのAOPの適用
  • DIによる単体テストの促進
  • Springが与えるアーキテクチャの柔軟性

 また、DIの課題として「設定ファイルの肥大化問題」について考えます。

■仕様変更へのAOPの適用

 ここでは開発の現場で発生した仕様変更に対してAOPを適用することで対処した事例を紹介します。AOPの適用対象として有名なものはロギングやトランザクション管理ですが、アーキテクチャに関係するような横断的な仕様変更やプロジェクト特有のコーディングルールに対してAOPによる解決策を取ることで、効率的、効果的に対処することができる場合があります。

 さて、筆者が参画したあるプロジェクトでシステムテストを開始しようとするころ、以下のような仕様を追加することになりました。

  1. バッチが動作している間はデータベースの在庫テーブルにアクセスしない
  2. 上記の仕様追加のため、在庫テーブルにアクセスする在庫照会などのビジネスロジックでは、処理を行う前にデータベースのバッチ状況テーブルを確認する。

 対象となるプログラムは多数あるうえ、全体のスケジュールに影響を与えないように素早く対応する必要がありました。また、後の管理を楽にしたいという要望もありました。

 一般的にはこうした仕様追加を行う場合、問題を解決するためのメソッドを作成して、修正の対象となるすべてのメソッドは処理を行う前に、作成した共通メソッドを呼び出す、という解決方法が考えられます(図1)。例えば今回の状況であれば、AOPを利用しないやり方として、ZaikoUtilクラスにバッチ状況テーブルを確認するconfirmBatchRunning()メソッドを作成し、在庫テーブルにアクセスするすべての処理でこのメソッドを呼び出すようにすることで対処が可能です。しかし、この方法ではソースコードの修正個所が広範囲に広がってしまい、管理や把握が困難になります。

図1 共通する部分を処理するメソッドを作成 図1 共通する部分を処理するメソッドを作成

 さて、AOPを利用した別の対策案として、「在庫テーブルにアクセスするビジネスロジックを実行する前に、チェック処理を挿入すればよいのではないか」と考えました。AOPを利用して在庫テーブルにアクセスするメソッドが呼び出される直前に、バッチ状況テーブルを確認する処理を挿入するという方法です(図2)。そうすれば、在庫テーブルにアクセスするクラスで、confirmBatchRunning()メソッドを直接呼び出す必要がなく、ソースコードを修正する必要もありません。対象となるプログラムに処理を挿入するためにSpringの設定ファイルを変更することのみで対処可能となります。

図2 AOPを利用して処理を挿入する 図2 AOPを利用して処理を挿入する

 筆者のプロジェクトではこの2つの方法「共通部分を処理するメソッドを作成するという方法」と「AOPを利用する方法」を比較し、検討した結果、AOPを利用した対応を採用することにしました。採用の理由は以下の3点です。

  • 作業時間が若干短いこと
  • 対象となるビジネスロジックが追加されても設定ファイルの変更だけで対応できること
  • 特殊なコーディングルールや横断的仕様変更に対処する処理を少数のアーキテクトが一括して把握・管理できること

 では、これら2つの方法の作業内容と効率を比較してみましょう(表2)。

表2 2つの方法の作業比較
共通処理を呼び出す場合 AOPを利用する場合
既存のソースコード修正 あり なし
作業の対象 在庫テーブルにアクセスする全10クラス 新規の1クラスと設定ファイル
作業量概算 バッチ確認処理作成・単体テスト:2時間
既存ソースコード修正・
単体テスト:2時間30分(15分×10クラス)
結合テスト:2時間
バッチ確認処理作成・単体テスト:2時間
設定ファイル記述:20分(2分×10クラス)
結合テスト:2時間
作業時間概算 6時間30分 4時間20分

 両者を比較したところ、修正対応の時間には大きな差は生まれないように感じられます。

 それでも、“共通処理を呼び出す”場合は対象となるすべてのプログラムを修正する必要があるため、作業時間が若干長くなります。“AOPを利用する”場合は、既存のソースコードを変更する作業がないため、作業時間が若干短くて済みます。しかし、作業時間を比較するだけでは、結局のところテストの時間が同じだけかかるため、大きく差異が広がることはありません。筆者のプロジェクトでも、この時点では決定的な判断はできませんでした。

 筆者のプロジェクトで“AOPを利用する”方法を採用した決め手は、将来バッチ状況テーブルを確認する処理の範囲を広げた際に、設定ファイルの追記だけで対応できることでした。

 筆者のプロジェクトでは、実際この対応後にさらなる仕様変更が追加されましたが、設定ファイルの追記のみで対応できました。ソースコードを修正するよりも、設定ファイルの修正をする方が、バグの混入率は低いといえます。

 また、このような「プロジェクトの特殊な事情によるコーディングルール」を用いる場合、プログラマーにルールを徹底させるよりも、少数のアーキテクトが一括して把握・管理する方が、抜け・漏れがなくなり品質が向上します。筆者のプロジェクトの場合も、プログラマーが把握・管理しなければならないコーディングルールを増やさないことで、プログラマーが開発に集中できていました。特にそのことを実感したのは、ソースコードレビュー時です。ソースコードレビュー時にコーディングルールにのっとってメソッドを呼んでいるか? というチェックポイントが不要となり、全体の開発効率が向上していることを実感しました。

 以上が、処理を後から挿入するというAOPの特長を利用して仕様変更に対応した事例です。Springを利用していればAOPを利用できるため、こういった対応が可能です。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。