3

我正在创建一个客户端摇摆应用程序,该应用程序将具有由众多数据提供者(经纪人)之一提供/来自其的数据。然而,数据提供者有不同的方式来执行相同的事情,例如

broker1的登录方式

public boolean doLogin(String username, String password);

broker2的登录方式

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

对于所有提供者,所需操作的集合是相同的,例如

login、getstatus、sendRequest、getData、logOff
(但它们有不同的参数和返回类型)

我查看了适配器模式,但遗憾的是无法很好地使用它,因为所需的方法具有不同的参数。

在这种情况下适配器模式是否可用?如果是这样怎么办?
如果不是,那么最好的方法是什么?

谢谢。

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
   }
}

当然,这是一种非常通用的方法。如果您知道一种方法将接收所有参数的字符串,您还可以有一个抽象签名,例如:

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 ”一书中,它与适配器在同一章中进行了解释,并与家庭影院组件的远程控制进行了比较。

这个外观将位于客户端应用程序和各种代理之间。因此,客户不必关心“剧院”中有哪些经纪人以及有多少经纪人,它只需要“按下登录按钮”和“所有经纪人连接都已打开”。

于 2010-07-15T06:59:07.363 回答