RxJavaPlugins,背后的模式



我想使用RxJavaPlugins重现RxJava的"静态"注入,如果这个类的设计是一个众所周知的模式,我很想知道!?

我有一个基本的模型类为我的所有事件

import lombok.Getter;
public abstract class BasicEvent {
@Getter
private final String id;
@Getter
private final long timestamp;
public BasicEvent() {
this.id = IDGenerator.BY_COUNTER.generate();
this.timestamp = TimePlayer.clock().timestamp();
}
}

上述类的主要缺点是可测试性。我无法更改IDGenerator和TimePlayer。

我认为有一个像RxJavaPlugins这样设计的第三方类可以帮助我更改测试的元数据生成器

更新

我遵循了RxJavaPlugins解决方案,以保持模型的创建简单,而不必担心id和时间戳(我称这两个字段为元数据(,以下是找到的解决方案。

public BasicEvent() {
this.id = MetaGenerator.idGenerator().generate();
this.timestamp = MetaGenerator.timePlayer().timestamp();
}

public class MetaGenerator {
public static IDGenerator idGenerator() {
// DGenerator.BY_COUNTER is the default value
return MetaGeneratorPlugins.onIDGenerator(IDGenerator.BY_COUNTER);
}
public static TimePlayer timePlayer() {
return MetaGeneratorPlugins.onTimePlayer(TimePlayer.realtime);
}
}
public class MetaGeneratorPlugins {
private static Function<? super TimePlayer, ? extends TimePlayer> onTimePlayerHandler;
private static Function<? super IDGenerator, ? extends IDGenerator> onIDGeneratorHandler;
public static void setTimePlayerHandler(@Nullable Function<? super TimePlayer, ? extends TimePlayer> handler) {
onTimePlayerHandler = handler;
}
public static void setIDGeneratorHandler(@Nullable Function<? super IDGenerator, ? extends IDGenerator> handler) {
onIDGeneratorHandler = handler;
}
//return the default value or the value returned by the handler
public static TimePlayer onTimePlayer(@Nonnull TimePlayer defaultScheduler) {
if (onTimePlayerHandler == null) {
return defaultScheduler;
}
return apply(onTimePlayerHandler, defaultScheduler);
}
public static IDGenerator onIDGenerator(@Nonnull IDGenerator defaultScheduler) {
if (onIDGeneratorHandler == null) {
return defaultScheduler;
}
return apply(onIDGeneratorHandler, defaultScheduler);
}
private static <T, R> R apply(@Nonnull Function<T, R> f, @Nonnull T t) {
return f.apply(t);
}
}

在我现在的测试中,我可以通过调用MetaGeneratorPlugins 来更改这个MetaGenerator的实现

MetaGeneratorPlugins.setIDGeneratorHandler(IDGenerator.INCREMENTAL);
MetaGeneratorPlugins.setTimePlayerHandler(TimePlayer.simulated);

RxJavaPlugins就是这样工作的,我受到了他们的解决方案的启发

现在,我的模型创建很简单,可以用于生产和测试。

更改BasicEvent的设计,使idtimestamp以更可测试的方式绑定。

引入"压模"接口:

public interface Stamper {
String generateId();
long   generateTimestamp();
}

"默认"实现看起来像:

public RealTimeStamper implements Stamper {
@Override public String generateId() {
return IDGenerator.BY_COUNTER.generate();
}
@Override public long generateTimestamp() {
return TimePlayer.clock().timestamp();
}
}

提供Stamper的可测试实现。然后使用您使用的任何依赖注入过程绑定适当的实现。

public abstract class BasicEvent {
static Stamper stamper;
...
public BasicEvent() {
this.id = stamper.generateId();
this.timestamp = stamper.generateTimestamp();
}
}

stamper字段可以手动注入,也可以使用依赖注入框架注入。

相关内容

  • 没有找到相关文章

最新更新