how to create an interface around classes that already exist but cannot be modified in java

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-04 15:51:22

问题


Suppose I already have 2 classes in my code:

class SomeOrder {
  String getOrderId() { return orderId; }
}

class AnotherOrder {
  String getOrderId() { return orderId; }
}

How to create an interface around both these classes which is:

interface Order {
    String getOrderId();
}

Ideally, I would modify the code so that SomOrder implements Order and AnotherOrder implements Order but the catch here is that they belong in a package that I cannot control or edit (i.e. they come from an external jar).

My algorithm currently looks like this:

void sorter(List<SomeOrder> orders) {
    ... <custom sort logic> ...
    someOrder.getOrderId();
}

void sorter(List<AnotherOrder> orders) {
    ... <custom sort logic> ...
    someOrder.getOrderId();
}

With a single interface I can write:

void sorter(List<Order> orders) {
        ... <custom sort logic> ...
        order.getOrderId();
}

回答1:


You can use adapter classes:

class SomeOrderAdapter implements Order {
    private SomeOrder delegate;

    @Override
    public String getOrderId() {
        return delegate.getOrderId();
    }
}

and similar for AnotherOrder.




回答2:


Since your interface is a functional interface, you could define functions that map to this new Order interface my referencing the getOrderId method for each different class:

private Order wrap(SomeOrder obj) {
    return obj::getOrderId;
}

private Order wrap(AnotherOrder obj) {
    return obj::getOrderId;
}

An example calling it:

private void test() {
    List<Order> orders = Arrays.asList(
        wrap(new SomeOrder()),
        wrap(new AnotherOrder())
    );
    sorter(orders);
}



回答3:


Create a Proxy wrapped around the instances implementing the interface you need. The proxy just calls the instance's method with the same parameters.

public class Proxied<T> implements InvocationHandler {
  private final T wrapped;

  public Proxied(T wrapped) {
    this.wrapped = Objects.requireNonNull(wrapped);
  }

  public T getWrapped() {
    return wrapped;
  }

  public <I> Class<I> proxy(Class<I> interfaceClass) {
    @SuppressWarnings("unchecked")
    Class<I> proxyClass = (Class<I>)  Proxy.getProxyClass(getClass().getClassLoader(), interfaceClass);
    return proxyClass;
  }

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    return method.invoke(wrapped, args);
  }
}


来源:https://stackoverflow.com/questions/49947749/how-to-create-an-interface-around-classes-that-already-exist-but-cannot-be-modif

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!