测试方法输入参数的可空性组合

时间:2014-10-05 17:19:52

标签: java design-patterns service refactoring

我用Java编写一种服务。它涉及具有许多参数的方法(也有许多类型)。这些方法必须首先测试一些参数的可空性和其他参数的非可空性,以便调度处理(其他服务的调用,Web服务调用,简单的计算,日志记录,有时甚至没有...)

这些方法的签名和正文如下:

public void method(String param1, String param2, Integer param3, long param4, Object param5, List<Object> param6){

if (param1 == null and param2 == null and param2 == null and param3 == null and param4 == null and param5 == null and param6 == null){
// do something

}

else if (param1 != null and param2 == null and param2 == null and param3 == null and param4 == null and param5 == null and param6 == null){

// do something

}


else if (param1 == null and param2 != null and param2 == null and param3 == null and param4 == null and param5 == null and param6 == null){
//do something

}

else if (param1 != null and param2 != null and param2 == null and param3 == null and param4 == null and param5 == null and param6 == null){

}

else if (...){


}


else {

// ...
}




}

真实的情况是我使用jQuery调用jQuery到spring控制器方法。

public class MySpringController{

private MyRepo myRepo;
// some attributes 

public List<String> findAllNames(Integer telephoneNumber, String job, Integer birthDate){

if (telephoneNumber == null and job == null and birthDate == null){
  return myRepo.getAllNames()
}

else if (telephoneNumber != null and job == null and birthDate == null)
{
  return myRepo.fetchByTelephone(telephoneNumber);
}

else if (...)
{
//...
}

else 
{
//do something ...
}

}

这个案例促使我扩展我的问题,并想知道是否有一个设计模式。

我想知道我是否能找到更优雅的方式(设计模式可能)来进行这些测试。对示例进行编码的方式可能会导致一些冗余代码...我不知道您是否同意我以及您是否对此有任何建议?

2 个答案:

答案 0 :(得分:2)

以下是您的代码应该是什么样的:

public List<String> findAllNames(Integer telephoneNumber, String job, Integer birthDate) {
    return myRepo.fetchByCriteria(telephoneNumber, job, birthDate);
}

在存储库中,您应该根据条件的值动态构建查询。 JPA有一个专门为这种用例设计的Criteria API。如果使用SQL,这就是代码的样子:

public List<String> fetchByCriteria(Integer telephoneNumber, String job, Integer birthDate) {
    String sql = "select name from user u where 1 = 1";
    List<Object> parameters = new ArrayList<>();
    if (telephoneNumber != null) {
        sql += " and u.phone = ?";
        parameters.add(telephoneNumber);
    }
    if (job != null) {
        sql += " and u.job = ?";
        parameters.add(job);
    }
    if (birthDate != null) {
        sql += " and u.birthDate = ?";
        parameters.add(birthDate);
    }

    ...

}

当然,也有API允许动态编写这样的SQL查询(想到JOOQ)。

答案 1 :(得分:1)

这里有几个选项:

  • 责任链:您实现对象的链接列表(每个不同的类)。每个对象看起来是否适合处理这种情况,如果它处理它,否则它将它传递给下一个。

示例代码

//Handler template
public abstract class FooHandler {

    private FooHandler next;

    protected FooHandler () {
        this(null);
    }

    protected FooHandler (FooHandler next) {
        this.next = next;
    }

    public Result handle (Bar arguments) {
        if(next != null) {
            next.handle(arguments);
        } else {//end of chain, unfortunately no handler found :(
            return null;
        }
    }

}

//Handlers
public class Handler1 extends FooHandler {

    public Handler1 () {}
    public Handler1 (FooHandler next) {
        super(next);
    }

    public Result handle (Bar arguments) {
        if(arguments.first != null) {//the criteria are met
            return new Result("First handler's result.");
        } else {
            super.handle(arguments);
        }
    }

}

public class Handler2 extends FooHandler {

    public Handler2 () {}
    public Handler2 (FooHandler next) {
        super(next);
    }

    public Result handle (Bar arguments) {
        if(arguments.first == null && arguments.second != null) {//the criteria are met
            return new Result("Second handler's result.");
        } else {
            super.handle(arguments);
        }
    }

}

//Construct handler
public class Bar {

    public static void main (String[] args) {
        FooHandler handlerChain = new Handler1(new Handler2());
        Bar bar = new Bar(args);
        FooHandler.handle(bar);
    }

}

如果一个条件导致两个新的处理程序,你也可以将它实现为某种二叉树。