MVCモデルをDBから疎結合にしますか?


9

私はコードをテスト可能な状態に保ち、現在のMVCフレームワークの依存性注入戦略を採用することを決定しました。

しかし、デザインパターンのマスターとはほど遠いので、モデルをデータベースコネクタクラスから可能な限り疎結合に保つための適切な方法を理解するのに苦労しています。

これはどのように行うことができますか?
この質問では物理的なコードを提供していなかったので、上記の問題を理解する方向に私を導くことができるいくつかのロジック/コードの例または情報に本当に感謝します。


この問題はソフトウェアエンジニアリングに属します。これは、コードでの実装よりも、このトピックに関する構造化と思考に関するものであるためです。
Lasse V. Karlsen、2011

回答:


6

1つの方法は、データベースを設計する前にモデルを設計することです。モデルを設計する際の焦点は、問題ドメイン内のビジネスロジックと意味を取り込むことです。これは、エンティティとデータフィールドだけでなく、ビジネスにとって意味のある方法でキャプチャする必要があります。一部のデータ要素は他の要素から解釈され、一部は他の要素に依存します。さらに、特定の要素が特定の値に設定されたときのオブジェクトの内部応答など、必要な基本ロジックをこのモデルに追加します。

最終的には、データを永続化する方法と90%以上同じになる可能性があります。それはいいです。結合しなくても完全に同一にすることができます。

真の永続性の無知の霧の中でドメインをモデル化することは、ソフトウェア設計にとってちょっとした聖杯であることにも注意してください。できれば素晴らしいです。ただし、問題のドメインがまったく重要で複雑な場合は、データの永続性の健全性チェックを行って、ペイントしていないことを確認するために、時々ドメインモデリングから後退することをお勧めします。コーナーに自分自身。

さまざまなコンポーネントの実際の役割を覚えて、設計時にそれらの役割を分離してください。与えられた設計上の決定について、それらの役割のいずれかに違反していないかどうかを自問してください。

  1. データベース-データを保存し、データの整合性を維持し、データを保存します。
  2. モデル-ビジネスロジックを含み、問題ドメインをモデル化し、動いているデータを維持し、ビジネスレベルのイベントに応答します。
  3. ビュー-ユーザーにデータを提示し、ユーザー側のロジックを実行します(モデルで実際の検証が実行される前の基本的な検証など)。
  4. コントローラー-ユーザーイベントに応答し、モデルに制御を渡し、要求をルーティングし、応答を返します。

こんにちはデビッド。たくさんのご返信ありがとうございます!高レベルの疎結合を維持しながら、モデルをデータベースコネクタにどのように接続しますか?
インダストリアル

1
@Industrial:モデルを永続化に接続する方法はいくつかありますが、これまでのところ、懸念事項を分離したいという私の欲求を完全に満たす唯一の方法は、DALによって外部で実装されるドメインにリポジトリインターフェイスを持つことです。リポジトリメソッドは、ドメインモデルを受け入れて返し、それらと生成されたデータベースエンティティの間で内部的に変換します。(正直なところ、私はPHPでこれほど多くのことを行っていません。)したがって、DALフレームワークを使用してすべてのDB CRUDなどを自動生成し、そのものとモデルの間のインターフェースとしてリポジトリを書き込むことができます。
デビッド

@Industrial:たとえば、ORMを使用する場合、そのORMはDAL(ドメインモデルから分離されている)によって参照され、それに応じてモデルをデータアクセスに変換します。または、手動SQLで直接データベースアクセスを行う場合は、DALのリポジトリメソッドでそれを行い、SQLクエリの結果を返す前にSQLモデルの結果をドメインモデルに変換します。
デビッド

@Industrial:リポジトリメソッドはCRUDでなくてもかまいません。そのコードに多くのインテリジェンスを組み込むことができます。より複雑なものの多くは、データベースからデータを変換する内部コードをたくさん持つことができます。または、複雑なものにデータベースへの多くのトリップが含まれる場合は、パフォーマンスを向上させるためにロジックをストアドプロシージャに配置し、DALメソッドがそのプロシージャに渡され、結果をモデルに変換するだけです。
デビッド

こんにちはデビッド!この回答をありがとうございました。間違いなく、私がStackExchangeで受け取った最高のものの1つです。
インダストリアル

2

あなたは二つのものを持ちたいです。

  1. モデル(DBALへのアクセサーとアプリロジックのほとんどを実行します)。
  2. 「ドメインモデル」またはデータエンティティ。これらは、ユーザー、投稿、製品など、システムのエンティティを表します。

    class PPI_Model_User {
    
        protected $_conn = null;
    
        function __construct(array $options = array()) {
            if(isset($options['dsnData'])) {
                $this->_conn = new PPI_DataSource_PDO($options['dsnData']);
            }
        }
    
        function getAll() {
            $rows = $this->_connect->query("SELECT .....")->fetchAll();
            $users = array();
            foreach($rows as $row) {
                $users[] = new PPI_Entity_User($row);
            }
            return $users;
        }
    
    }

使用法コード

    $model = new PPI_Model_User(array('dsnData' => $dsnData));
    $users = $model->getAll();
    foreach($users as $user) {
        echo $user->getFirstName();
    }

これでドメインモデル(エンティティ)を作成し、MVCモデルでDB接続とデータ操作を行うことができます。

PPIが何であるか疑問に思っている場合は、「PPIフレームワーク」で検索してください。

検索で頑張ってください。

よろしく、ポールDragoonis。


1

MVCはすべてのオブジェクトに対して自動的に永続化されるsmalltalkで発生したことを覚えておいてください。したがって、MVCパターンはモデルと永続性の分離のソリューションを規定していません。

私の好みは、データベースからモデルオブジェクトを作成し、データベースにモデルオブジェクトを格納する方法を知っている「リポジトリ」オブジェクトを提供することです。次に、モデルは永続性について何も知りません。ただし、一部のユーザーアクションでは保存をトリガーする必要があるため、コントローラーがリポジトリーを認識している可能性があります。私は通常、何らかの形の依存性注入を使用して、コントローラがリポジトリに結合されないようにします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.