1

アップデート:

いくつかの更新があります。最終的にフレームワーク (Yii) を決定し、いくつかの初期構造を用意しました。現在のステータスを説明するために、いくつかの関連コードを貼り付けます: (ここでは読み取りアクションのみ)

コントローラ

class SponsorController extends RestController
{
    public function actionRestView($id)
    {
        $sponsorMapper = new SponsorMapper(
            new Db1Adapter(), // Gateway to the external SOAP Webservice
            new Db2Adapter()  // Gateway to the external REST Webservice
        );

        $data = $sponsorMapper->read($id);

        $this->renderJson(
            array(
                'success' => true,
                'message' => 'Record Retrieved Successfully',
                'data' => $data
            )
        );
    }
}

ドメイン モデル

class Sponsor extends CModel
{
    public $id;
    public $db1Result;
    public $db2Result;

    public function attributeNames()
    {
        return array(
            'id',
            'db1Result',
            'db2Result',
        );
    }
}

データマッパー

class SponsorMapper extends Mapper
{
    public function __construct(SoapAdapter $db1Adapter,
                                RestAdapter $db2Adapter)
    {
        $this->adapters['soap'] = $db1Adapter;
        $this->adapters['rest'] = $db2Adapter;
    }

    public function read($id)
    {
        $db1Result = $this->adapters['soap']->demoRequest();
        $db2Result = $this->adapters['rest']->demoRequest();

        return $this->createEntity($db1Result, $db2Result);
    }

    protected function createEntity($db1Result, $db2Result)
    {
        $sponsor = new Sponsor();
        $sponsor->db1Result = $db1Result;
        $sponsor->db2Result = $db2Result;

        return $sponsor;
    }
}

今、私は2つの質問があります:

  1. 現在、Sponsor オブジェクトのプロパティは db1Result と db2Result だけですが、これを実際のプロパティ (例: firstName、lastName、email) に変更するので、SponsorMapper::createEntity は次のようになります。

    protected function createEntity($db1Result, $db2Result)
    {
        $sponsor = new Sponsor();
        $sponsor->firstName = $db1Result->result->first_name;
        $sponsor->lastName = $db1Result->result->last_name;
        $sponsor->email = $db2Result->QueryResult->ItemObject->email;
    
        return $sponsor;
    }
    

これらの種類のものは、マッパーではなくドメイン オブジェクト内で発生する必要があるように思えます。db1Result と db2Result を独自のドメイン オブジェクトとして扱い、スポンサー ドメイン オブジェクトとの関係を作成できることはわかっていますが、それが正しい方向であるかどうかはわかりません。マッパーでやるべきですか?

  1. 外部データベースからデータを取得するのは高速ではないため、キャッシング レイヤーを導入する必要があります。キャッシングレイヤーを導入するのに最適な場所/プラクティスはどこですか? これを行う 1 つの方法はコントローラー内にあるため、コード キャッシング レイヤーを別のマッパーとして使用します。このキャッシュ マッパーがデータを返さない場合は、外部からデータを取得するために長い道のりを行くことができます。しかし、この解決策は、これらすべてのロジックをコントローラー アクション全体に配置する必要があることを意味します。キャッシュ レイヤーを配置するためのより良い方法があるのではないでしょうか?

最初の質問:

PHP MVC フレームワーク上で RESTFul API プロジェクトを設計/作成中です。プロジェクトの目標は、他の 2 つの「外部」API (1 つは SOAP、もう 1 つは REST) 間のアダプターとして機能することです。

このプロジェクトのモデルは、大まかに次のように機能するはずだと考えています。

  • それぞれの API の背後にある「外部」データベースの両方にユーザー データのコレクションがあり、ローカルでモデル「ユーザー」を作成するとします。
  • 「User」モデル内に「GetById」メソッドがあるとします。このメソッドは、次のことを行う必要があります。両方の外部 API から ID でユーザー データを取得し、結合して結果を返します。
  • おそらく、「ユーザー」モデル内でビルダー パターンを使用して、他の 2 つのモデル (外部 API ごとに) をインスタンス化し、それらの 2 つのモデルにデータを取得するように依頼します。この構造により、2 つの追加モデルが API との通信に必要なものを継承できるようになります。
  • したがって、これらのモデルがあります。

    1. ユーザー
    2. SOAPビルダー
    3. RESTビルダー
    4. ユーザーSOAP
    5. ユーザーREST

この設計で気に入らないのは、構造が少し複雑で、モデル ファイルを「タイプ」(ユーザー モデル自体、ビルダー モデルなど)。

私はこれを過度に設計していますか?考慮すべきより良いパターンはありますか?

4

1 に答える 1

1

MVC には「複数のモデル」はありません。モデルは、MVC デザイン パターンを構成する 2 つのレイヤー (プレゼンテーション レイヤーと共に) の 1 つです。通常「モデル」と呼ばれるものは、実際にはドメイン オブジェクトですこれは関連性があると思うかもしれません。

そうは言っても、あなたはこれをすべて間違った方法で見ています。現在持っているのは、アクティブなレコードパターンのバリエーションです。データベースの代わりに、この場合のストレージ メディアは、従来の SQL ストレージではなく、REST API および/または SOAP インターフェイスです。

この場合の最適なオプションは、ドメイン オブジェクト (例: User) をストレージ関連ロジックのさまざまな要素から分離することです。個人的には、このためにデータマッパーを実装することを好みます。基本的に、ドメイン オブジェクトがある場合は、それをマッパーのメソッドに渡します。マッパーのメソッドは、そのオブジェクトから情報を取得してストレージに送信するか、ストレージからデータを取得してそのドメイン オブジェクトに適用します。

インスタンスは、User保存されたかどうかは気にしません。ドメイン ロジックには影響しません。

于 2012-08-18T04:25:37.527 に答える