简体   繁体   English

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

[英]Java generic parameter method to avoid code duplication

I have a function that parse an object. 我有一个解析对象的函数。 But this function is required in two services and the parameter have same class name, but different package name. 但是在两个服务中都需要此函数,并且参数具有相同的类名,但具有不同的包名。 What i need is to avoid duplicated code. 我需要的是避免重复的代码。

Suppose the function is: 假设函数为:

    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;
    }

Possible function calls: 可能的函数调用:

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

PagingRequestType is an auto-generated class in two different packages. PagingRequestType是两个不同程序包中的自动生成的类。 The function needs to be implemented once and used in both services. 该功能只需实施一次,即可在两种服务中使用。

Thanks. 谢谢。

If you can modify your PagingRequestType classes, it will be a good idea to use a common interface: 如果可以修改PagingRequestType类,则最好使用通用接口:

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

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

The obvious answer is not to auto-generate PagingRequestType in two places. 显而易见的答案是不要在两个地方自动生成PagingRequestType

If you can't do this, you need the two classes to implement a common interface, through which the requisite fields ( getNumberOfRecordsPerPage and getStartAtRecordNumber ) are available. 如果无法执行此操作,则需要两个类来实现一个公共接口,通过该接口可以使用必填字段( getNumberOfRecordsPerPagegetStartAtRecordNumber )。

If you can't change the classes, you can create an interface with these fields: 如果无法更改类,则可以使用以下字段创建接口:

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

and implement for the two PagingRequestType s: 并为两个PagingRequestType实现:

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

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

  // Same for other method.
}

If all else fails, pass in the class fields as separate parameters: 如果其他所有方法均失败,则将类字段作为单独的参数传递:

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

using some "special" value to indicate null , eg 0, since the conditional is a no-op if both parameters are zero. 使用一些“特殊”值来指示null ,例如0,因为如果两个参数均为零,则条件为空操作。

Both PagingRequestType could implement one common interface or extend one common class and you could take this "common part" as argument to your function. 这两个PagingRequestType都可以实现一个公共接口或扩展一个公共类,您可以将此“公共部分”作为函数的参数。 Although I don't know if you can modify your auto generated code in that way. 尽管我不知道您是否可以通过这种方式修改自动生成的代码。

If the option to make those two PagingRequestType s to implement a common interface is impossiable, you could do it the reverse way, define a proxy type to wrap those two types: 如果使这两个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();
    }
}

And change the parameter type of getPagination to: 并将getPagination的参数类型getPagination为:

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

Then you could use it like: 然后您可以像这样使用它:

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

The cons is that there're extra codes to define PagingRequestTypeProxy , the pros is that logic of PagingRequestTypeProxy is very simple and easy to maintain, and you can put your biz code getPagination in one place. 缺点是定义了PagingRequestTypeProxy需要额外的代码,优点是PagingRequestTypeProxy logic非常简单且易于维护,您可以将业务代码getPagination放在一个地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM