MVC アーキテクチャの詳細な紹介と分析

MVC

  Mvcの概念:M:モデル(モデル)、V:ビュー(ビュー)、C:コントローラー(コントローラー)
ここに画像の説明を挿入します

MVC制御フローチャート
   MVC の処理プロセスは、コントローラーがビジネス リクエストを受信し、処理のために呼び出すモデルを決定します。その後、モデルのビジネス ロジックがユーザーのリクエストを処理してデータを返します。最後に、コントローラーは、モデルから返されたデータを対応する形式でフォーマットします。ビューを表示し、それを通過させます。 ビュー レイヤーがユーザーに表示されます。

階層の概念

ビュー層: データの表示とユーザーとの対話に使用される
インターフェイス コントロール層: クライアント要求を受信できます 特定のビジネス機能を完了するには、依然としてモデル コンポーネントが必要です。
モデル層: ビジネス ロジックとデータベースの相互作用の処理、およびデータの伝達を担当します。モデルには、単純な pojo/vo (値オブジェクト)、ビジネス モデル コンポーネント、データ アクセス層コンポーネントなど、さまざまなタイプがあります。

モデル層のカテゴリ:
1) pojo/vo: 値オブジェクト: フルーツクラスは値オブジェクトであり、対応する属性データを取得できます。
ここに画像の説明を挿入します

2) DAO: Data Access Object: データベースに接続し、対応するデータベース フォームを操作する DAO クラス

ここに画像の説明を挿入します

3)BO:ビジネスオブジェクト:ビジネスオブジェクトは、対応するデータオブジェクトを呼び出して一連の操作を実行する。
ここに画像の説明を挿入します

ビジネス オブジェクトとデータ アクセス オブジェクトを区別します:
1) DAO のメソッドはすべて単精度メソッドまたは詳細メソッドです。各メソッドは、データベースへの追加や挿入など、1 つの操作のみを考慮し、他の操作の影響は考慮しません。 。
2) BO のメソッドはビジネスメソッドに属しますが、実際のビジネスは比較的複雑であるため、ビジネスメソッドの粒度は比較的粗いです。サービス層のビジネス実装では、定義された dao 層インターフェイスを呼び出す必要があるため、サービス層のビジネス ロジックをカプセル化すると、一般的なビジネス ロジックの独立性と再利用性が向上します。プログラムは非常に単純なようです。
   例えば、アカウント登録機能はビジネス機能であるため、登録メソッドもビジネスメソッドになります。
このビジネス メソッドには多数の DAO メソッドが含まれています。つまり、このビジネス関数の登録を完了するには、複数の DAO メソッドを組み合わせて呼び出す必要があります。
登録:
1. ユーザー名が登録されているかどうかを確認します - DAO での選択操作
2. ユーザー テーブルに新しいユーザー レコードを追加 - DAO で挿入操作
3. ユーザー テーブルに新しいユーザー レコードを追加 - DAO で挿入操作
4.新しいユーザー レコードをシステム メッセージ テーブルに追加します - DAO
5 で操作を挿入します。 新しいユーザー レコードをシステム ログ テーブルに追加します - DAO
6 で操作を挿入します。
簡単に言うと、DAO レイヤーはデータベースを処理し、サービス レイヤーは一部のビジネス プロセス (DAO 呼び出し操作だけでなく) を処理します。

MVC構築のメリット

  各層を強制的に分離できるため、層間の依存関係が軽減され、コードの再利用を最大限に高めることができます。たとえば、MVC レイヤーでは、複数のビューが 1 つのモデルを共有でき、コントローラーはユーザーのニーズを満たすために異なるモデルとビューを接続することもでき、3 つのコンポーネントが互いに独立しているというこの設計思想により、良好な疎結合を生み出すことができます。

フルーツプロジェクトシステムにビジネスレイヤー実装の概念を追加

  オリジナルの最適化されたフルーツシステムでは、ユーザーから送信されたリクエストの処理フローは下図のようになります:
ここに画像の説明を挿入します
  リクエストを受け取ったユーザーセントラルコントローラーは、コントロール層に直接コマンドを発行し、コントロール層はモデルにアクセスして一連の処理を実行します。 DAO メソッドを呼び出してデータを取得し、最後にページのレンダリングを表示します。
  MVC モデルを使用して開発を進めていくと、徐々にレイヤー間の癒着や曖昧さを感じるようになりますが、これがサービス レイヤーの出現の重要な理由です。ビジネス ロジックは C 層と M 層に接続されているため、ビジネス ロジックを分離して独立したサービス層にする必要があります。
  この機能を実行するためにユーザー テーブルと権限テーブルを使用すると仮定します。その後、フロント ページがアクションにアクセスし、アクションがユーザー モジュール サービスを呼び出します。ユーザー モジュール サービスは、ユーザー テーブルと権限テーブルのどちらを操作しているかを決定します。ユーザーを操作している場合、サービス実装クラスは userDAO を呼び出します。パーミッションテーブルが操作されている場合、パーミッションDAOが呼び出されます。つまり、DAO はデータベース内の各テーブルと 1 対 1 の対応関係を持つ必要がありますが、サービスはそうではありません。


サービス層がないことによって生じる問題:
   ビジネス ロジックは制御層に直接実装することしかできないため、複数のコントローラーが共通のビジネス ロジックを共有できなくなります。ビジネス ロジックをアップグレードする必要がある場合は、ソース コードを直接変更する必要があります。互換性により、コントローラーのコードはますます複雑になります。

サービス層の役割:
 サービスはビジネス層であり、1 つ以上のモデルを使用して操作を実行する方法です。
      1: いくつかの一般的なビジネス ロジックをカプセル化します。
      2: データ層と対話します。
     3: その他の要求: リモート サービス データの取得など。

したがって、コントローラーがモデル構築の呼び出しとビューの処理に集中できるように、モデルを呼び出すビジネス モデルを構築する必要があります。

package com.ck.fruit.biz.impl;
import com.ck.dao.FruitDAO;
import com.ck.fruit.biz.FruitService;
import com.ck.fruit.pojo.Fruit;
import java.util.List;
public class FruitServiceImpl implements FruitService {
    
    
    FruitDAO fruitDAO=null;
    @Override
    public List<Fruit> getFruitList(String keyword, Integer pageNo) {
    
    
        return  fruitDAO.getFruitList(keyword,pageNo);
    }
    @Override
    public void addFruit(Fruit fruit) {
    
    
        fruitDAO.addFruit(fruit);
    }
    @Override
    public Fruit getFruitById(Integer fid) {
    
    
        return fruitDAO.getFruitByFid(fid);
    }
    @Override
    public void delFruit(Integer fid) {
    
    
        fruitDAO.deleteFruit(fid);
    }
    @Override
    public Integer getPageCount(String keyword) {
    
    
        Integer fruitCount=fruitDAO.countNum(keyword);
        Integer pageCount=(fruitCount+5-1)/5;
        return pageCount;
    }
    @Override
    public void updateFruit(Fruit fruit) {
    
    
        fruitDAO.updateFruit(fruit);
    }
}

上記のモデルを構築したら、コントローラー上でビジネスコールを行うだけでよく、fruitDAOのメソッドを直接呼び出す必要はありません。
ここに画像の説明を挿入します
ここに画像の説明を挿入します
  サービス層は DAO 層の上に構築されます。サービス層は DAO 層が確立された後でのみ確立できます。サービス層はコントローラー層の下にあります。したがって、サービス層は DAO 層のインターフェイスを呼び出すだけでなく、また、呼び出しを行うためのコントローラー層クラスへのインターフェイスも提供します。これはたまたま中間層にあります。各モデルには Service インターフェイスがあり、各インターフェイスは独自のビジネス処理メソッドをカプセル化します。

IOC

  MVC の包括的なデザイン パターンを採用します。MVC 自体はデザイン パターンの一種ではありません。デカップリングという最終的な目標を持つ構造を記述します。デカップリングとは、コードの特定の層を変更しても、コードの他の層には影響を与えないことを意味します。 Spring のようなフレームワークを知っていれば、プレゼンテーション層がコントロール層を呼び出し、コントロール層がビジネス層を呼び出し、ビジネス層がデータ アクセス層を呼び出す、インターフェイス指向プログラミングを理解できるようになります。初期段階では、次の層を呼び出すために新しいオブジェクトが使用される可能性があります。たとえば、ビジネス層で新しい DAO クラス オブジェクトを作成し、DAO クラス メソッドを呼び出してデータベースにアクセスする場合、ビジネス層は次の層を呼び出す必要があるため、これは間違っています。特定のオブジェクトは含まれません。存在できるのは参照のみです。特定のオブジェクトが存在する場合、それは結合されます。したがって、レイヤ間のデカップリングを達成する必要があり、IOC はこの要件を達成できます。

概念的な理解

  1. 結合/依存関係
    依存関係とは、何かを何かから分離できないことを意味し、
    ソフトウェア システムでは層間に依存関係が存在します。これをカップリングとも呼びます。
    当社のシステム アーキテクチャまたは設計の原則の 1 つは、高い凝集性と低い結合性です。
    層内の組成は高度に凝集しており、層間の関係は低結合である必要があり、理想的な状態は結合 0 (つまり、結合がない) です。
  2. IOC - コントロールの反転/DI - 依存関係の注入
    コントロールの反転:
    1) 前のプロジェクトの ControllerServlet で、サービス オブジェクト、FruitService Fruitservice=new FruitServiceImpl(); を作成しましたが、
    それがサーブレットの特定のメソッドに表示される場合は、この FruitService のスコープ (ライフサイクル) はメソッド レベルです。
    これがサーブレット クラスに出現する場合、つまり、fruitService がメンバー変数である場合、この FruitService のスコープはサーブレット インスタンス レベルになります。
    2) その後、applicationContext.xml で FruitService を定義し、XML を解析して FruitService インスタンスを生成し、beanMap に格納しました。この beanMap は、beanFactory クラス内の他のクラスのインスタンスを生成します。そのため、以前のサービスインスタンスやDAOインスタンスなどのライフサイクルを移行(変更)しました。制御はプログラマから BeanFactory に移されます。この現象を制御の反転といいます。

    依存関係の注入:
    1. 以前は、制御層に FruitService FruitService=new FruitServiceImpl() というコードがありましたが、制御層とサービス層の間に結合があります。2. その後、コードを FruitService FruitService=null に変更しました
    。 、次に構成ファイルの構成:
<bean id="fruit" class="com.ck.fruit.controllers.FruitController">
    <property name="fruitService" ref="fruitService"/>
</bean>

このようにして、クラスに必要な依存関係を構成内のプロパティを通じて見つけてインスタンス化できます (これがインジェクション依存関係です)。

制御の反転と依存関係の注入をフルーツ プロジェクト システムに追加する

  1. 元のプロジェクトでは、コントローラー層とサービス層に他の層をインスタンス化して呼び出すクラスがあり、層間の結合依存関係が存在するため、現状の構造を改善する必要があります。
ここに画像の説明を挿入しますここに画像の説明を挿入します

  2. 最初に必要なクラスを null に割り当てます
ここに画像の説明を挿入しますここに画像の説明を挿入します

   3. Beanfactory インターフェイスを確立し、その実装クラスを作成して、XML 構成ファイルに格納されたクラス XML 構成ファイルを格納する MAP コレクションを構築します。各
Bean ノードは各クラスに対応し、 Bean のプロパティ ノードは、Bean によって表されるクラスが依存する必要があるクラスを表し、その後の依存関係の注入に使用されます。
ここに画像の説明を挿入します

  ClassPathXmlApplicationContext クラスは beanFactory インターフェースを実装し、リフレクションを通じて XML 構成ファイル内のすべてのクラスを対応するコレクションにマップします。
ここに画像の説明を挿入します

   XML 内のすべてのクラスをコレクションに挿入した後、Bean 間の依存関係のアセンブルを開始する必要があります。Bean の下のプロパティ サブノードを取得してコレクションから対応するクラス インスタンスを取得し、リフレクション テクノロジを使用してプロパティを追加します。対応するクラスの代入、依存関係の注入。
ここに画像の説明を挿入します
最後にフルーツ システムを実現します。

ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/ccjjjjdff/article/details/129497607