【问题标题】:Dart, override many getters and setters in a DRY or synthetic way in a Proxy PatternDart,在代理模式中以 DRY 或合成方式覆盖许多 getter 和 setter
【发布时间】:2020-04-25 19:47:24
【问题描述】:

让我们学习这个飞镖课程:

class Subject {
  String a;
  String b;
  String c;
}

现在我想通过代理使用它来管理延迟加载和同步。

我还希望在从网络加载真实数据时使用默认值作为占位符。为了保持大腿整洁和独立,我添加了另一个类:

class Fallback implements Subject {
  @override String a = 'a';
  @override String b = 'b';
  @override String c = 'c';
}

现在我有了写下“带有后备的代理”类所需的所有积木:

class Proxy implements Subject {
  Subject model;
  Subject fallback = Fallback();

  Future<void> slowlyPopulateModel() async => if (model == null) ... // do some async stuff that valorize model

  @override
  String get a {
    slowlyPopulateModel();
    return model?.a ?? fallback.a;
  }
  @override
  set a(String _a) {
    model?.a = a;
    notifyListener();
  }

  // same getters and setters for b and c
}

通过覆盖get a,我可以在需要时调用慢速I/O 方法并返回我的Fallback 类的占位符值。一旦设置了新值,我覆盖的set a(String _a) 将调用notifyListener(),这将更新我的界面。
它工作正常,但我已经为我班级的每个字段手动覆盖 getter 和 setter(它们很多)。

Dart 有什么技巧可以以更DRY 的方式做到这一点吗?
例如。在每个 getter 或 setter 之前或之后注入要执行的代码的某种方式?

【问题讨论】:

  • 所以你的界面必须能够请求这个值并在它改变时得到通知?你在使用 Flutter 作为你的界面吗?

标签: flutter dart dry proxy-pattern


【解决方案1】:

我建议看看Streams

此代码示例将返回一个初始值,获取一个新值并通过流通知侦听器。

import 'dart:async';

class Subject {
  // Current value, initially at "a"
  String _a = "a";
  
  StreamController<String> _aController = StreamController<String>();
  
  String get a {
    _updateA();
    return _a;
  }
  
  Stream<String> get aStream => _aController.stream;
  
  void _updateA() async {
    String newValue = await _fetchA();
    _a = newValue; // update the current value
    _aController.add(newValue); // push the new value onto the stream for listeners
  }
  
  // return a String after two seconds
  Future<String> _fetchA() async {
    return Future.delayed(
      Duration(seconds: 2),
      () => "New value for _a",
    );
  }
  
  // This closes the stream
  void dispose() {
    _aController.close();
  }
  
}

main(args) {
  final subject = Subject();
  
  // listen to changes
  subject.aStream.listen((value) {
    print("new value of a: $value");
  });
  
  // get current value
  final currentValue = subject.a;
  print("current value of a: $currentValue");
  
}

这个例子的输出

a的当前值:a

(两秒后)a 的新值:_a 的新值

在 Flutter 中使用 StreamBuilder

StreamBuilder<String>(
  stream: subject.aStream,
  initialData: subject.a,
  builder: (context, snapshot) {
    final valueOfA = snapshot.data;
    return Text("value is $valueOfA");
  }
)

一些样板代码可以替换为RxDart 中的BehaviorSubject。但这需要将另一个依赖项导入到项目中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    • 1970-01-01
    • 2011-04-27
    • 2014-08-05
    相关资源
    最近更新 更多