观察者模式抽象与界面

时间:2013-06-05 19:33:26

标签: design-patterns observer-pattern

我对观察者模式有疑问。它说Observer和Subject都应该是接口。我明白为什么观察者是接口,但为什么将主题作为抽象类更好呢?难道你不能实现至少删除/注册吗?

5 个答案:

答案 0 :(得分:10)

设计模式旨在适应应用程序的特定需求;他们没有规定一成不变的规则。考虑到决策对其余应用程序的所有影响,特别是某些东西是抽象类还是接口是由您决定的。

也就是说,由于几个原因,建议接口优先于抽象类。例如,抽象类要求您使用继承,而在许多语言中,您不能从多个类继承。如果这对您的用例不是问题,那么如果您觉得它们更方便,请继续使用抽象类。

答案 1 :(得分:7)

为什么不只有一个实现Subject的抽象类?使用界面只会给您更大的灵活性。从抽象类开始,它并没有真正为你买任何东西。如果每个事情都发生了很大变化(比如跨越流程边界)那么你的Observable将会被抽象的实现所困扰。

答案 2 :(得分:3)

在使用word接口时的设计模式中,它表示暴露给具有不同具体实现的客户端组件的抽象API。

当设计模式接口映射到Java世界时,它可以是Java接口或Java抽象类,设计模式具体类映射到Java常规类(非抽象)。

然而,在做出决定时,您需要了解Java界面和抽象类之间的区别及其目的以及优缺点。

请参阅:Interface Vs Abstract Class

答案 3 :(得分:1)

  

为什么让主题成为抽象类

更好

避免将设计与特定的具体实现联系起来。请记住,目的是创建一个模式,使您可以根据需要灵活地交换具体主题,而不是让观察者与原始实现相关联。

您不希望观察者引用FirstConcreteSubject,而是引用ISubject,可以快速更改为SecondConcreteSubject实现,而无需修改观察者

也就是说,IMHP有一个BaseSubject抽象类来存储一些本来会被FirstConcreteSubjectSecondConcreteSubject复制的代码。

答案 4 :(得分:0)

Java接口描述类型(由《设计模式》一书定义)。 Java接口的限制因素是您无法声明观察者列表所需的实例变量。

这就是抽象类的来源。您可以 声明这样的实例变量:

import java.util.List;

public abstract class Subject {

    List<Observer> observers; // this would not be allowed in an interface

    public void attachObserver(ObjectObserver objectObserver) {
    // implementation
    };

    public void detachObserver(ObjectObserver objectObserver) {
    // implementation
    };

    public abstract void notifyObservers();

}

但是,接口更好,因为它们在强制封装方面更好。您可以通过在接口中声明这三个方法/“类型”的三个方法来添加另一层抽象。然后,抽象类可以实现这些方法。