8

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

4

5 回答 5

11

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

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

于 2013-06-05T19:43:20.217 回答
7

为什么不只拥有一个实现 Subject 的抽象类呢?使用界面只会为您提供更大的灵活性。从抽象类开始并没有真正给你带来任何好处。如果每件事都发生了很大的变化(比如跨越进程边界),那么您的 Observable 将被抽象实现所困。

于 2013-06-05T19:38:33.853 回答
3

在使用接口一词的设计模式中,它意味着向客户端组件公开的抽象 API,这些组件将具有不同的具体实现。

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

但是,在做出决定时,您确实需要了解 Java 接口和抽象类之间的区别以及它们的用途以及优缺点。

请参阅:接口与抽象类

于 2013-06-05T19:58:11.420 回答
1

为什么将主题设置为抽象类不是更好

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

您不希望观察者引用 a FirstConcreteSubject,而是引用一个 interface ISubject,可以快速将其更改为由 a 实现,SecondConcreteSubject而无需修改观察者。

也就是说,拥有一个BaseSubject抽象类来存储一些本来会被 and 复制的代码FirstConcreteSubject并没有错(IMHP) SecondConcreteSubject

于 2013-06-05T19:45:47.480 回答
1

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();

}

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

于 2019-05-06T12:23:00.907 回答