1

他のモデルを参照するモデルを検証する際に問題が発生しています。

「ユーザー」モデルと「プロファイル」モデルがあります。プロファイルを作成したいのですが、ユーザーが実際に存在するかどうかを確認する必要があります。

私のプロファイル モデルにはメソッド「validateUser」がありますが、データベース内の特定のテーブルにクエリを記述するか、ユーザー モデル オブジェクトを作成して exists(id) を呼び出す必要があります。

どちらのオプションにも多くの欠点があるようです。テーブル名は変更される可能性があり、それを使用するすべてのモデルを調べる必要があります。ユーザー モード オブジェクトでは、プロファイル モデル内にオブジェクトを作成するか、オブジェクトを挿入する必要があります。

これにアプローチする最良の方法は何ですか?

4

1 に答える 1

1

運命の領域..

実際の状況では、検証が単純なプロセスになることはめったにありません。代わりに、いくつかの無関係な懸念があります。

  • インスタンス内のデータがビジネス ルールと一致しているかどうかを確認する
  • インスタンスの状態が他のドメイン構造と競合していないことを確認する
  • ストレージ内の既存のデータおよび制約に対する情報の整合性の検証

ドメイン モデル を表すためにアクティブ レコードを使用している場合(MVC の M と混同しないでください)、これら 3 つの側面すべてが単一のオブジェクトの責任になります。

それはあなたが今持っているものです。

しかし、希望があります..

最善の選択肢は、これらすべての責任を分離することです(すべて Hail SRP )。基本的に行うことは、現在のセットアップを 3 つの異なる構造グループに分割することです。

  • ドメイン オブジェクト: ドメイン エンティティの特定のルールを処理するため

  • データ マッパー: ストレージの抽象化用

  • サービス: ドメイン オブジェクトとマッパー (または他のドメイン オブジェクト) 間の対話用

あなたの質問はやや混乱していたので(ユーザーとプロファイル、保存と検証、そして何かがそこにありませんでした)、私がそれを正しく理解したかどうかはわかりませんが、ここに小さな例があります:

public function createProfile( $id, $email, $name )
{
    $account = new Account;
    $account->setId( $id );

    $accountMapper = new AccountMapper( $pdo ); // explained below

    if ( $accountMapper->fetch( $account ) === false )
    {
        $this->errors[] = .. something about missing account
        return;
    }

    $profile = new Profile;
    $profile->setEmail( $email )
            ->setName( $name );

    if ( $profile->isValid() === false )
    {
        $this->errors[] = .. something about invalid profile
        return;
    }
    
    try
    {
        $profileMapper = new ProfileMapper( $pdo ); // explained below
        $profileMapper->store( $profile );
    }
    catch ( Exception $e )
    {
        $this->errrors[] = .. something about failing to create profile
        return;
    }

    $account->addProfile( $profile );
    $accountMapper->store( $account );
}

これは非常に単純化された例です。特にマッパーが初期化される場所では、実際の状況ではその部分が一部のファクトリによって処理されるためです。この投稿で説明されているようなものです。

ここでのポイントは、ドメイン データの検証と DB の整合性の保証が別々に行われることです。データベースと対話するための基礎となる API は、実際にエラー コードを返します。これは、違反したUNIQUE KEY場合FOREIGN KEYやその他の制約であり、これを使用して何が問題なのかを判断できます。

メソッド自体はサービスの一部になります (この場合、ユーザー アカウントを管理するサービス)。

注:アプリケーションが操作ごとに複数の SQL 対話を実行する必要があり、それらの対話をロールバックを実行できるトランザクションとして実行する必要がある場合は、データ マッパーを直接使用する代わりに、Units of Work の実装を検討する必要があります。UoW について学ぶには、エンタープライズ アプリケーション アーキテクチャのパターンを読む必要があります。

于 2013-09-11T21:44:35.447 に答える