MVCモデルに基づいたプログラム構造の例

 昨今、MVCモデルに基づくプログラムというのが話題となっていますが、概念的なことはいいとして、我々プログラマにとっては、実際どのような実装になるのかが関心のあるところです。
そこで、MVCモデルに基づいた業務アプリケーションのプログラムの構造を考えてみたいと思います。


  1. MVCモデル

     まず、MVCモデル についてあらためて整理しておきたいと思います。

     MVCモデルとは、


    の略で、プログラムをできるだけ独立した(相互に影響の受けない)これらの3つの部分に分けて実装しようというものです。

    また、業務仕様に依存しない基盤部品(Basic Parts)は、このモデルでは Model に含まれるのかもしれませんが、ここでの設計のシミュレーションでは、これとは別に考えようと思います。


  2. プログラム構造

     MVCモデルに基づいて考えたプログラムの構造のひとつの例として、以下の図のような構造が考えられます。

    
                                   +-----------------+
                                   |                 |        *1. Adaptor
                                   |       UI        |
                                   |                 |            イベントを受けた時に呼ばれるモジュール。
                                   +-----------------+            JavaではListenerといっている場合もある。
                                            |
                                   +-----------------+
                                   |                 |
                     +-------------|   Adaptor(*1)   |←-----------+
                     |             |                 |             |
                     |             +-----------------+             |
                     |                      |                      |
            +-----------------+             |             +-----------------+
            |                 |             |             |                 |
            |  Request  Data  |             |             |  Response Data  |
            |                 |             |             |                 |
            +-----------------+             |             +-----------------+
                     |                      |                      |
                     |             +-----------------+             |
                     |             |                 |             |
                     +-----------→|   Controller    |-------------+
                                   |                 |
                                   +-----------------+
                                            |
                                   +-----------------+
                                   |                 |
                                   | Business Logic  |
                                   |                 |
                                   +-----------------+
                                            |
                                   +-----------------+
                                   |                 |
                                   |   Basic Parts   |
                                   |                 |
                                   +-----------------+
        
    補足1:モジュール構成

     原則的な考え方としては、ひとつのイベントに対して1セットの Adaptor, Controller, Request Data, Response Data を用意する。
    もちろん、共通的に使えるのであれば、異なるイベントに対して同じものを使うことは禁じない。

    Business Logic は、共通的に使用する(汎用的な)モジュールである。

    補足2:Adaptor, Controller 間のデータの受け渡し

     Adaptor, Controller 間のデータの受け渡しは、拡張性を考慮して、個別に引数で渡すのではなく、データ構造(JavaであればDataBean(*2))で行なう方式にする。
    ここで、Request Data, Response Data は、View に依存しないことが重要である。
    受け渡しデータは、表示の有無や表示形式等(View)は考慮せず、それらは全て View に任せるのが好ましい。(だからといって、数個のデータを表示するだけのために大量のデータを渡すことになってしまうような場合は考慮が必要かもしれない。)

    *2. DataBean … プロパティ(クラス変数)とそれに対するアクセッサ(setter, getter)だけを持つクラス。

    コメント:

     実際に本方式でプログラミングしていたところ、Webアプリケーションにおいては、イベントごとに処理が独立しているために本方式が良いが、単独実行プログラムでは、プログラムが冗長になってしまい、かなり無理なプログラムになってしまった。
    無理して本方式にする必要はないと思うが、本方式にしておけば、Viewの部分が単独実行プログラムであってもWebアプリケーションであってもController以下は同じプログラムを使えることも心に留めておくべきである。


  3. 各モジュールの考え方

    1. Adaptor

      • 要求を実施するのに必要なデータをUIから取得して、それを添えて Controller に処理を依頼する。
      • Controller から戻ってきた処理結果を、UIに合わせた形式にして出力する。
      • 単なる画面遷移等の業務処理の必要ないイベントに対しては、Adaptor 内で処理を完結する。

    2. Controller

      • Business Logic を駆使して、Adaptor からの要求を実現する。

      注)Controller では、Business Logic の呼び出しとその結果の収集にとどめ、業務処理的なことはしない。

    3. Business Logic

      • 個別の業務仕様に対する処理を提供する。

      注)使われ方を意識しないプログラム仕様であることが重要。

    4. Request Data

      • UI からの要求を実現するのに必要なデータ。

    5. Response Data

      • UI からの要求を実施した結果のデータ。

      注)View 意識せず、業務的な意味でのデータの単位で作成する。
        そうしておけば、出力仕様に変更があっても、 Adaptor 内で吸収できる範囲が大きい。