我目前正在开发一个网络健康监测系统,它允许监视多种资源,根据事实进行诊断,并根据诊断做出反应。
最初的想法..。
我最初的想法是拥有一个抽象的Watcher类,它可以配置一个Diagnosis对象(负责生成基于Facts的Diagnostic )和一个DiagnosticHandler对象列表。此Watcher类的abstract protected Facts _check()模板方法将被子类(如HttpWatcher或MemoryWatcher )覆盖。
Facts是一个标记接口,表示可以观察到的生成Diagnostic的内容。例如,_check方法HttpWatcher将返回HttpFacts,这基本上是http响应详细信息。
下面是HttpWatcher构造函数的样子:
public HttpWatcher(
Duration interval,
Diagnosis<HttpFacts> diagnosis,
List<DiagnosticHandler> handlers,
URL url
)正如我们所看到的,因为这个类的_check方法返回HttpFacts,所以它也只允许基于HttpFacts进行诊断的Diagnosis策略,这正是我们想要的。这样,如果使用了不兼容的Diagnosis策略,编译器就有可能抱怨。
缺失的概念?
但是,在这个设计中有一些让我困扰的地方,因为我注意到在行为方面,Watcher子类覆盖的唯一东西是_check方法。更糟糕的是,_check算法无法在其他地方重用。这让我想,也许我在我的设计中缺少了一个Resource概念,它可以封装检索Facts的算法,而不是必须对Watcher进行子类分类。
尽管如此,我只需要一个具体的Watcher类,它将配置为一个Resource、一个Diagnosis<T extends Facts>和一个List<DiagnosticHandler>。
这个设计对我来说更有意义,但那样的话,我就失去了防止不兼容策略一起使用的类型安全性,如下所示:
new Watcher(
new Duration(...),
new HttpResource(...),
new SimpleMemoryDiagnosis(...), /*<- incompatible with HttpResource*/
...
)解决办法?
我已经有一段时间没有用一种强类型的语言编程了,我想确保我使用这些类型对我有利,但同时我不想让我的设计受到影响。
我的一个想法是创建一个新的类,比如HttpWatchedResource,它将封装HttpResource和Diagnosis<HttpFacts>对象。
类似于:
public abstract class WatchedResource {
private final Resource resource;
private final Diagnosis diagnosis;
public WatchedResource(Resource resource, Diagnosis diagnosis) {
//null checks
this.resource = resource;
this.diagnosis = diagnosis;
}
//called by Watcher
public final Diagnostic checkHealth() {
return diagnosis.diagnose(resource.facts());
}
}
public final class HttpWatchedResource {
public HttpWatchedResource(HttpResource resource, Diagnosis<HttpFacts> diagnosis) {
super(resource, diagnosis);
}
}然后,Watcher构造函数将如下所示:
public Watcher(
Duration interval,
WatchedResource resource,
List<DiagnosticHandler> handlers,
URL url
)我想知道,当一个对象由可能不兼容的多个策略组成时,是否存在一种广泛采用的模式,以及/或我是否正朝着建议的解决方案的正确方向前进?
发布于 2014-04-24 15:26:08
我可能遗漏了一些东西,但根据我目前对这个问题的理解,我会做这样的事情:
public class Watcher<T> {
public Watcher(Resource<T> res, Diagnosis<T> diag) {
...
}
}和
public class HttpResource implements Resource<HttpFacts> {
...
}这将确保“监视”和“诊断”始终具有兼容的类型,并且仍然允许您重写任何一种类型。
不过,我很可能错过了一些重要的东西。
https://stackoverflow.com/questions/23247816
复制相似问题