【问题标题】:Implement an Observer pattern in Dart在 Dart 中实现观察者模式
【发布时间】:2013-12-09 18:33:38
【问题描述】:

我想在 Dart 中实现一个观察者模式,但我不知道如何去做。

假设我有一堂课:

class MyClass {

  String observed_field;

}

现在,每当我更改字段时,我想将“observed_field changed”字符串打印到控制台中。使用自定义设置器非常简单:

class MyClass {

  String _observed_field;

  get observed_field    => _observed_field;
  set observed_field(v) {
    _observed_field = v;
    print("observed_field changed");
  }

}

当然,如果我没有一个,但有很多这样的字段,我就不想创建所有这些 getter 和 setter。显而易见的理论解决方案是将它们动态添加到类中,如下所示(不是工作代码,只是我希望它看起来如何的示例):

class MyClass

  String  _observeable_field;
  String  _observeable_field_2;

  observe(#observeable_field, #observeable_field_2);

end

有可能吗?此外,如果不在observe() 调用之上定义这些字段,而是编写如下内容,那就太棒了:

observe(String: #_observeable_field, String: #_observeable_field_2);

以便自动声明这些字段。

【问题讨论】:

    标签: dart


    【解决方案1】:

    这是一种使用Observe 包的方法。该示例取自该包中的代码 cmets(并适用于您上面的示例)。本质上,您使用 @observable 注释来注释您希望可观察的字段,然后监听更改(通过调用 Observable.dirtyCheck() 触发;

    首先,在你的pubspec.yaml中添加observable包

    dependencies:
      observe: any
    

    然后创建一个快速测试程序...

    import 'package:observe/observe.dart';
    
    class MyClass extends Object with Observable {
      @observable String observedField = "Hello";
    
      toString() => observedField.toString(); 
    }
    
    main() {
      var obj = new MyClass();
    
      // anonymous function that executes when there are changes
      obj.changes.listen((records) {
        print('Changes to $obj were: $records');
      });
    
    
      obj.observedField = "Hello World";
    
      // No changes are delivered until we check for them
      Observable.dirtyCheck();
    
      print('done!');
    }
    

    这会产生以下输出:

    Changes to Hello World were: [#<PropertyChangeRecord Symbol("observedField") from: Hello to: Hello World>]
    done!
    

    更新以响应 cmets... 更新示例以省略 Observable.dirtyCheck(),您可以使用 setter 和 notifyPropertyChanged,而将类混入 ChangeNotifier

    class MyClass2 extends Object with ChangeNotifier {
    
      String _observedField = "Hello";
    
      @reflectable get observedField    => _observedField;
      @reflectable set observedField(v) {
        _observedField = notifyPropertyChange(#observedField, _observedField, v);    
      }
    
      toString() => observedField;
    
    }
    

    【讨论】:

    • 我在 SO 上阅读了另一个问题,建议使用这个 Observe 包。但是,我不喜欢您实际上必须致电 Observable.dirtyCheck() 才能交付更改。如果您仍然必须基本上手动检查更改,这种方式否定了观察某事的全部意义。
    • 如果您查看 API 文档中的示例,它会显示如何使用 @reflectable 注释和 notifyPropertyChange() 来避免dirtyCheck()。这更类似于您的示例。 api.dartlang.org/docs/channels/stable/latest/observe.html
    • @ChrisBuckett 我看到你写了 class MyClass extends Object with Observableclass MyClass extends Observable 有区别吗
    • 我想既然类现在是可观察的,我们不需要像列表或地图那样创建它们var obj = toObservable(new MyClass())??跨度>
    • toObservable 仅用于列表和地图,无需在其他对象上调用。对于您之前的评论:class MyClass extends Object with Observable 是一个 mixin 应用程序,class MyClass extends Observable 是继承。如果您想要或必须从 Observable 以外的其他类继承,前者很有用。在 Dart 中,你不能从多个类继承。在这里,mixin 派上用场了,因为它们提供了某种有限的多重继承。如果您想坚持一种风格,您可以始终使用 Observable 的 mixin 变体,即使您只是扩展 Object
    猜你喜欢
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 2015-02-12
    相关资源
    最近更新 更多