在实例创建后“扩展”匿名类

时间:2018-04-13 06:53:52

标签: java design-patterns anonymous-class

假设我必须为Request期间发生的事件分配事件处理程序。 API公开了一个抽象类RequestHandlerAPIAdapter和一个接口RequestHandlerAPI来手动定义事件处理程序。 RequestHandlerAPIAdapter实施RequestHandlerAPI。适配器仅存在,因此我可以执行以下操作:

client.setRequestHandler(new RequestHandlerAPIAdapter(Request request) {
    // override some or all inherited methods
});

请注意,适配器允许我只处理我感兴趣的事件而忽略其他事件。例如,如果我只想在发送请求时执行某些操作并且不关心处理请求或响应到达时发生的情况,我只能为onRequestSent指定处理程序并忽略{{ 1}}和onRequestProcessing。这种设计模式满足了大多数现实世界的需求。

现在假设我不知道我需要事先处理哪些事件,我可能会在创建onResponseArrived的匿名实例后决定是否应该在将来手动处理onResponseArrived。将需要RequestHandlerAPIAdapter的新实例,我将不得不重复RequestHandlerAPIAdapter的定义。我知道这听起来很奇怪,也许开发人员永远不需要以这种方式编写代码,但我想知道在这种情况下是否有防止代码重复的解决方法。

我想出的一个解决方案是创建一个实现onRequestSent或扩展RequestHandlerAPI的具体类,为每个继承的方法定义公共功能接口,为刚定义的所有功能接口定义私有字段并为请求期间可能发生的每个事件添加方法RequestHandlerAPIAdapter

以下是此类的代码:

setHandler

这允许我做这样的事情:

public class RequestHandlerConcreteAdapter implements RequestHandlerAPI {
    private HandleOnRequestSent onRequestSent = null; // or may be an empty lambda expression that does nothing
    private HandleOnRequestProcessing onRequestProcessing = null;
    private HandleOnResponseRetrieved onResonseRetrieved = null;

    public interface HandleOnRequestSent {
        void onRequestSent (Request request);
    }

    public interface HandleOnRequestProcessing {
        void onRequestProcessing (Request request);
    }

    public interface HandleOnResponseRetrived {
        void onResponseRetrived (Request request, Response response);
    }

    @Override
    public void onRequestSent (Request request) {
        onRequestSent.onRequestSent(request);
    }

    public RequestHandlerConcreteAdapter setHandler (HanldeOnRequestSent h) {
        onRequestSent = h;
        return this; // allows us to chain methods
    }

    @Override
    public void onRequestProcessing (Request request) {
        onRequestProcessing.onrequestProcessing(request);
    }

    // overloaded
    public RequestHandlerConcreteAdapter setHandler (HanldeOnRequestProcessing h) {
        onRequestProcessing = h;
        return this; // allows us to chain methods
    }

    // and a pair to handle onResponseRetrived
}

我会寻找避免做我上面所做的一切的可能性,因为这个解决方案对我来说太脏了。另外,我想知道我所做的是Java中的已知设计模式。

总而言之,我想知道是否有更简洁的方法来实现上面的代码正在做什么,如果没有,你能建议对代码进行一些改进,使它看起来不那么脏吗?

1 个答案:

答案 0 :(得分:1)

在我看来,你只是在寻找Decorator pattern。实现使用RequestHandlerAPIDecorator实例创建的RequestHandlerAPI,并委托对其进行所有onRequest<DoSomething>次调用。要覆盖某些操作,请继承RequestHandlerAPIDecorator并覆盖其中一个方法。

有些事情:

 public abstract class RequestHandlerAPIDecorator implements RequestHandlerAPI {

     protected final RequestHandlerAPI delegate;

     public RequestHandlerAPIDecorator(RequestHandlerAPI delegate) {
         this.delegate = Objects.requireNonNull(delegate, "delegate must not be null.");
     }

     public void onRequestProcessing(Request request) {
         delegate.onRequestProcessing(request);
     }

     // Etc. You IDE will happily generate delegate methods for you.
 }

现在,如果您想要覆盖某些现有RequestHandlerAPI的“请求已发送”处理,您只需执行以下操作:

 RequestHandlerAPI decoratedRequestHandler = 
     new RequestHandlerAPIDecorator(existingRequestHandler) {
         public void onRequestSent(Request request) {
             System.out.println("Request is sent.");
         }
     });

您可以从头开始实施处理或另外做一些事情,然后再调用delegate.onRequestSent(request)