Java 使用lambdas实现类似功能的设计模式

Java 使用lambdas实现类似功能的设计模式,java,spring,design-patterns,Java,Spring,Design Patterns,我正试图找到一种方法或模式来简化我的服务类,并使其非常可调整。我的目标是使用lambdas或谓词访问服务类中的方法 class Client { @RequestLine("something/a") public A fetchA() {} @RequestLine("something/b") public B fetchB() {} //... lots of similar methods @RequestLine("something/z") publ

我正试图找到一种方法或模式来简化我的服务类,并使其非常可调整。我的目标是使用lambdas或谓词访问服务类中的方法

class Client {
  @RequestLine("something/a")
  public A fetchA() {}

  @RequestLine("something/b")
  public B fetchB() {}

  //... lots of similar methods

  @RequestLine("something/z")
  public Z fetchZ() {}
}

class Service {

 Client client;

 public void fixA(){
  client.fetchA();
  method();
 }

 public void fixB(){
  client.fetchB();
  method();
 }

// ... lots of similar methods

 public void fixZ(){
  client.fetchZ();
  method();
 }

 void method() {}

}
因此,我的重点是如何更改它,使其使用lambdas或其他东西,使我的服务类保留一个“fix”方法,但它知道我需要从我的客户机获取什么


如果这个问题不好,并且不符合这里的规则,那么请为我指出正确的方向,因为我迷路了

一种方法是将调用作为服务方法的参数传递给客户端。您需要使用泛型:

class Service {

    Client client;

    public <T> void fix(Function<Client, T> clientCall) {

        T result = clientCall.apply(client);

        // Do something with result

        method();
    }

}

我猜你想要的是

class Service {

    private Client client;

    public void fix(Consumer<Client> consumer){
        consumer.accept(client);
        method();
    }

    private void method() {}
}
为什么不

class Client {

  public A fetch (String identifier) {

    ArrayList<String> identifiers = ...;

    // validate user-provided identifier here

    if (___.equals(identifier)) {
      // specific code for each identifier
    } else if {
      // ...etc.
    }

  }
}

class Service {

  Client client;

  public void fix (String identifier){
    client.fetch(identifier);
    method();
  }

  void method() {}

}
类客户端{
公共获取(字符串标识符){
ArrayList标识符=。。。;
//在此验证用户提供的标识符
if(uu u;等于(标识符)){
//每个标识符的特定代码
}否则如果{
//……等等。
}
}
}
班级服务{
客户;
公共无效修复(字符串标识符){
client.fetch(标识符);
方法();
}
void方法(){}
}

这个问题可能有点基于观点,但让我们试一试

在我看来,您造成的第一个设计缺陷是将所有
fetchXYZ
方法放在一个客户机中。您可以创建一个界面
Client
,该界面可能如下所示

interface Client<T> {
  T fetch();
}
可能有很多方法可以解决您的需求,这只是其中之一

我个人不喜欢将客户机函数作为参数传递给方法的想法(尽管您要求这样做),因为在您当前的设计中,
client
有不同的职责(获取
A
B
等等)。使用lambdas实际上强化了此缺陷,并进一步隐藏了
客户端的实际功能


只有我的2美分。

通常,服务的重点是成为客户的门面。如果您的示例就是这种情况,并且您不想向服务的调用者公开Clent类,那么可以使用单一方法和枚举,如下所示:

public class ClientA implements Client<A> {
  @RequestLine(”something/a“)
  public A fetch() {
    // do fetch stuff
  }
}
public void fix(String clientType) {
  // returns instance of ClientA for ’a‘ for example
  final Client client = getClientForType(clientType);
  client.fetch();
  method();
}
public class Service {
    Client client = new Client();

    public enum FixType{
        A(Client::fetchA),
        B(Client::fetchB),
        Z(Client::fetchZ);

        private Consumer<Client> c = null;

        private FixType(Consumer<Client> c) {
            this.c = c;
        }

        private void fix(Client client) {
            c.accept(client);
        }
    }

    public void fix(FixType ft) {
        ft.fix(client);
        method();
    }

    void method() {}
}

你能澄清一下你的要求是什么吗?您有一个带有一些公共方法的
Client
类,还有一个
Service
类,您希望通过该类调用
Client
的方法,确保在每次调用之后都调用
Service.method()
。你是说你想简化
Service
中的代码,以便它“知道”基于
Service.fix*
方法调用哪个
Client.fetch*
方法吗?我想有一个fix()方法,它接受一些参数,比如lambda或谓词之类的参数(我对此没有很多想法)它会知道调用哪个客户机方法。也许调用特定的客户端方法应该作为参数传递?
public void fix(String clientType) {
  // returns instance of ClientA for ’a‘ for example
  final Client client = getClientForType(clientType);
  client.fetch();
  method();
}
public class Service {
    Client client = new Client();

    public enum FixType{
        A(Client::fetchA),
        B(Client::fetchB),
        Z(Client::fetchZ);

        private Consumer<Client> c = null;

        private FixType(Consumer<Client> c) {
            this.c = c;
        }

        private void fix(Client client) {
            c.accept(client);
        }
    }

    public void fix(FixType ft) {
        ft.fix(client);
        method();
    }

    void method() {}
}
new Service().fix(Service.FixType.B);