基于UML图的观察者模式实现

我无法理解“可重用面向对象软件的元素”中观察者模式的以下 UML 图。谁能解释我为什么我的 Java 实现是错误的,我必须改变什么才能正确实现它?

UML-图

尝试(但错误)实施

public interface Subject {
    
    public static final List<Observer> observers = new ArrayList<Observer>();
    
    public void attach(Observer o);
    public void detach(Observer o);
    public void notifyObservers();
}

public interface Observer { 
    public void update();
}

public class ConcreteSubject implements Subject {
    
    private String subjectState;

    @Override
    public void attach(Observer o) {
        observers.add(o);   
    }

    @Override
    public void detach(Observer o) {
        observers.remove(o);
    }

    @Override
    public void notifyObservers() {
        for (Observer o : observers) {
            o.update();
        }       
    }
    
    public String getState() {
        return subjectState;
    }
    
    public void setState() {
        subjectState += "x";
    }
}

public class ConcreteObserver implements Observer {
    
    private ConcreteSubject subject;
    public String observerState;

    @Override
    public void update() {
        observerState = subject.getState();
    }
}

回答

一个问题是您有一个静态的观察者列表,Subject因此所有主题都共享相同的观察者。但是,该模式要求每个单独的主题都有自己的观察者,因此将列表放入ConcreteSubject并使其成为实例字段。

另一个问题是您ConcreteObserver有一个 type 字段ConcreteSubject。但是,它应该不知道Subjectso 的具体实现,因此该字段应该只有 type Subject

编辑:实际上,UML 图要求具体的观察者了解具体的主题,以便能够调用,getState()因此上面的段落在您的情况下不正确 - 这应该不是问题。

但是,实际上我实际上会有另一个接口来扩展Subject和隐藏ConcreteSubject观察者的实现。

编辑2

正如所建议的那样,您还可以使用抽象类来处理主题的观察者。这可能是一个阶级之间SubjectConcreteSubject甚至Subject本身,而是因为Java不支持多重继承我会经常使用一些其他的办法,使Subject只是一个接口。

最简单的实现是ConcreteSubject维护观察者列表,但在现实世界的应用程序中,您不希望开发人员这样做或依赖他们正确实现它。

相反,您可以使用一个中央注册表来维护每个主题的观察者列表,并且主题使用它来通知其观察者。许多依赖注入框架以这种方式运行,即每当“主题”发生变化时,它们都会通知其观察者该事件。

  • @MoritzWolff to clarify a point made by Thomas, UML is supposed to be "language agnostic." However sometimes, there are limits or constraints based on the language. So, as a developer, you have to be aware and explore what are the accepted equivalents for the language you're using.

以上是基于UML图的观察者模式实现的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>