我想提供可选在我的工作类中添加回调的可能性。这种回调的界面可能看起来像这样:
public interface Callback<T> {
void callback(final T data);
}
因为回调是可选的,所以每次调用之前我都需要检查是否在工作类中设置了一个:
public void doWork(final T data) {
if (callback != null) {
callback.callback(data);
}
// do the actual work
}
所以我想知道是否有一个非操作回调而不是看起来像这样:
@SuppressWarnings("rawtypes")
public class NopCallback implements Callback {
public static final NopCallback CALLBACK = new NopCallback();
@Override
public void callback(final Object data) {
// do nothing
}
}
默认情况下,worker会将其回调设置为此NopCallback:
@SuppressWarnings("unchecked")
public Worker() {
callback = NopCallback.CALLBACK;
}
我已经发现Nop变体似乎表现更好(通过调用doWork(...)
几次1000并测量每个变体的持续时间)。我并不完全满意的是需要@SuppressWarnings
。我知道我可以摆脱它们但是在我的每个工作类中都需要一个自己的NopCallback实例。
长话短说,就是清洁代码,可读性,性能等意义上使用这种无操作回调的好主意或者还有其他(优雅的)替代方案吗?
答案 0 :(得分:4)
这看起来很优雅。它与Collections.emptyList()
基本相同,它总是返回相同的空的不可变列表。我不会把它变成公共类,但会使用工厂方法来获取它,以确保警告只在一个地方,其余的代码是类型安全的:
@SuppressWarnings("unchecked")
private static final Callback NOP = new Callback() {
@Override
public void callback(final Object data) {
// do nothing
}
};
@SuppressWarnings("unchecked")
public static final <T> Callback<T> nop() {
return (Callback<T>) NOP;
}
这就是Collections.emptyList()
的实施方式。
答案 1 :(得分:0)
对于未来的读者,我为我的特殊用例找到了另一种解决方案。因为无论如何所有工作类都具有相同的父类(例如Worker
),我可以让Worker
实现Callback
接口本身:
public abstract class Worker<T> implements Callback<T> {
private Callback<T> callback;
public Worker() {
setCallback(this);
}
public void doWork(final T data) {
callback.callback(data);
doRealWork(data);
}
protected abstract void doRealWork(final T data);
@Override
public void callback(final T data) {
// do nothing
}
public void setCallback(final Callback<T> callback) {
if (callback == null) {
this.callback = this;
// Or throw some exception (depending on your situation)
} else {
this.callback = callback;
}
}
}
在我的特殊用例中,回调方法存在并且可以在工作人员自己中访问也没有问题。