Java 完全透明的观察员

Java 完全透明的观察员,java,oop,design-patterns,observer-pattern,template-method-pattern,Java,Oop,Design Patterns,Observer Pattern,Template Method Pattern,我正在以以下方式实现观察者模式: interface Layer{ void adjustString(Set<String> strings); } interface NotifiableLayer extends Layer{ void layerAdjusted(Layer layer); } abstract class ObservableLayer implements Layer{ Set<NotifiableLayer> ob

我正在以以下方式实现观察者模式:

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?
    }
}
但在这里,我不喜欢将方法名称更改为doAdjustString,并且它在直接实现层接口的其他层实现之间不再统一


除了在MyLayer类中保留public StringSet strings签名之外,还有什么简单的方法可以实现此功能吗?

一种方法是使用一个装饰器实例来保存ObserveLayer实例并委托给它

最后一个类LayerCorator实现了层{ 最后一名私人助理代表; 公共层CoratorObservableLayer委托{ this.delegate=委托; } @凌驾 公共字符串集字符串{ delegate.stringstrings; 代表、观察员; } } 这假设调用代码使用层而不是ObservaleLayer的引用工作

如果调用代码必须使用对ObservalElayer的引用,那么最好将ObservalElayer重构为一个接口,该接口具有注册监听器、删除监听器并通知监听器的方法。此接口还扩展了层接口

接口IObservableLayer扩展层{ void addObserverNotifiableLayer层; void removeObserverNotifiableLayer层; 无效观察员; } 抽象类ObservableLayer更改为实现IObservableLayer,而不是直接实现Layer。这个类仍然是公共的,以支持应用程序类定义可观察层的变化

接下来,可观察层的内部装饰器可以定义如下所示

最后一个类ObservableDecorator实现IObservableLayer{ 最后一名私人助理代表; 公共ObservableLayer DecoratorObservableLayer委托{ this.delegate=委托; } @凌驾 public void addObserverNotifiableLayer层{ delegate.addObserverlayer; } @凌驾 public void removeObserverNotifiableLayer层{ delegate.removeObserverlayer; } @凌驾 公众观察员{ 代表、观察员; } @凌驾 公共字符串集字符串{ delegate.stringstrings; 这是一位观察员; } } 请注意在这种情况下通知是如何完成的

现在,IObservableLayer的实例可以创建为

IObservableLayer observableLayer=新的observableLayer装饰或新的MyClass;
工厂方法在这里会很有用,因为它们可以被定义来处理各种应用程序级可观察层类的创建,以便可以一致地创建实例,从而返回一个经过修饰的IObservableLayer。这将使开发人员不必知道如何使用decorator,并允许decorator成为一个内部实用程序。

一种方法是使用一个decorator实例,该实例包含一个observeLayer实例并委托给它

最后一个类LayerCorator实现了层{ 最后一名私人助理代表; 公共层CoratorObservableLayer委托{ this.delegate=委托; } @凌驾 公共字符串集字符串{ delegate.stringstrings; 代表、观察员; } } 这假设调用代码使用层而不是ObservaleLayer的引用工作

如果调用代码必须使用对ObservalElayer的引用,那么最好将ObservalElayer重构为一个接口,该接口具有注册监听器、删除监听器并通知监听器的方法。此接口还扩展了层接口

接口IObservableLayer扩展层{ void addObserverNotifiableLayer层; void removeObserverNotifiableLayer层; 无效观察员; } 抽象类ObservableLayer更改为实现IObservableLayer,而不是直接实现Layer。这个类仍然是公共的,以支持应用程序类定义可观察层的变化

接下来,可观察层的内部装饰器可以定义如下所示

最后一个类ObservableDecorator实现IObservableLayer{ 最后一名私人助理代表; 公共ObservableLayer DecoratorObservableLayer委托{ this.delegate=委托; } @凌驾 public void addObserverNotifiableLayer层{ delegate.addObserverlayer; } @凌驾 public void removeObserverNotifiableLayer层{ delegate.removeObserverlayer; } @凌驾 公众观察员{ 代表、观察员; } @凌驾 公共字符串集字符串{ delegate.stringstrings; 这是一位观察员; } } 请注意在这种情况下通知是如何完成的

现在是IObservab的实例 leLayer可以创建为

IObservableLayer observableLayer=新的observableLayer装饰或新的MyClass;
工厂方法在这里会很有用,因为它们可以被定义来处理各种应用程序级可观察层类的创建,以便可以一致地创建实例,从而返回一个经过修饰的IObservableLayer。这将使开发人员不必知道如何使用decorator,并允许decorator成为一个内部实用程序。

另一种方法是面向方面编程

下面的示例使用AspectJ拦截扩展Observable的类上的任何公共方法执行,并在同一对象上调用NotifyObservators

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class EventAspect {
    @AfterReturning("execution(public * Observable.*(..)) && target(observable)")
    public void notifyObservers(Observable observable) {
        observable.notifyObservers();
    }
}

另一种方法是面向方面编程

下面的示例使用AspectJ拦截扩展Observable的类上的任何公共方法执行,并在同一对象上调用NotifyObservators

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class EventAspect {
    @AfterReturning("execution(public * Observable.*(..)) && target(observable)")
    public void notifyObservers(Observable observable) {
        observable.notifyObservers();
    }
}

感谢您提供的另一种方法-标准组合优于继承。感谢您提供的另一种方法-标准组合优于继承。