java - 完全透明的观察者
问题描述
我正在通过以下方式实现观察者模式:
interface Layer{
void adjustString(Set<String> strings);
}
interface NotifiableLayer extends Layer{
void layerAdjusted(Layer layer);
}
abstract class ObservableLayer implements Layer{
Set<NotifiableLayer> observers = new HashSet<>();
void addObserver(NotifiableLayer layer){
observers.add(layer);
}
void removeObserver(NotifiableLayer layer){
observers.remove(layer);
}
void notifyObservers(){
observers.forEach(l -> l.layerAdjusted(this));
}
}
class MyLayer extends ObservableLayer{
@Override
public void adjustString(Set<String> strings) {
this.notifyObservers(); //can this be auto?
}
}
这当然可行,但无论谁正在实施,都ObservableLayer
需要记住调用this.notifyObservers()
该adjustString
方法。这没什么大不了的,但我想看看是否有办法完全隐藏这一点。
到目前为止,我只有这个想法(使用模板方法):
abstract class ObservableLayer implements Layer{
//...methods removed for simplicity
@Override
public void adjustString(Set<String> strings) {
this.doAdjustString(strings);
this.notifyObservers(); //<---- here is auto
}
abstract void doAdjustString(Set<String> strings);
}
class MyLayer extends ObservableLayer{
@Override
public void doAdjustString(Set<String> strings) {
//now notification is in base adjustString
}
}
但是这里我不喜欢把那个方法名改成doAdjustString
,而且其他层实现(直接实现Layer
接口的层)之间也不再统一了。
有没有简单的方法来拥有这个功能,但要public void adjustString(Set<String> strings)
在课堂上保持签名MyLayer
?
解决方案
一种方法是使用一个包含一个ObservableLayer
实例并委托给它的装饰器实例。
final class LayerDecorator implements Layer {
final private ObservableLayer delegate;
public LayerDecorator(ObservableLayer delegate) {
this.delegate = delegate;
}
@Override
public void adjustString(Set<String> strings) {
delegate.adjustString(strings);
delegate.notifyObservers();
}
}
这假定调用代码正在使用对Layer
而不是ObservableLayer
.
如果调用代码必须使用引用来工作,ObservableLayer
那么最好将其重构ObservableLayer
为具有注册侦听器、删除它们并通知它们的方法的接口。这个接口也扩展了Layer
接口。
interface IObservableLayer extends Layer {
void addObserver(NotifiableLayer layer);
void removeObserver(NotifiableLayer layer);
void notifyObservers();
}
抽象类ObservableLayer
更改为实现IObservableLayer
而不是Layer
直接实现。这个类仍然是公开的,以支持应用程序类定义可观察层的变体。
接下来可以定义可观察层的内部装饰器,如下所示。
final class ObservableLayerDecorator implements IObservableLayer {
final private ObservableLayer delegate;
public ObservableLayerDecorator(ObservableLayer delegate) {
this.delegate = delegate;
}
@Override
public void addObserver(NotifiableLayer layer) {
delegate.addObserver(layer);
}
@Override
public void removeObserver(NotifiableLayer layer) {
delegate.removeObserver(layer);
}
@Override
public void notifyObservers() {
delegate.notifyObservers();
}
@Override
public void adjustString(Set<String> strings) {
delegate.adjustString(strings);
this.notifyObservers();
}
}
请注意在这种情况下通知是如何完成的。
现在的实例IObservableLayer
可以创建为
IObservableLayer observableLayer = new ObservableLayerDecorator(new MyClass());
工厂方法在这里会很有帮助,因为它们可以被定义为处理各种应用程序级可观察层类的创建,以便可以一致地创建实例,返回一个IObservableLayer
被修饰的。这将使开发人员无需了解如何使用装饰器,并允许装饰器成为内部实用程序。
推荐阅读
- javascript - 如何根据屏幕大小更改文本的位置?
- microservices - 将 Pact 与生成的客户端 API 服务一起使用
- c# - 当我尝试在属性初始化中使用 nameof 时出现错误 cs0120
- c# - 在 .NET 5 Winforms 迁移之后,“在 ITypeIdentityResolutionService 开始处理入队程序集之前无法解析类型”
- node.js - 在受保护的路线上反应重定向不起作用
- blockchain - 返回值无效,它是否用尽了 Gas?web3 1.5.0 和 sol-0.5.15
- c++ - 创建新的结构指针和 emplace map
- python - 使用 RDFLib Python 按特定顺序添加三元组
- r - 使用 purrr::map 在 for 循环中重写向量
- http - 如何从编码的 URL 获取 Yii 2 中的请求变量?