Java通用参数方法避免代码重复

时间:2017-03-31 07:46:21

标签: java generic-programming code-reuse

我有一个解析对象的函数。但是这个函数在两个服务中是必需的,并且参数具有相同的类名,但包名不同。我需要的是避免重复的代码。

假设函数是:

    private HashMap<String, Integer> getPagination(PagingRequestType pagingRequestType) {
        int pageSize = 200;
        int pageNumber = 1;
        if(pagingRequestType != null) {
            if (pagingRequestType.getNumberOfRecordsPerPage() != 0) {
                pageSize = pagingRequestType.getNumberOfRecordsPerPage();
            }
            if (pagingRequestType.getStartAtRecordNumber() != 0) {
                pageNumber = pagingRequestType.getStartAtRecordNumber();
            }
        }
        HashMap<String, Integer> result = new HashMap<>();
        result.put("pageNumber", pageNumber);
        result.put("pageSize", pageSize);
        return result;
    }

可能的函数调用:

- getPagination(new Abc.PagingRequestType());
- getPagination(new Xyz.PagingRequestType());

PagingRequestType是两个不同包中的自动生成的类。该功能需要实施一次并在两种服务中使用。

感谢。

4 个答案:

答案 0 :(得分:1)

如果您可以修改PagingRequestType课程,最好使用通用界面:

class Abc.PagingRequestType implements PagingRequestType
class Xyz.PagingRequestType implements PagingRequestType

interface PagingRequestType {
    getNumberOfRecordsPerPage();
    getStartAtRecordNumber();
}

答案 1 :(得分:1)

显而易见的答案是不要在两个地方自动生成PagingRequestType

如果你不能这样做,你需要这两个类来实现一个通用接口,通过它可以获得必要的字段(getNumberOfRecordsPerPagegetStartAtRecordNumber)。

如果无法更改类,可以使用以下字段创建界面:

interface YourInterface {
  int getNumberOfRecordsPerPage();
  int getStartAtRecordNumber();
}

并实现两个PagingRequestType s:

class AbcYourInterface implements YourInterface {
  final Abc.PagingRequestType delegate;  // Set in constructor.

  @Override public int getNumberOfRecordsPerPage() {
   return delegate.getNumberOfRecordsPerPage();
  }

  // Same for other method.
}

如果所有其他方法都失败了,请将类字段作为单独的参数传递:

private HashMap<String, Integer> getPagination(int numberOfRecordsPerPage, int startAtRecordNumber) {

使用一些“特殊”值来表示null,例如0,因为如果两个参数均为零,则条件为无操作。

答案 2 :(得分:0)

PagingRequestType可以实现一个公共接口或扩展一个公共类,您可以将此“公共部分”作为函数的参数。虽然我不知道你是否可以用这种方式修改自动生成的代码。

答案 3 :(得分:0)

如果使这两个PagingRequestType实现公共接口的选项是不可能的,你可以采用相反的方式,定义一个proxy类型来包装这两种类型:

public final class PagingRequestTypeProxy {
    private a.b.c.PagingRequestType abcPagingRequestType;

    private a.b.d.PagingRequestType abdPagingRequestType;

    public PagingRequestTypeProxy(PagingRequestType abcPagingRequestType) {
        this.abcPagingRequestType = abcPagingRequestType;
    }

    public PagingRequestTypeProxy(a.b.d.PagingRequestType abdPagingRequestType) {
        this.abdPagingRequestType = abdPagingRequestType;
    }

    public int getNumberOfRecordsPerPage() {
        return abcPagingRequestType != null ? abcPagingRequestType.getNumberOfRecordsPerPage() : abdPagingRequestType.getNumberOfRecordsPerPage();
    }

    public int getStartAtRecordNumber() {
        return abcPagingRequestType != null ? abcPagingRequestType.getStartAtRecordNumber() : abdPagingRequestType.getStartAtRecordNumber();
    }
}

并将getPagination的参数类型更改为:

private HashMap<String, Integer> getPagination(PagingRequestTypeProxy pagingRequestType) {...}

然后你就可以使用它:

getPagination(new PagingRequestTypeProxy(abcPagingReqType));
getPagination(new PagingRequestTypeProxy(abdPagingReqType));

缺点是有额外的代码来定义PagingRequestTypeProxy,优点是logic的{​​{1}}非常简单且易于维护,你可以把你的商业代码PagingRequestTypeProxy在一个地方。