特集

.NET開発者のためのDI&AOP入門(後編)

コードで簡単に分かる“AOP”

株式会社アイビス 杉本 和也
2008/01/23
Page1 Page2

 “DI”や“AOP”の説明を読むと難しくていまいちよく分からないし、結局どのような場面で何の役に立つのかよく分からない。そんな印象を持つ人は多いのではないだろうか?

 本特集では、DIやAOPを用いた非常にシンプルなソース・コードを実際に書いて動かしてみることで、DIやAOPの有効性や可能性を感じていただくことを目的にしている。本稿を通して.NET開発におけるDI&AOPの有効性と可能性を感じ取っていただければ幸いである。

 前編ではDI(Dependency Injection。依存注入)を説明した。今回の後編ではAOP(Aspect-Oriented Programming。アスペクト指向プログラミング)について紹介していきたいと思う。

3. ソース・コードで考えるAOP

3-1. ソース・コードで考える「AOPとは何か?」

 前編ではAOPについて次のように説明した。

「AOPとは、オブジェクト指向ではうまくメソッド化できない、オブジェクト間に共通する処理を抽出して、1カ所にまとめるプログラミング手法のこと。」

 だが、このような言葉だけの説明では、なかなかAOPの概念は理解しづらい。そこで以下では、前編と同じDI&AOP用のフレームワーク「S2Container.NET」を実際に用いながら、ソース・コードを交えてAOPを解説していこう。

 それでは、業務ロジックをコーディングする場合を考えてみよう。この際に、本来の目的ではない「業務処理以外のコーディング」が必要となる場合がある。例えばロギング処理(=ログ出力処理)やトランザクション処理がそれである。

 これらの処理は、複数の個所(=複数のメソッド内など)で必要とされることが多い。一般的に共通する処理が複数存在する場合、その共通処理のメソッド化(=メソッドの切り出し)を行うだろう。しかし、ロギング処理やトランザクション処理はこのような共通処理のメソッド化が行えない場合が多い。

 例えば、複数のメソッドで、その開始時と終了時にログを出力する場合、下記のコードのように、各メソッドの開始部分と終了部分にロギング処理をちりばめていくことになる。従って、ロギング処理をメソッド化することは難しいのだ。

using System;
……省略……
public string GetEmpNameWithTitle(int empNo)
{
  Console.WriteLine("開始GetEmpNameWithTitle(" + empNo + ")");
  string empName = EmpDao.GetEmpName(empNo) + "さん";
  Console.WriteLine("終了GetEmpNameWithTitle : " + empName);
  return empName;
}
……省略……
リスト1 各メソッドの開始部分と終了部分に記述したロギング処理のコード(EmployeeLogic.cs)

 このような場合にAOPが役立つ。AOPを使って共通処理を抽出して1カ所にまとめることによって、ロギング処理が分散することを防ぐことができ、ロギング処理に仕様変更が必要となった場合のメンテナンス性が向上する。また、本来の目的ではない「業務処理以外のコード」が分離され、本来の目的である業務処理だけのシンプルなソース・コードになり可読性も向上する。

 詳しくは後述するが、S2Container.NETのQuillでは「Aspect属性(Seasar.Quill.Attrs名前空間)」を指定するだけで簡単にAOPを実践することができる。Quillは前編でも使用しているので、Quillについては前編を参照してほしい。なお本稿のサンプルも、前編で作成した「QuillSample」プロジェクトを利用している。このプロジェクトは次のリンクからダウンロードしてもよい。

 次のリスト2は、先ほどのコード例(リスト1)をQuillのAspect属性を用いて書き換えたものだ。Aspect属性のパラメータとして指定されている「ConsoleTraceInterceptor」クラスには、抽出されたロギング処理が記述されている。詳しくは次項の「3-2. AOPの実践」で紹介する。

using Seasar.Quill.Attrs;
……省略……
[Aspect(typeof(ConsoleTraceInterceptor))]
public virtual string GetEmpNameWithTitle(int empNo)
{
  string empName = EmpDao.GetEmpName(empNo) + "さん";
  return empName;
}
……省略……
リスト2 Aspect属性によってAOPを利用するコード(EmployeeLogic.cs)
ConsoleTraceInterceptorクラスに、共通するロギング処理が抽出されて記述されている。

 それでは、前回作成したWindowsアプリケーションのサンプル・コードを基にAOPを実践してみよう。


 INDEX
  [特集].NET開発者のためのDI&AOP入門
  Seasar.NETでDIを始めよう
    1.DI&AOP開発環境の準備
    2.DIとAOPを理解するためのサンプルの作成
    3.ソース・コードで理解するDI
    4.DIが役立つ場面
 
  コードで簡単に分かる“AOP”
  1.ソース・コードで理解するAOP
    2.AOPの実践


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間