我有一个抽象的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()
方法,因为任何数量的对象都可以通过编译器警告传递。是否存在可能没有这些缺点的模式或其他解决方案?
答案 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();