用 Java 编写响应处理程序

one*_*ece 3 java design-patterns java-8

我的服务调用下游服务,该服务返回一个ResponseEntity<MyBodyClass> response. 我的服务需要根据不同的属性做出不同的反应response

例如,如果response.getStatusCode() == HttpStatus.BAD_REQUESTresponse.getBody().code == 1,服务应该做一些动作“A”,但是如果对于相同的状态代码response.getBody().id == 1,那么它应该做“B”。另一个例子是如果response.getStatusCode() == HttpStatus.OKresponse.getBody() != null,服务应该做“C”。

我知道这可以用一堆 if 语句来完成,但是有没有更好的设计模式?

dav*_*xxx 5

将规则作为责任链实施:

ruleFoo -> ruleBar -> ruleFooBar -> ....
Run Code Online (Sandbox Code Playgroud)

必须根据规则优先级对链进行排序,并且对链的每个元素(此处的规则)进行处理以检测匹配项。一旦规则匹配,该规则就会执行适当的操作并停止链过程。

这是一个非常简单的实现,它利用了 java 8 流(与原始 GOF 模式略有不同,但我喜欢它,因为实现起来更轻松)。

public interface ResponseRule {        
    boolean match(Response response);                  
    void performAction();                          
}

public class RuleFoo implements ReponseRule {

    public boolean match(Response response){
       return response.getStatusCode() == HttpStatus.BAD_REQUEST && response.getBody().code == 1;
    }

    public void performAction(){
       // do the action
    }
}

public class RuleBar implements AbstractReponseRule {

    public boolean match(Response response){
       return response.getStatusCode() == HttpStatus.BAD_REQUEST && response.getBody() != null;
    }

    public void performAction(){
       // do the action
    }
}
Run Code Online (Sandbox Code Playgroud)

以及如何使用它们:

Response response = ...;
List<ResponseRule> rules = new ArrayList<>();
rules.add(new RuleFoo(), new RuleBar());

rules.stream()
     .filter(rule -> rule.match(response))
     .findFirst()
     .ifPresent(ResponseRule::performAction);
Run Code Online (Sandbox Code Playgroud)

请注意,如果可以累积规则执行,则需要进行一些小的更改:

rules.stream()
     .filter(rule -> rule.match(response))
     .forEachOrdered(ResponseRule::performAction);
Run Code Online (Sandbox Code Playgroud)