n階層システム設計の考慮点

第5回 ビジネスレイヤの設計について

この記事を読むのに必要な時間:およそ 7 分

③ ビジネスコンポーネント設計の注意点およびノウハウについて

ビジネスコンポーネントには以下のような機能が含まれます。

入力チェック

サービスインターフェイス経由もしくは直接ビジネスコンポーネントが呼び出された場合でも,業務ロジックにデータを渡す前にチェックを行います。ここでは単純な入力チェックだけでなく,データの相互性チェックや論理チェック,データレイヤからのデータとのマッチングなどさまざまなチェックを行います。これらは共通部品化され,ビジネスレイヤ内で再利用されることが多いため,それを意識した設計にする必要があります。しかし,共通化を図るあまり,内部が複雑になってしまうケースがよく見受けられます。共通部品の種類は多くなってしまいますが,できるだけ単純な機能の単位で設計するようにします。

ビジネスファサード

いくつかのビジネスコンポーネントを纏めて実行する場合やインターフェイスを纏める場合などで作成されます。ここにはビジネスロジックは実装しません。

業務ロジック

業務ロジックそのものです。これらも機能単位でカプセル化され,再利用,再試行,再構成が可能になるように設計します。しかし,これは下記のトランザクション管理と密接に関連し,同じデータの2重実行でもデータの一貫性を保つように設計します。

業務ロジックのデータの入出力はできるだけ一貫性を保つようにし,XMLやDataSet(型付き,型なし)などでやり取りします。

トランザクション管理

ビジネスコンポーネントはトランザクションを開始できます。そのため,トランザクションの境界を意識して設計する必要があります。また,短時間で終了するトランザクションだけでなく,長時間トランザクションも管理するため,状態,中間データ等の管理も考慮する必要があります。

トランザクション開始後,別のビジネスコンポーネントの呼び出しなどがある場合,トランザクションに参加しているすべてのビジネスコンポーネントのどこかでエラー発生・中断・例外等が発生した場合,これらをすべてロールバックできるように設計する必要があります。

また,トランザクション開始後,別のビジネスコンポーネントがデータレイヤのサービスエージェントを経由してアプリケーション外に接続している場合などでは,非同期処理として考え,ビジネスデータ的に一貫性,整合性が保てるように設計します。しかし,この場合,可能であれば接続先の状態を入手し,メッセージやログなどに出力し,痕跡が残るように設計します。

バッチ処理的にビジネスコンポーネントが設計・実装・利用される場合は中間コミット等を用い,エラー等が発生した場合の再試行性の向上を図ることも設計時に検討します。

また,長時間トランザクションについても一定時間の経過後トランザクションを終了させるポリシーを作成し,それに従って設計を行います。

④ ビジネスエンティティ設計の注意点およびノウハウについて

ビジネスエンティティはサービスインターフェイスを通してビジネスレイヤがサービスとして公開されている場合およびデータレイヤとのデータの受け渡しにおいて,さまざまなデータ形式が使用されます。

XML

W3C(World Wide Web Consortium)標準の準拠のため,プラットフォームに依存しません。 しかし,厳密な型の指定のエンティティを作成知るためにはXML スキーマ定義言語(以降XSDと略します)で定義する必要があります。

XMLを作成するためには専用のエディタもしくはVisual Studio等を用いて作成するとタイプミスなどが少なくなります。

また,.NET Language-Integrated Query(LINQ⁠⁠ to XMLを用いることで,メモリ内に読み込んだXMLの構文解析・ソート・ツリー構造化・操作が行えるようになりました。

DataReader

ADO.NET(ActiveX Data Objects for .NET Framework)を利用してデータベースに同期型で接続しデータを取得します。データの型は基本的にデータベース内のデータ型に依存します。

型なしDataSet

ADO.NETを利用して非接続型で接続し,データのやり取りを行います。

型なしDataSetはシリアル化に対応しており,ユーザインターフェイスコンポーネント(DataGrid,GridViewなど)への表示が容易にできます。 また,データ・項目の並べ替え,フィルタリングができ,DataSetの内容をXMLとして入出力することができます。この場合はXSDがないため,厳密な型指定はできません。

しかし,型なしDataSetのインスタンス生成やデータの出し入れ,検索の際に実行環境に負荷がかかります。

型なしDataSetは厳密な型指定がされていないため,コンパイル時に型のチェックがされず,エラーの原因となりやすいです。

型付DataSet

ADO.NETを利用して非接続型で接続し,データのやり取りを行います。型付DataSetはシリアル化に対応しており,ユーザインターフェイスコンポーネント(DataGrid,GridViewなど)への表示が容易にできます。 また,データ・項目の並べ替え,フィルタリングができ,DataSetの内容をXMLとして入出力することができます。この場合はXSDがあるため,厳密な型指定がされます。

しかし,型付DataSetのインスタンス生成やデータの出し入れ,検索の際に実行環境に負荷がかかります。

型付DataSetは厳密な型指定がされてるため,コンパイル時に型のチェックがされます。 この際,DataSetのデータ操作などのメソッド等も自動的に生成されるので,容量が大きくなります。

型付DataSetはXSDで厳密に型指定されているため,データの受け渡し側に変更が発生した場合は再作成する必要があります。

カスタムビジネスエンティティコンポーネント

カスタムオブジェクトは個別に型指定されたプロパティやメソッドを作成するため,プライベートロジック,個別の操作や検証用ロジックを実装することができます。

カスタムオブジェクトは厳密な型指定がされてるため,コンパイル時に型のチェックがされます。

Visual Studioを用いてソースを作成する際には,インテリセンスを使用してカスタムオブジェクト内のプロパティやメソッドを呼び出すことができます。

カスタムオブジェクトは個別に作成するソース内で厳密に型指定するため,開発工数が大きくなります。 また,厳密に型指定されているため,データの受け渡し側に変更が発生した場合は再作成する必要があります。

しかし,.NET Framework 3.5でサポートされたLINQ to Objectを用いることで,メモリ内に読み込んだカスタムオブジェクトの構文解析・検索・ソート・ツリー構造化・操作が行えるようになりました。

サービスインターフェイスを通してビジネスレイヤがサービスとして公開されている場合は,XML,カスタムビジネスエンティティコンポーネントを使用します。これらを使用することで,ほかのプラットフォームとの互換性を持たせることができます。

データレイヤとのデータの受け渡しにおいては,XML,DataReader,型なしDataSet,型付きDataSet,カスタムビジネスエンティティコンポーネントを選択し,より効率のよい方法を用いて設計します。これらの選択基準としては,ビジネスコンポーネントでのこれらデータの操作によって選択できると思います※5⁠。

XML

XMLは下記に紹介するLINQ to XML技術を使用しない限り,検索・ソート等は低コストでは実装できません。しかし,軽量であることと値の読み出しなら低コストで実装できます。

DataReader

ビジネスコンポーネントでデータを加工し,データレイヤ経由でデータベースを更新する場合,DataReaderでは,Arrayなどへの値の入れ替え,更新前に型付きDataSetでのデータの確認後,更新となるので,非効率となります。しかし,接続したデータベースからの値の読み込みだけであれば高速で,低コストで実装できます。

型なしDataSet

複数のTableやデータ以外のオブジェクトを扱うのであれば型なしDataSetを選択するのが低コストで実装できます。

型付きDataSet

厳密な型指定がされているので,ビジネスコンポーネントでデータを加工し,データレイヤ経由でデータベースを更新する場合はそのままデータを渡すことができるので,低コストで実装できます。

カスタムビジネスエンティティコンポーネント

カスタムビジネスエンティティコンポーネントに関しては,上記の手法では実装が難しい場合などに選択することとなります。

LINQの登場

LINQが登場するまでのXMLおよびカスタムビジネスエンティティコンポーネントでは,構文解析・検索・ソート・ツリー構造化・操作などを行うことは非常に困難で,これらを行うために別にコンポーネントを作成したり,型付きDataSetに格納・操作後,再取り出す等のオーバヘッドを行っているプロジェクトもありました。

また,さまざまなデータベースへの接続,コマンド等はSQLで基準化されているとは言え,少しずつ作法や方言的なものがあり,使用するものによって使い分ける必要がありました。

さらにXMLドキュメントの操作や各種Webサービスなどそれぞれのデータソースに対してクエリ言語を習得する必要もありました。

しかし,LINQの登場により,これらは開発時に使用する言語の一部として扱えるようになりました。クエリは,C#とVisual Basicにおける言語構成要素となり,言語キーワードと使い慣れた演算子を使用することで,厳密に型指定されたオブジェクトのコレクションに対するクエリを記述できるようになりました。

LINQ技術はデータレイヤで扱うデータソースやサービスへの接続・操作であるため,データレイヤで扱うべきではないかとの意見もあります。しかし,私としてはビジネスロジックと密接な関係がある,開発言語の一部として提供されていることなどからビジネスエンティティで取り扱うべきであると考えています。

※5

以前私が支援したプロジェクトでは当初,本部サーバから支店サーバへ型付きDataSetを支店サーバのアプリケーションにデータ受け渡しをしていました。しかし,格納データが多いこと(最大10万件)もあり,転送時間がかかっていました。そこで,型付きDataSetからXSD付きのXMLファイルに変換し,XMLファイル,XSDファイルを共に圧縮し,ファイルを転送する方式に変更しました。これにより,転送時間を約1/10に短縮することができました。しかし,支店サーバ側では圧縮ファイルの解凍,型付きDataSetへの読み込みが必要であり,全体的な時間は約1/4程度となりました。

このように型付きDataSetからのXMLへのシリアライズ及びデシリアライズにはシステムへの負荷がかかります。これらも考慮して方式を検討する必要があります。

著者プロフィール

露木敏博(つゆきとしひろ)

1966年神奈川県横浜市生まれ。1990年,株式会社日立システムアンドサービス(旧日立システムエンジニアリング株式会社)に入社。

流通系SE,営業所駐在SEなどを経て,2003年から生産技術部門で.NET技術に関する技術支援業務に携り,.NET技術に関する各種基準書および標準化,設計ガイドなどを作成。

マイクロソフトMVPアワードプログラムよりDevelopment Platforms - ASP/ASP.NETのカテゴリで2008年7月よりMVPアワードを受賞。