個々のコンポーネントを組み上げて、どのようなシステムを構築するか。構造(アーキテクチャ)によって、できあがるシステムの性質が変わってくる。作り手側の視点に立てば、どのようなアーキテクチャを採用するかによって、作り方も変わってくる。いままで連載した記事を通して、わたしたちは、個々のコンポーネントの作り方を学んできた。今回からは、コンポーネントをいかに組み上げるか、という課題に知恵を絞ることになる。コンポーネントの利点を最大限に生かすこと。それがアーキテクチャ設計の現実的な意味の1つだ。そして、1つの有効なアプローチに階層化アーキテクチャがある。
前回「使いやすくて、変化に強いコンポーネント」までにサブシステムなどを利用したコンポーネントの作り方についてお話ししてきました。それでは、コンポーネントは実際どのような単位で作り上げていけばよいのでしょうか。
コンポーネントの単位として考えられるのは、業務的な側面から見た考え方と技術的な側面から見た考え方があります。
業務的な側面とは、会員関連のサービスをまとめた会員コンポーネントや、貸出関連のサービスをまとめた貸出コンポーネントなどに整理整頓していく考え方です。これについては概念モデリングやユースケース分析等を通して機能要件としてまとめていきます。
それでは、技術的な側面からのコンポーネント化の考え方はどのようなものなのでしょうか?
ビジネスアプリケーションは、いろいろな技術を利用して構築していきます。一般的なWebシステムの例では次のようになります。
上記のようにWebシステムはユーザーインターフェイスやデータの永続化などをいろいろな技術で実現しています。会員コンポーネントを実装するには、HTMLやJavaScript、Java言語によるアプリケーションロジック、SQLなど複数の技術が必要になります。
これらの技術は、ある目的を実現するために適用します。例えば、HTMLはWebシステムにおいてはユーザーインターフェイスを実現するために適用します。また、Java言語はビジネスロジックを実現するためなどに適用します。そして、トランザクション制御や分散性の実現などはアプリケーションサーバの機能を利用して実現します。
これらのインターフェイスやビジネスロジック、トランザクションの実現などを、1つのコンポーネントの中に整理せずに入れてしまうと、役割が複雑になり理解がしにくいものになってしまいます。ユーザーインターフェイスのための機能やビジネスロジック、データベースをアクセスするロジックなどが混在してしまいます。これでは、拡張性や保守性、生産性を良くすることはできません。
また、技術に依存したコンポーネントを作成してしまうと、技術が進歩したときやほかの技術で実現したくなったときに、簡単に変更することができなくなります。データベースやアプリケーションサーバを変更したいときなど、関係のないビジネスロジックなどには影響を与えたくありません。
このような問題を解決するためにアーキテクチャの設計を行います。まさにこれこそが、アーキテクチャ設計を行う意味ともいえます。それではアーキテクチャとはどのようなものでしょうか。
上流工程では実現したい業務システムを概念モデリングやユースケース分析で分析・設計し、次のようなことを目指しました。
次の段階として実装を意識した設計を行う必要があります。拡張性・保守性も業務面からだけではなく技術面からも検討する必要があります。
このようなことを考慮に入れて設計するためにアーキテクチャ設計があります。
今回は、(1)の「業務システムのシステム環境からの依存性の排除」と(2)の「コンポーネント化され保守しやすく、拡張性の高いシステム」に関するアーキテクチャの設計手法として、階層化アーキテクチャについて考えていきます。
ソフトウェアにおけるアーキテクチャとは、要求を実現するために必要なソフトウェアの構造やメカニズム、制約などを定義するものです。
ソフトウェアの構造とは、階層構造やコンポーネントを定義することであり、メカニズムとは、データの永続化やセキュリティ要件、分散性の実現などを定義することです。そして制約は、システムを実際に実現するために開発言語、ミドルウェア、DBMSなどの実装上の制約を定義します。
アーキテクチャとは、要求を実現するために必要なソフトウェアの構造、メカニズム、制約を定義すること
→ソフトウェアの構造……階層構造化(レイヤ化)など
→メカニズム……データの永続化、セキュリティ、分散性
→制約……言語による制約、データベースによる制約、アプリケーションサーバによる制約など
これらのうち、今回はソフトウェアの構造について重点的に見ていきましょう。
ソフトウェアの構造を定義する道具は、パッケージやサブシステムを利用します。そして、ソフトウェアの構造を定義する考え方は、次に示すようにコンポーネント化や階層化などがあります。
(1)ソフトウェア構造を定義する道具
(2)ソフトウェア構造を定義する考え方
アーキテクチャは整理整頓するための考え方の1つです。いままでにサブシステムやパッケージを利用して整理整頓する考え方についてお話ししてきました。
コンポーネント化とは、「複雑なもの」を「簡単な構造の組合せ」で分析し設計するために行います。これからお話しする階層化アーキテクチャは、このコンポーネントを利用して技術的な観点から整理する考え方です。
階層化アーキテクチャは、目的に応じて層を定義し、層と層の間のインターフェイスを考えていきます。図2に、階層構造の代表的な例を示します。このようにシステムの論理的な階層構造を定義しています。
層とは、ある目的(インターフェイスやビジネスロジックなど)に合った機能のレベルを合わせたコンポーネントの集合体です。
層は技術的な機能レベルでの分離を実現し、層内では業務機能に基づく業務機能的なレベルの分離を行います。
ユーザーや外部システムから見えるのはユーザーインターフェイス層であり、アプリケーション層などは利用できません。ユーザーインターフェイスは、画面の描写や入力受け付けの制御、外部システムからの入力電文の受け付けなどを受け持ちます。
アプリケーション層はユーザーインターフェイス層から利用される層であり、下位の層であるサービス層を利用します。アプリケーション層は、ユーザー入力値の検証や画面遷移の制御などを行います。
サービス層は、サービスを実現するコントローラーの役割を持っています。サービスを実現するために、ドメイン層にあるビジネスロジックを利用して一連のサービスを実行していきます。サービス層ではトランザクションや分散性などの非機能要件を設計します。
ドメイン層は、複数のサービス層から利用されるビジネスロジックを設計します。ドメイン層は、データを永続化する必要があるので、下位のパーシステンス層を利用してデータベースにデータを永続化します。
パーシステンス層は、RDBなどを利用して実際に永続化する機能を受け持ちます。
このように階層化アーキテクチャは、ある層は上位の層から利用され下位の層を利用するように設計します。層はできるだけブラックボックス化し、上位の層が利用するときは、内部の仕組みを理解しなくても利用できるようにインターフェイスを設計します。
それでは次に、これらの階層は上流工程で設計してきた結果(概念モデルやユースケースモデル)とどのように関連するのでしょうか。
上流工程では、普遍的な構造と固有な構造を定義しました。普遍的な構造は概念モデルを定義します。また、ユースケース分析から固有な構造を定義しました。実際にシステムを構築するには、次のような実装を意識した設計を行う必要があります。
(1)インターフェイス設計
画面設計や他システムとの接続
(2)ユースケース分析
システムが提供すべきサービスを分析・設計する。サービス固有な構造を定義する。
(3)概念モデリング
サービスから利用される概念の構造を分析・設計する。各サービスから利用されるビジネスロジックを設計する。普遍的な構造を定義する。
(4)データベース設計
概念モデリングなどで分析した結果から、データベースのデータ構造を定義する。
概念モデルから、ビジネスロジックや永続化データを中心に実装可能なドメインモデルを作り上げ、ドメイン層を実装していきます。
ユースケース分析の結果のユースケースモデルは、サービスを実現するための複数のビジネスロジックを実現するコントローラーの役割を明らかにしているため、サービス層において実装していきます。
また、ユースケースモデルによりサービスの要件が明らかになり、画面設計や画面遷移、チェック条件などのインターフェイス設計を行いプレゼンテーション層やアプリケーション層の設計を進めていきます。
概念モデルからは永続化データの構造を分析していきます。リレーショナルデータベースを利用するなら、O-Rマッピングを行います。概念モデルからER分析等を通してデータベース設計を行いパーシステンス層の設計を進めていきます。
このように上流工程で設計を基に、メカニズムや制約を取り込みながら階層化アーキテクチャを設計していきます。
階層化アーキテクチャは、ソフトウェアの全体構造を定義します。まずは階層化アーキテクチャの層によってインターフェイスなどの役割ごとに分離します。それから、技術的な要因の複雑さを減少させ、コンポーネントを機能ごとに分離します。そのうえで、業務機能からくる複雑さを少しずつ少なくしていきます。以下にポイントを示します。
以下に階層化アーキテクチャを利用する利点を示します。
層の再利用
層と層の間はインターフェイスで定義されているため、例えばドメイン層のビジネスロジックは、ほかのシステムでも利用することができます。また、層が役割に応じて作られていれば、ドメイン層にトランザクションの制御の機能が含まれることがないため、ほかのシステムのサービス層でも利用することができます。
交換容易性
データベースを変更する場合など、層ごと交換してもインターフェイスを変えなければほかの層に影響が出ない。
標準化の支援
層により役割が明確になり標準化が進む。
依存性の局所化
技術的、業務的にまとめられ隠ぺいされた独立性に高いコンポーネントにより依存性を少なくできる。
階層化アーキテクチャの設計における考慮事項としては、次のようなことが挙げられます。
(1)可視性
依存 関係は、現在の階層とその直下の階層のみとする(ただし、データを表示するだけのときなど、直接パーシステンスを利用することは例外的にある)
(2)不安定性
(3)汎用性
より抽象的なモデル要素を下位の階層に入れる
(4)レイヤの数
今回は5層の例を説明しましたが、規模や複雑さによって、階層の数は変えていきます。複雑でないシステムなら、インターフェイス層、アプリケーション層、ドメイン層などの3層にしてもよいでしょう。また、大規模開発などでは、層を多くすることにより設計作業が複雑になり管理が大変になることもあります。システムの規模や複雑さ、プロジェクトのスキルなども考慮し決めていく必要があります。
今回は、階層化アーキテクチャを適用することにより、非機能要件に基づく技術的な複雑さを低減するための考え方をお話ししました。次回は、階層化アーキテクチャのサービス層、ドメイン層、パーシステンス層についての設計の考え方についてお話ししていきたいと思います。
Copyright © ITmedia, Inc. All Rights Reserved.