94

私のチームにアダプタパターンの使用法を示したいと思います。私はオンラインでたくさんの本や記事を読みました。誰もが概念を理解するのに役立つ例(形状、メモリーカード、電子アダプターなど)を引用していますが、実際のケーススタディはありません。

アダプタパターンのケーススタディを教えてください。

ps stackoverflowで既存の質問を検索しようとしましたが、答えが見つからなかったため、新しい質問として投稿しました。これに対する答えがすでにあることがわかっている場合は、リダイレクトしてください。

4

15 に答える 15

79

Adapter の多くの例は、自明または非現実的です ( Rectangle と LegacyRectangle、Ratchet と SocketSquarePeg と RoundPegDuck と Turkey )。さらに悪いことに、多くの場合、異なるアダプティーに対して複数のアダプターが表示されません(アダプター パターンの例として Java の Arrays.asList を引用した人もいます)。1 つのクラスだけのインターフェイスを別のクラスで動作するように適合させることは、GoF アダプター パターンの弱い例のように思えます。このパターンは継承とポリモーフィズムを使用するため、さまざまなアダプティーのアダプターの複数の実装を示す良い例が期待されます。

私が見つけた最良の例は、 Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition)の第 26 章にあります。次の画像は、本の FTP サイトで提供されているインストラクターの資料からのものです。

最初のものは、アプリケーションが機能的に似ている複数の実装 (アダプティー) を使用する方法を示しています (税計算機、会計モジュール、信用認証サービスなど) が、API は異なります。税金を計算したり、売上を計上したり、クレジット カードのリクエストを承認したりするためのさまざまな方法を処理するために、ドメイン レイヤー コードをハードコーディングすることは避けたいと考えています。これらはすべて、異なる可能性がある外部モジュールであり、コード。アダプターを使用すると、アダプターでハード コーディングを行うことができますが、ドメイン層のコードは常に同じインターフェイス (IWhateverAdapter インターフェイス) を使用します。

図 26.1

上の図には、実際のアダプティが表示されていません。ただし、次の図はpostSale(...)、IAccountingAdapter インターフェースでポリモーフィック呼び出しが行われる方法を示しています。これにより、SOAP を介して SAP システムに販売が転記されます。

図 26.2

于 2012-11-10T16:19:53.890 に答える
53

フランス人を普通の人に変える方法...

 public interface IPerson
    {
        string Name { get; set; }
    }

    public interface IFrenchPerson
    {
        string Nom { get; set; }
    }

    public class Person : IPerson
    {
        public string Name { get; set; }
    }

    public class FrenchPerson : IFrenchPerson
    {
        public string Nom { get; set; }
    }

    // that is a service that we want to use with our French person
    // we cannot or don't want to change the service contract
    // therefore we need 'l'Adaptateur'
    public class PersonService
    {
        public void PrintName(IPerson person)
        {
            Debug.Write(person.Name);
        }
    }

    public class FrenchPersonAdapter : IPerson
    {
        private readonly IFrenchPerson frenchPerson;

        public FrenchPersonAdapter(IFrenchPerson frenchPerson)
        {
            this.frenchPerson = frenchPerson;
        }

        public string Name 
        {
            get { return frenchPerson.Nom; }
            set { frenchPerson.Nom = value; }
        }
    } 

    var service = new PersonService();
    var person = new Person();
    var frenchPerson = new FrenchPerson();

    service.PrintName(person);
    service.PrintName(new FrenchPersonAdapter(frenchPerson));
于 2015-08-27T14:15:09.643 に答える
5

アダプターの設計パターンは、あるクラスのインターフェースをクライアントが期待するインターフェースに変換するのに役立ちます。

例: 入力値として都市名を渡して天気 (摂氏) を返すサービスがあります。ここで、クライアントが郵便番号を入力として渡し、その見返りに都市の気温を期待しているとします。ここでは、これを実現するためのアダプターが必要です。

public interface IWetherFinder {
    public double getTemperature(String cityName);
}

class WeatherFinder implements IWetherFinder{
   @Override
   public double getTemperature(String cityName){
     return 40;
   }
}

interface IWeatherFinderClient
{
   public double getTemperature(String zipcode);
}  

public class WeatherAdapter implements IWeatherFinderClient {

    @Override
    public double getTemperature(String zipcode) {

        //method to get cityname by zipcode 
        String cityName = getCityName(zipcode);

        //invoke actual service
        IWetherFinder wetherFinder = new WeatherFinder();
        return wetherFinder.getTemperature(cityName);
    }

    private String getCityName(String zipCode) {
        return "Banaglore";
    }
}
于 2019-11-14T12:42:16.397 に答える
2

変更できないが使用する必要があるインターフェイスがある場合は、Adapter を使用します。あなたはオフィスの新しい男であり、白髪をあなたのルールに従わせることはできません.あなたは彼らのルールに適応しなければなりません. これは、私がいつか取り組んだ実際のプロジェクトからの実際の例で、ユーザー インターフェイスが与えられています。

ファイル内のすべての行を List データ構造に読み取り、それらをグリッドに表示するアプリケーションがあります (基になるデータ ストア インターフェイス IDataStore を呼び出しましょう)。ユーザーは、「最初のページ」、「前のページ」、「次のページ」、「最後のページ」のボタンをクリックして、これらのデータをナビゲートできます。すべて正常に動作します。

ここで、メモリに読み込むには大きすぎる運用ログでアプリケーションを使用する必要がありますが、ユーザーは引き続きログをナビゲートする必要があります。1 つの解決策は、最初のページ、次のページ、前のページ、および最後のページを格納するキャッシュを実装することです。ユーザーが「次のページ」をクリックすると、キャッシュからページが返され、キャッシュが更新されます。最後のページをクリックすると、キャッシュから最後のページが返されます。バックグラウンドでは、すべての魔法を実行するファイルストリームがあります。そうすることで、ファイル全体ではなく、メモリ内に 4 ページしかありません。

アダプターを使用すると、ユーザーが気付かないうちに、この新しいキャッシュ機能をアプリケーションに追加できます。現在の IDataStore を拡張し、それを CacheDataStore と呼びます。ロードするファイルが大きい場合は、CacheDataStore を使用します。First、Next、Previous、および Last ページのリクエストを行うと、情報はキャッシュにルーティングされます。

明日、上司はデータベース テーブルからファイルの読み取りを開始したいと考えています。キャッシュの場合と同様に IDataStore を SQLDataStore に拡張し、バックグラウンドで接続をセットアップするだけです。[次のページ] をクリックすると、データベースから次の数百行を取得するために必要な SQL クエリが生成されます。

基本的に、アプリケーションの元のインターフェイスは変更されていません。従来のインターフェースを維持しながら、モダンでクールな機能を単純に適応させました。

于 2015-12-14T01:46:05.640 に答える
2

実際の例の 1 つは Qt-Dbus です。

qt-dbus には、提供された xml ファイルからアダプターとインターフェースのコードを生成するためのユーティリティーがあります。これを行う手順は次のとおりです。

 1. Create the xml file - this xml file should have the interfaces 
that can be viewed by the qdbus-view in the system either on 
the system or session bus.

    2.With the utility - qdbusxml2cpp , you generate the interface adaptor code. 
This interface adaptor does the demarshalling of the data that is 
received from the client. After demarshalling, it invokes the 
user defined - custom methods ( we can say as adaptee).

    3. At the client side, we generate the interface from the xml file. 
This interface is invoked by the client. The interface does the 
marshalling of the data and invokes the adaptor interface. As told 
in the point number 2, the adaptor interface does the demarshalling 
and calls the adaptee - user defined methods.

ここで Qt-Dbus の完全な例を見ることができます -

http://www.tune2wizard.com/linux-qt-signals-and-slots-qt-d-bus/

于 2014-12-09T09:38:20.680 に答える
-1

実際の例は、アプリケーション内のレポート ドキュメントです。ここのような単純なコード。

アダプターは、構造のプログラミングに非常に役立つと思います。

class WordAdaptee implements IReport{
    public void report(String s) {
        System.out.println(s +" Word");
    }
}

class ExcellAdaptee implements IReport{
    public void report(String s) {
        System.out.println(s +" Excel");
    }
}


class ReportAdapter implements IReport{
    WordAdaptee wordAdaptee=new WordAdaptee();
    @Override
    public void report(String s) {
        wordAdaptee.report(s);
    }
}

interface IReport {
    public void report(String s);
}

public class Main {
    public static void main(String[] args) {

        //create the interface that client wants
        IReport iReport=new ReportAdapter();

        //we want to write a report both from excel and world
        iReport.report("Trial report1 with one adaptee");  //we can directly write the report if one adaptee is avaliable 

        //assume there are N adaptees so it is like in our example
        IReport[] iReport2={new ExcellAdaptee(),new WordAdaptee()};

        //here we can use Polymorphism here  
        for (int i = 0; i < iReport2.length; i++) {
            iReport2[i].report("Trial report 2");
        }
    }
}

結果は次のようになります。

Trial report1 with one adaptee Word
Trial report 2 Excel
Trial report 2 Word
于 2014-11-17T12:33:34.457 に答える