読者です 読者をやめる 読者になる 読者になる

【アーキテクチャパターン】POSA Vol.1のReflection(リフレクション)

Reflectionアーキテクチャパターンは,システムの構造と振る舞いを動的に変更するメカニズムを提供する.
このパターンを利用すると,型機構や関数呼び出し機構といった基礎的な部分の変更が可能になる.

このパターンはアプリケーションを2つの部分(メタレベルとベースレベル)に分割する.

  • メタレベルはシステム属性に関する情報を提供し,ソフトウェア自体を自己認識可能にする.
  • ベースレベルはアプリケーションの論理を含み,メタレベル上に実装される.

メタレベルの保持する情報に対する変更は,結果的にベースレベルの振る舞いに影響を与える.

  • 別名
    • Open Implementation
    • Meta-Level Architecture

前提

システム自身の変更を支援する機構を,前もって組み込んだシステムを構築する.

課題

変更や拡張にオープンなシステムを構築すること. 関連するフォースを列挙する.

  • 変更による影響を抑える
  • 適合性をもつシステムは,複雑な内部構造を持つ.この複雑性を保守担当者から隠蔽する
  • 変更はさまざまなスケールで発生する

解決策

ソフトウェアを自己監視できるものにする. そして,適合や変更のためには,その構造やふるまいのどの部分にアクセスするのかを決定する. これを間ゲルと,2つの部分から構成されるアーキテクチャを採用することとなる.

  • メタレベル
  • ベースレベル

静的構造

f:id:yusuke_ujitoko:20161119180718p:plain

メタレベル

メタレベルでは,ソフトウェア自身の構造を振る舞いを記述する. このレベルを構成するのはメタオブジェクトである. メタオブジェクトは,ソフトウェア情報をカプセル化する. カプセル化する情報の発生源は下記の3つ

  • システムの実行環境
    • 例:C++の実行時型情報
  • ユーザ定義
  • 実行時に行われるベースレベルからの問い合わせ
    • 例:現在の計算状態

システムの詳細部分のうち,変更の発生しやすい部分や顧客ごとに変化する部分だけを,メタオブジェクトでカプセル化するのが望ましい.

ベースレベル

ベースレベルで,アプリケーションロジックを定義する. ベースレベルは,メタオブジェクトのインターフェースを介して,メタオブジェクトの管理している情報やサービスにアクセスできる. これらのメタオブジェクトに変更の発生しやすい要素をカプセル化することで,ベースレベルのロジックは変更から守られている.

メタオブジェクトプロトコルコンポーネント(Metaobject Protocol:MOP)

f:id:yusuke_ujitoko:20161119180944p:plain

メタオブジェクトプロトコルコンポーネントは,メタレベルの外部インターフェースである. そして,リフレクティブなシステムへのアクセスを定義する.

Layersパターンとの違いについて

リフレクティブなアーキテクチャの汎用的な構造は,Layersパターンに従う構造に似ている. メタレベルとベースレベルが2つのレイヤを構成する.

f:id:yusuke_ujitoko:20161119181250p:plain

しかしLayersパターンと異なり,Reflectionアーキテクチャでは,2つのレイヤが相互依存する.

  • ベースレベルはメタレベルに基づいて構築される.
  • メタレベルもベースレベルに基づいている.
    • 例:例外を起こす振る舞いをメタオブジェクトが実装する場合など.
      そのときには現在の計算状態に依存するような手続きが存在する この手続の中でメタレベルはベースレベルから情報を取り出すことになる.

動的側面

シナリオ1

ディスク上のファイルに保存されたオブジェクトを読み込む際のベースレベルとメタレベルの協調作業を示す. ベースレベルは,メタオブジェクトのインターフェースを介して,メタオブジェクトの管理している情報や提供しているサービスにアクセスできる.

f:id:yusuke_ujitoko:20161119182838p:plain

シナリオ2

メタレベルに情報を追加する際のメタオブジェクトプロトコルの使用方法を示すもの f:id:yusuke_ujitoko:20161119183518p:plain

実装

  1. アプリケーションのモデルを定義する
  2. 振る舞いのバリエーションを特定する
  3. システムの構造的側面を特定する
  4. システムサービスを特定する
  5. メタオブジェクトを定義する
  6. メタオブジェクトプロトコルを定義する
  7. ベースレベルを定義する

バリエーション

  • 複数のメタレベルをもつリフレクション

結論

Reflectionアーキテクチャの利点

  • ソースコードの変更が起きない.
  • ソフトウェアシステムの変更が容易である
  • さまざまな変更を支援する

Reflectionアーキテクチャの欠点

  • メタレベルの変更が致命的ダメージになる危険性をもつ
  • コンポーネント数の増大
  • 効率性が低い
  • ソフトウェアの変更可能性がすべて想定されているわけではない
  • リフレクションをサポートしない言語も存在する

yusuke-ujitoko.hatenablog.com