"Extending" 匿名 class 实例创建后
"Extending" anonymous class after instance creation
假设我必须为 Request
期间发生的事件分配事件处理程序。 API 公开抽象 class RequestHandlerAPIAdapter
和接口 RequestHandlerAPI
以手动定义事件处理程序。 RequestHandlerAPIAdapter
实施 RequestHandlerAPI
。适配器仅存在,因此我可以执行以下操作:
client.setRequestHandler(new RequestHandlerAPIAdapter(Request request) {
// override some or all inherited methods
});
请注意,适配器只允许我处理我感兴趣的事件,而忽略其他事件。例如,如果我只想在发送请求时做某些事情,而不关心在处理请求或响应到达时会发生什么,我只能为 onRequestSent
指定一个处理程序并省略 onRequestProcessing
和 onResponseArrived
。这种设计模式可以满足大多数现实世界的需求。
现在假设我事先不知道我需要处理哪些事件,我可能会在创建 [=16= 的匿名实例之后决定将来是否应该手动处理 onResponseArrived
].需要 RequestHandlerAPIAdapter
的新实例,我将不得不重复 onRequestSent
的定义。我知道这听起来很奇怪,也许开发人员永远不需要以这种方式编写代码,但我想知道在这种情况下是否有防止代码重复的解决方法。
我想到的一个解决方案是创建一个实现 RequestHandlerAPI
或扩展 RequestHandlerAPIAdapter
的具体 class,为每个继承方法定义 public 功能接口,为刚刚定义的所有功能接口定义私有字段,并为请求期间可能发生的每个事件添加一个方法setHandler
。
下面是这样的代码 class:
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
}
这让我可以做这样的事情:
RequestHandlerConcreteAdapter adapter = new RequestHandlerConcreteAdapter ();
adapter.setHandler ( (RequestHandlerConcreteAdapter.HandleOnRequestSent) (request) -> {
//do something here
});
client.setRequestHandler (adapter);
// and at a later time
adapter.setHandler ( (RequestHandlerConcreteAdapter.HanldeOnResponseRetrieved) (request, response) -> {
// do something here
});
client.setRequestHandler (adapter);
我会寻找各种可能性来避免做我上面所做的事情,因为这个解决方案对我来说太脏了。另外,我想知道我所做的是否是 Java.
中已知的设计模式
总而言之,我想知道是否有更简洁的方法来实现上面的代码正在做的事情,如果没有,您能否建议对代码进行一些改进,使其看起来不那么脏?
在我看来,您只是在寻找 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.
}
现在如果你想覆盖,比如 "request sent" 处理一些现有的 RequestHandlerAPI
,你只需做:
RequestHandlerAPI decoratedRequestHandler =
new RequestHandlerAPIDecorator(existingRequestHandler) {
public void onRequestSent(Request request) {
System.out.println("Request is sent.");
}
});
您可以从头开始实施处理,也可以另外做一些事情,然后再调用 delegate.onRequestSent(request)
。
假设我必须为 Request
期间发生的事件分配事件处理程序。 API 公开抽象 class RequestHandlerAPIAdapter
和接口 RequestHandlerAPI
以手动定义事件处理程序。 RequestHandlerAPIAdapter
实施 RequestHandlerAPI
。适配器仅存在,因此我可以执行以下操作:
client.setRequestHandler(new RequestHandlerAPIAdapter(Request request) {
// override some or all inherited methods
});
请注意,适配器只允许我处理我感兴趣的事件,而忽略其他事件。例如,如果我只想在发送请求时做某些事情,而不关心在处理请求或响应到达时会发生什么,我只能为 onRequestSent
指定一个处理程序并省略 onRequestProcessing
和 onResponseArrived
。这种设计模式可以满足大多数现实世界的需求。
现在假设我事先不知道我需要处理哪些事件,我可能会在创建 [=16= 的匿名实例之后决定将来是否应该手动处理 onResponseArrived
].需要 RequestHandlerAPIAdapter
的新实例,我将不得不重复 onRequestSent
的定义。我知道这听起来很奇怪,也许开发人员永远不需要以这种方式编写代码,但我想知道在这种情况下是否有防止代码重复的解决方法。
我想到的一个解决方案是创建一个实现 RequestHandlerAPI
或扩展 RequestHandlerAPIAdapter
的具体 class,为每个继承方法定义 public 功能接口,为刚刚定义的所有功能接口定义私有字段,并为请求期间可能发生的每个事件添加一个方法setHandler
。
下面是这样的代码 class:
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
}
这让我可以做这样的事情:
RequestHandlerConcreteAdapter adapter = new RequestHandlerConcreteAdapter ();
adapter.setHandler ( (RequestHandlerConcreteAdapter.HandleOnRequestSent) (request) -> {
//do something here
});
client.setRequestHandler (adapter);
// and at a later time
adapter.setHandler ( (RequestHandlerConcreteAdapter.HanldeOnResponseRetrieved) (request, response) -> {
// do something here
});
client.setRequestHandler (adapter);
我会寻找各种可能性来避免做我上面所做的事情,因为这个解决方案对我来说太脏了。另外,我想知道我所做的是否是 Java.
中已知的设计模式总而言之,我想知道是否有更简洁的方法来实现上面的代码正在做的事情,如果没有,您能否建议对代码进行一些改进,使其看起来不那么脏?
在我看来,您只是在寻找 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.
}
现在如果你想覆盖,比如 "request sent" 处理一些现有的 RequestHandlerAPI
,你只需做:
RequestHandlerAPI decoratedRequestHandler =
new RequestHandlerAPIDecorator(existingRequestHandler) {
public void onRequestSent(Request request) {
System.out.println("Request is sent.");
}
});
您可以从头开始实施处理,也可以另外做一些事情,然后再调用 delegate.onRequestSent(request)
。