一个带有变量返回类型和变量输入参数的java方法

时间:2015-01-28 09:52:10

标签: java design-patterns

我有一个抽象的java类“BaseOperation”。该类只有一个抽象方法:

public abstract T execute()
{
    ...

    return T;
}

BaseOperation的子类必须实现此方法:

public class GetUsersOperation extends BaseOperation<GetUsersResponse>
{
    ...

    @Override
    public GetUsersResponse execute()
    {

        ...

        return GetUsersResponse;
    }

}

这是将所有常见“操作”逻辑放在BaseOperation类中的好方法,但仍然使每个具体子类的execute()方法具有不同的返回类型。

现在我需要更改此结构以允许execute()方法具有可变数量的参数。例如,一个具体的子类需要:

execute(String, int)

而另一个则需要:

execute(Date, Date, String)

这很棘手,因为execute方法是在基类中声明的。简单地重载基础中的执行方法并不理想。首先,过载量将是巨大的。其次,每个子类只会使用一种执行方法,其他所有方法的意义何在?

(在我看来)最简单的解决方案是用varargs声明execute方法:

execute(Object... arguments)

然后向下转发子类中的所有参数:

execute(Object... arguments)
{
    String s = (String) arguments[0];
    ...
}

显然这有两个主要缺点:

  • 因所有向下转换操作而降低性能
  • 不再严格键入execute()方法,因为任何数量的对象都可以通过编译器警告传递。

是否存在可能没有这些缺点的模式或其他解决方案?

2 个答案:

答案 0 :(得分:5)

您可以使用包含参数的bean:

public interface BaseOperation<T, U> {
    T execute(U input);
}

public class GetUsersOperation implements BaseOperation<GetUsersResponse, UserInput> {

    @Override
    public GetUsersResponse execute(UserInput input) {
        Date date = input.getDate();
        return new GetUsersResponse(date);
    }

}

您的抽象类只有一个抽象方法:更好地使用接口。您可以实现多个接口,而只能扩展一个类。

答案 1 :(得分:3)

如前所述,解决问题的常用方法是使用bean保存参数。但这是基于构建器方法的另一种解决方案:

public interface BaseOperation<T> {
   public T execute();
}

public class AddOperation implements BaseOperation<Integer> {
   private int a, b;

   public void setA(int arg){
     a = arg ;
     return this;
   }

   public void setB(int arg){
     b = arg;
     return this;
   }

   @Override
   public Integer execute() {
     return a+b ;
   }
}

然后像这样使用它:

new AddOperation().setA(1).setB(2).execute();

您可以通过以下方式混合必需参数和可选参数:

public class MultipleAddOperation implements BaseOperation<Integer> {
  private int sum ;

  public MultipleAddOperation(int requiredInt){
    sum = requiredInt;
  }

  public void add(int optionalInt){
    sum += optionalInt ;
    return this;
  }

  @Override
  public Integer execute(){
    return sum;
  }
}

所以:

new MultipleAddOperation(5).add(1).add(2).execute();