8

3 つの永続化レイヤーに書き込む必要があるシステムを PHP で作成しています。

  • 1 つの Web サービス
  • 2 つのデータベース (1 つの mysql と 1 つの mssql)

この理由はレガシー システムであり、変更することはできません。

DataMapper パターンを使用したいと考えており、目的を達成するための最良の方法を確立しようとしています。次のようなインターフェースがあります。

<?php
    $service = $factory->getService()->create($entity);
?>

以下は、簡潔にするためにいくつかの工夫された短縮されたコードです。

<?php
class Post extends AbstractService
{
    protected $_mapper;

    public function create(Entity $post)
    {
        return $this->_mapper->create($post);
    }
}

class AbstractMapper
{
    protected $_persistence;

    public function create(Entity $entity)
    {
        $data = $this->_prepareForPersistence($entity);
        return $this->_persistence->create($data);
    }   
}
?>

私の質問は、永続化レイヤーが 3 つあるため、それぞれに 3 つのマッパーが必要になる可能性が高いということです。これを機能させるには、クリーンなデザイン パターンにインスパイアされたインターフェイスが必要です。

次の 3 つのオプションがあると思います。

  1. 3 つのマッパーを Service に挿入し、それぞれで create を呼び出します
  2. $_mapper は配列/コレクションであり、それぞれに対して create を呼び出して反復します
  3. $_mapper は実際には、さらなるプロキシとして機能し、それぞれに対して create を呼び出すコンテナ オブジェクトです。

これらのソリューションのそれぞれに何か問題があると思います。これに適合する可能性のあるフィードバック/認識された設計パターンをいただければ幸いです。

4

3 に答える 3

2

私は同様の問題を解決しなければなりませんでしたが、何年も前の PEAR DB の時代です。その特定のケースでは、複数のデータベース間でデータを複製する必要がありました。

異なるデータベースが異なるマッピングを持つという問題はありませんでしたが、かなり単純でした。

私たちが行ったことは、DB クラスをファサード化し、getResult 関数 (またはそれが呼び出されたもの) をオーバーライドすることでした。次に、この関数は SQL を分析し、それが読み取りの場合は 1 つだけに送信し、書き込みの場合はすべてに送信します。

これは実際、非常に頻繁に使用されるサイトで非常にうまく機能しました。

その背景から、すべての永続化操作を完全にファサード化することをお勧めします。これを行うと、実装の詳細は関連性が低くなり、いつでも変更できます。

この観点から、実装のアイデアはどれも妥当なアプローチのように思えます。とはいえ、考えてもらいたいことはいろいろあります。

  • バックエンドの 1 つがエラーをスローした場合はどうなりますか?
  • 3 台のデータベース サーバーへの書き込みによるパフォーマンスへの影響は?
  • 非同期で書き込みを行うことはできますか (そうであれば、最初の質問をもう一度尋ねてください)。

この問題を解決する別の方法も考えられます。つまり、ストアド プロシージャを使用します。プライマリ データベース サーバーがある場合は、コミット時 (またはその前後) に他のデータベースに接続してデータを同期するトリガーを作成できます。

データの更新をすぐに行う必要がない場合は、プライマリ データベースに変更を記録させ、このデータを他のシステムに定期的に "フィード" する別のスクリプトを用意することができます。ここでも、エラーの問題を考慮する必要があります。

お役に立てれば。

于 2013-02-24T19:28:17.453 に答える
1

まず、少し用語を説明します。3 つのレイヤーと呼ばれるものは、実際には 3 つのモジュールであり、レイヤーではありません。つまり、永続層内に 3 つのモジュールがあります。

さて、この問題の基本的な前提は次のとおりです。3 つの異なるストレージ ソースに対応する 3 つの異なる永続化ロジックが必要です。これは避けられないことです。したがって、問題は、このモジュールで書き込み操作を呼び出す方法についてです (読み取りの場合、3 つすべてを呼び出す必要はないと仮定します。または、呼び出す場合、それは別の問題です)。

あなたがリストした3つのオプションから、私の意見では最初のオプションが優れています. なぜなら、これは 3 つの中で最も単純だからです。残りの 2 つは、3 つのモジュールを個別に呼び出す必要があり、コンテナーまたは何らかのデータ構造を導入する追加作業が必要です。どこかで 3 つのモジュールを呼び出すことは避けられません。

最初のオプションを使用する場合は、ユーザー/クライアント (この場合はサービス) に統一された抽象化を提供するために、明らかにインターフェイスを使用する必要があります。

私のポイントは次のとおりです。1.それらは問題に固有の複雑さであり、これ以上単純化することはできません。2. 最初のオプションの方が優れています。他の 2 つのオプションを使用すると、物事が単純ではなく、より複雑になるからです。

于 2013-02-28T17:39:29.850 に答える
0

私の意見では、オプション#2が最適だと思います。私はそれで行きます。オプション 3 よりもマッパーが 10 個以上ある場合は、作成ロジックをマッパー自体にシフトするのが理にかなっていますが、妥当な数のマッパーがあるため、それらを注入して反復処理する方が理にかなっています。別のマッパーを追加して機能を拡張するには、依存性注入構成に 1 行追加するだけです。

于 2013-02-27T22:51:56.897 に答える