Muhammad Ramzan
Muhammad Ramzan

Reputation: 288

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. The function needs to be implemented once and used in both services.

Thanks.

Upvotes: 0

Views: 996

Answers (4)

shizhz
shizhz

Reputation: 12501

If the option to make those two PagingRequestTypes to implement a common interface is impossiable, you could do it the reverse way, define a proxy type to wrap those two types:

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:

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.

Upvotes: 0

Andy Turner
Andy Turner

Reputation: 140319

The obvious answer is not to auto-generate PagingRequestType in two places.

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.

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 PagingRequestTypes:

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, e.g. 0, since the conditional is a no-op if both parameters are zero.

Upvotes: 1

Alex Romanov
Alex Romanov

Reputation: 11963

If you can modify your PagingRequestType classes, it will be a good idea to use a common interface:

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

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

Upvotes: 1

LLL
LLL

Reputation: 1907

Both PagingRequestType could implement one common interface or extend one common class and you could take this "common part" as argument to your function. Although I don't know if you can modify your auto generated code in that way.

Upvotes: 0

Related Questions