具有变量 return 类型和变量输入参数的 java 方法
A java method with both variable return type and variable input arguments
我有一个摘要javaclass"BaseOperation"。这个class只有一个抽象方法:
public abstract T execute()
{
...
return T;
}
BaseOperation 的子classes 必须实现此方法:
public class GetUsersOperation extends BaseOperation<GetUsersResponse>
{
...
@Override
public GetUsersResponse execute()
{
...
return GetUsersResponse;
}
}
这是将所有常见 "operation" 逻辑放入 BaseOperation
class 的好方法,但每个具体子 class 的 execute()
方法有不同的 return 类型。
现在我需要更改此结构以允许 execute() 方法具有可变数量的参数。例如,一个具体的 subclass 需要:
execute(String, int)
另一个需要:
execute(Date, Date, String)
这很棘手,因为 execute 方法是在基 class 中声明的。简单地重载基类中的执行方法并不理想。首先,过载量会很大。其次,每个 subclass 只会使用其中一种执行方法,其他方法有什么意义?
(在我看来)最简单的解决方案是使用可变参数声明执行方法:
execute(Object... arguments)
然后向下转换子classes中的所有参数:
execute(Object... arguments)
{
String s = (String) arguments[0];
...
}
显然这有两个主要缺点:
- 由于所有向下转换操作导致性能下降
- 调用
execute()
方法不再严格类型化,因为可以传递任意数量的对象而不会出现编译器警告。
是否存在可以避免这些缺点的模式或其他解决方案?
您可以使用包含参数的 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);
}
}
您的抽象 class 只有一个抽象方法:最好使用接口。您可以实现多个接口,而只能扩展一个 class.
如前所述,解决您的问题的常用方法是使用持有参数的 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();
我有一个摘要javaclass"BaseOperation"。这个class只有一个抽象方法:
public abstract T execute()
{
...
return T;
}
BaseOperation 的子classes 必须实现此方法:
public class GetUsersOperation extends BaseOperation<GetUsersResponse>
{
...
@Override
public GetUsersResponse execute()
{
...
return GetUsersResponse;
}
}
这是将所有常见 "operation" 逻辑放入 BaseOperation
class 的好方法,但每个具体子 class 的 execute()
方法有不同的 return 类型。
现在我需要更改此结构以允许 execute() 方法具有可变数量的参数。例如,一个具体的 subclass 需要:
execute(String, int)
另一个需要:
execute(Date, Date, String)
这很棘手,因为 execute 方法是在基 class 中声明的。简单地重载基类中的执行方法并不理想。首先,过载量会很大。其次,每个 subclass 只会使用其中一种执行方法,其他方法有什么意义?
(在我看来)最简单的解决方案是使用可变参数声明执行方法:
execute(Object... arguments)
然后向下转换子classes中的所有参数:
execute(Object... arguments)
{
String s = (String) arguments[0];
...
}
显然这有两个主要缺点:
- 由于所有向下转换操作导致性能下降
- 调用
execute()
方法不再严格类型化,因为可以传递任意数量的对象而不会出现编译器警告。
是否存在可以避免这些缺点的模式或其他解决方案?
您可以使用包含参数的 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);
}
}
您的抽象 class 只有一个抽象方法:最好使用接口。您可以实现多个接口,而只能扩展一个 class.
如前所述,解决您的问题的常用方法是使用持有参数的 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();