[英]Type-safe object composition
我目前正在开发一个网络健康监视系统,该系统可以监视多种资源,基于事实进行诊断并根据诊断做出反应。
我最初的想法是要有一个抽象的Watcher
类,该类可以配置一个Diagnosis
对象(负责基于Facts
生成Diagnostic
)和DiagnosticHandler
对象列表。 这个Watcher
类将具有一个abstract protected Facts _check()
模板方法,该方法被子类(例如HttpWatcher
或MemoryWatcher
abstract protected Facts _check()
覆盖。
Facts
是一个标记界面,代表可以观察到产生Diagnostic
。 例如, HttpWatcher
的_check
方法将返回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*/
...
)
自从我使用强类型语言编程以来已经有一段时间了,我想确保自己使用类型来发挥自己的优势,但是与此同时,我也不希望自己的设计受到影响。
我曾经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
)
我想知道当对象由可能不兼容的多种策略组成和/或我是否朝着建议的解决方案迈向正确方向时,是否使用了广泛采用的模式?
我可能会遗漏一些东西,但是基于对问题的当前理解,我会做类似的事情:
public class Watcher<T> {
public Watcher(Resource<T> res, Diagnosis<T> diag) {
...
}
}
和
public class HttpResource implements Resource<HttpFacts> {
...
}
这样可以保证Watcher和Diagnosis始终是兼容的类型,并且仍然允许您覆盖二者之一。
我可能很想念一些重要的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.