web-dev-qa-db-ja.com

サービスをラップして簡単にする方法

私たちは、3つのメソッドのように必要なだけの巨大なインターフェースを公開するサードパーティのサービスに依存しています。さらに、インターフェースは頻繁に変更されます...

インターフェースをプロジェクトのクラスにラップし、必要なメソッドのみを公開することにしました。

しかし、戻り値の処理方法がわかりません...インターフェイスは、Storage型のオブジェクトを返します。内部には、StorageModelの内部表現であるStorage型があります。

マッパーで何を返しますか:StorageまたはStorageModel?挿入されたラッパーの依存関係を取得するDataService StorageServiceがあります。

現在、私は基本的に次のようにしています:

public class StorageService 
{
    private readonly IExternalStorageWrapper externalStorageWrapper;

    public StorageService(IExternalStorageWrapper externalStorageWrapper)
    {
        this.externalStorageWrapper = externalStorageWrapper;
    }

    public StorageModel GetStorage(int storageId)
    {
        return this.externalStorageWrapper.GetStorage(storageId).ConvertToStorageModel();
    }
}

public class ExternalStorageWrapper : IExternalStorageWrapper
{
    public Storage GetStorage(int storageId)
    {
        using(var ext = new ExternalStorage())
        {
            return ext.GetStorage(storageId);
        }
    }
}

あなたは何と言うでしょう:

  • 上記のように、ラッパーが外部Storageオブジェクトを返し、内部StorageServiceが内部StorageModelを返すのは良いことですか?
  • または、ラッパーですでにStorageModelを返しますか?
11
xeraphim

私の意見では、ラッパーは外部ライブラリに関連するすべてのものを処理する必要があります。これは、Wrapperのパブリックインターフェースが外部型を指定してはならないことを意味します。

外部型をアプリケーションのそれぞれの型にマッピングすることは、ラッパーの役割の一部です。これが簡単な操作でない場合は、問題を分解するために使用できるさまざまなツールを使用できます。トランスレータオブジェクトを挿入します。ただし、トランスレータは引き続きラッパーモジュールの一部である必要があり、アプリケーションの他の部分がこれに依存することはできません。

このようにして、アプリケーションの残りの部分は、ライブラリの変更だけでなく、ライブラリを別のライブラリに置き換えても完全に影響を受けません。

11
doubleYou

プロジェクトのクラスにインターフェイスをラップし、必要なメソッドのみを公開することにしました。

それで大丈夫です。これは Adapter とも呼ばれます。

Adapterパターンを選択するので、ここでの目的はtransformingoneinterfaceです(ライブラリモデル)を別の(ドメインモデル)に変換します。したがって、前者の何かがドメインモデルに到達した場合、 アダプタはその目的に失敗しています です。

前述の引数によれば、アダプターはStorageModelを返すはずです。

最終的に、ドメインは特定の言語を「話します」。ここで、Storage見知らぬ人です。

しかし、私は戻り値をどのように処理するべきかわかりません...

ここで重要なのは、どのような理由でラッピング/適応ライブラリを使用するかを知ることです

アダプター、デコレーター、ファサードのパターンには類似点があるかもしれませんが、かなり異なります。彼らが解決する問題と同じくらい異なります。

とはいえ、あなたも興味があるかもしれません:

3
Laiv

ライブラリを複製して効果的にラップすることはできません。

ラップする必要があるのは、ライブラリの使用法です。つまり、オブジェクト、この場合はストレージを公開しないことです。それらを複製しようとしないでください。

ライブラリを使用してください。したがって、あなたの場合、StorageServiceを使用して物事を保存すると仮定すると、リポジトリにラップする必要があります

MyPocoObjectRepo
    MyPocoObject GetObject(string id);

ここで、MyPocoObjectは完全にデータとビジネスロジックです。 StorageやDataReaderなどの複製ではない

1
Ewan

答えは、StorageではないクラスからStorageModelに直接アクセスする必要があるかどうかに依存するということです。

ライブラリをラップする場合は、ライブラリによって返されたオブジェクトをラップして、将来ライブラリによって行われる将来の変更を証明できるようにすることは理にかなっています。ただし、Storageを直接使用する必要がある場合は、状況に応じてStorageを返す必要があるmayがあることを意味します。プログラム全体で一貫性を保ちたいので、ここでStorageの使用をStorageModelにする義務があるとする議論はあり得ます。

まだ行っていない場合は、インターフェイスと返されたオブジェクトの両方をラップすることを強くお勧めします。ただし、これは、プログラム全体でStorageModelのみを使用し、Storage

0
Neil