3

多くのデータ プロバイダー (ブローカー) の 1 つによって/から提供されるデータを持つクライアント側のスイング アプリを作成しています。ただし、データプロバイダーには、同じことを実行するさまざまな方法があります。

broker1 のログイン方法

public boolean doLogin(String username, String password);

broker2 のログイン方法

public int login(String username, String password,String sessionId);

すべてのプロバイダーで、一連の必要なアクションは同じです。

login、getstatus、sendRequest、getData、logOff
(ただし、params と戻り値の型は異なります)

アダプターのパターンを見てみましたが、必要なメソッドのパラメーターが異なるため、残念ながらうまく使用できません。

この場合、アダプターパターンは使用できますか? もしそうならどのように?
そうでない場合、これを行う最良の方法は何ですか?

ありがとう。

4

2 に答える 2

4

パターンは、ベスト プラクティスの一般的なガイドライン (出発点) です。多くの開発者は、ニーズに合わせてパターンを「適応」させています。重要なことは、パターンを使用する必要がある場合は、アプリケーション全体で一貫して使用することです。

さて、あなたの質問に答えます。はい、アダプターパターンはあなたの状況で非常にうまく使用できます。可能な解決策(同様の)は次のとおりです。

abstract class BrokerAbstract<T> {
   private int errCode;
   private String errMessage;

   abstract public boolean login(String user, String pass, Map<String,Object> options);
   abstract public int getStatus(Map<String,Object> options);
   abstract public boolean sendRequest(Map<String,Object> options);
   abstract public T getData(Map<String,Object> options);
   abstract public boolean logOff(Map<String,Object> options);

   protected void setError(int code, String message) {
      this.errCode = code;
      this.errMessage = message;
   }

   public int getErrorCode() { return this.errCode; }
   public String getErrorMessage() { return this.errMessage; }
}

それで

class Broker1 extends BrokerAbstract<Object> {
   private OriginalBroker1 original;       

   public boolean login(String user, String pass, Map<String,Object> options) {
      return original.doLogin(user, pass);  // ignore options
   }
   public boolean login(String user, String pass) {
      return login(user, pass, null);  // third parameters will be ignored
   }
   public int getStatus(Map<String,Object> options) { /*...*/ return 0; }
   public boolean sendRequest(Map<String,Object> options) { /*...*/ return false; }
   public Object getData(Map<String,Object> options) { 
      return original.getData();  // OriginalBroker1.getData():Object
   }
   public boolean logOff(Map<String,Object> options) {
      return original.doLogout((boolean) options.get("clearSession"));
   }
   public boolean logoff() {
      HashMap<String,Object> options = new HashMap<String,Object>();
      options.put("clearSession", true);
      return logoff(options);   // proxy to original method
   }
}

または

class Broker2 extends BrokerAbstract<Integer> {
   private OriginalBroker2 original;       

   public boolean login(String user, String pass, Map<String,Object> options) {
      int code = original.doLogin(user, pass, (String) options.get("sessionId"));
      if (0 != code) {
          setError(code, "Custom error message"); // could use enum here for messages...
          return false;
      } else {
          return true;
      }
   }
   public boolean login(String user, String pass, String sessionId) {
      HashMap<String,Object> options = new HashMap<String,Object>();
      options.put("sessionId", sessionId);
      return login(user, pass, options);
   }
   public int getStatus(Map<String,Object> options) { /*...*/ return 0; }
   public boolean sendRequest(Map<String,Object> options) { /*...*/ return true; }
   public Integer getData(Map<String,Object> options) { 
      return original.getData(options.get("key"));  // OriginalBroker2.getData(key:String):int
   }
   public boolean logOff(Map<String,Object> options) {
      return original.doLogout();
   }
   public boolean logoff() {
      return logoff(null);   // ignore third parameter
   }
}

もちろん、これは非常に一般的なアプローチです。1 つのメソッドがすべてのパラメーターの文字列を受け取ることがわかっている場合は、次のような抽象署名を使用することもできます。

abstract public boolean login(String...args);

次に、具体的な実装は次のようになります。

abstract class A {
   abstract public boolean login(String...args);    
}
class B extends A {
   public boolean login(String...args) { return this.login(args[0], args[1]); }
   public boolean login(String user, String pass) { return original.login(user,pass); }
}

class C {
   public void login() {
      B b = new B();
      b.login("foo", "secret");
      // or
      b.login(new String[] {"foo", "secret"});
      // or !
      b.login("foo", "secret", "sessionId");  // will ignore third, but otherwise would still work...
   }
}

于 2010-07-15T07:21:47.457 に答える
0

私が最初に考えたのは、ファサードパターンを調べることでした。これは、「Head First Design Patterns」の本で、Adapterと同じ章で説明されており、ホームシアターコンポーネントのリモートコントロールと比較されています。

このファサードは、クライアントアプリとさまざまなブローカーの間に位置します。したがって、クライアントは「シアター」に含まれるブローカーの数と数を気にする必要はなく、「ログインボタンを押す」と「すべてのブローカー接続がオンになっている」だけです。

于 2010-07-15T06:59:07.363 に答える