【问题标题】:OOP Observer Pattern: call notifyListener from outside of the subjectOOP 观察者模式:从主体外部调用 notifyListener
【发布时间】:2020-05-31 00:13:32
【问题描述】:

Observer 对象是否可以在更改其某些字段后在可观察对象上调用 notifyListeners()?可能会产生哪些不利因素?通常情况下,通知听众变化是主体的责任。

在将模型类包装在可观察/主题中时,我经常遇到以下问题,例如使它们在 UI 中可访问。

我的主体是否应该在模型对象的任何字段发生更改时通知其侦听器,或者我应该提供某种方法setModel() 将新模型对象作为参数然后才通知所有侦听器?

例如:

class MyData {
  String myString;
  int myInt;
}

class MyDataObservable {
  private MyData data;

  // constructor

  void setString(String string) {
    data.myString = string;
    notifyListeners();
  }

  void setInt(int num) {
    data.myInt = num; 
    notifyListeners();
  }

  void notifyListeners() {...}

  void addListener(Observer o) {...}
}

我不喜欢我的主题基本上反映了我模型的所有属性......这很丑陋。

class MyDataObservable {
  private MyData data;

  // constructor

  void setData(MyData data) {
    this.data = data; 
    notifyListeners();
  }

  void notifyListeners() {...}

  void addListener(Observer o) {...}
}

这种方法的缺点是每次发生任何变化时我都必须构建我的数据类的新副本,即使它只是我的模型类上的一个布尔标志。

所以我的想法是允许观察者在更改某些内容时通知其他听众,例如update 函数。

还有其他更优雅的选择吗?

编辑

目前,使我的数据类成为可观察的不是一种选择,因为我使用的框架提供了一种可观察的机制,该机制还可以保存业务逻辑。出于这个原因,我想解耦我的数据类和逻辑/可观察的。

【问题讨论】:

  • 您是否需要单独的MyData 类?它用于什么/为什么存在?为什么你不能使用 observable 类呢?
  • 您在 cmets 中说“观察者”,但您的代码说“可观察”。这些是非常不同的事情。

标签: oop design-patterns observer-pattern


【解决方案1】:

在这种情况下,我将使用继承而不是组合:MyData is-a Observable 而不是 Observable has-a MyData

class Observable {
    Collection<Listener> listeners

    void addListener(Listener l) {...}
    void notifyListeners() {...}
}

class MyData extends Observable {
    String myString;
    int myInt;

    void setString(String string) {
        this.myString = string;
        notifyListeners();
    }

    void setInt(int num) {
        this.myInt = num; 
        notifyListeners();
    }
}

【讨论】:

    猜你喜欢
    • 2019-08-22
    • 1970-01-01
    • 2011-09-25
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 2023-04-10
    相关资源
    最近更新 更多