【问题标题】:Observer Pattern abstract vs interface观察者模式抽象与接口
【发布时间】:2013-06-05 19:33:25
【问题描述】:

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

【问题讨论】:

    标签: design-patterns observer-pattern


    【解决方案1】:

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

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

    【讨论】:

    • 在许多方面,理想的模式是有一个实现接口的抽象类,但从不定义抽象类类型的任何存储位置——总是使用接口。这将允许可以从抽象类型派生的类简单地继承有用的代码,而那些必须从其他类型派生的类可以导入任何通用代码作为样板。但是,如果该类型的某些使用者使用抽象类型而不是接口类型,则该方法将失败,即使除非类需要访问其他实例的私有数据,否则这不是必需的。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

      见:Interface Vs Abstract Class

      【讨论】:

        【解决方案4】:

        为什么让主题成为一个抽象类不是更好

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

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

        也就是说,使用 BaseSubject 抽象类来存储一些本来会被 FirstConcreteSubjectSecondConcreteSubject 复制的代码并没有错 (IMHP)。

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-07-06
            • 2010-09-23
            • 2013-02-12
            • 2014-10-14
            • 2016-02-20
            • 2023-04-10
            • 2023-04-11
            • 1970-01-01
            相关资源
            最近更新 更多