如何在 Dart mixin 中编写任意初始化代码?

问题描述 投票:0回答:2

假设我有一个公开了

mixin
的包,它通过 API 提供了一些可扩展性:

mixin ListenerModifier<T> {
  T get value;
  void addListener(Callback callback);
  void removeListener(Callback callback);
}

假设我想基于这个 mixin 制作一个“插件”:

mixin PreviousValue<T> on ListenerModifier<T> {
  late T previous;

  const PreviousValue() {
    addListener(() => previous = value);
  }
}

(您也可以在其他包中定义插件,也许可以公开

Stream<T>
getter。)

然后,用户可以随意使用任何插件,如下所示:

abstract class MyListener<T> with ListenerModifier<T>, PreviousValue<T> {}

问题是,mixins 不能有像上面

PreviousValue
假设的构造函数。是否有一些 OOP/架构方法可以解决这个问题?我最初想到只是强制
PreviousValue
(例如)的用户在其
registerPreviousValue()
构造函数中调用
MyListener
方法作为解决方法,但这很容易出错。

相关:

dart oop mixins
2个回答
0
投票

刚刚意识到我给出的特定示例,我可以使用不同类型的插件系统而无需混合:

mixin ListenerModifierPluginAPI {
  T get value;
  void addListener(Callback callback);
  void removeListener(Callback callback);
}

abstract class ListenerModifier with ListenerModifierPluginAPI {
  T registerPlugin<T>(T Function(ListenerModifierPluginAPI) plugin) => plugin(this);
}

class MyListenerModifier extends ListenerModifier {
  late final PreviousValueState previousValueState;

  const MyListenerModifier() {
    previousValueState = registerPlugin(previousValuePlugin);
  }

  // ...
}

但这可能并不适合所有人。如果有人有不同的解决方案,我会洗耳恭听。


0
投票

实际上,有一种 OOP 方法可以解决这个问题。 您可以定义必须由使用该 mixin 的任何类实现的抽象 getter。这样你就可以将值放入 mixin 中,甚至强制它发生。 要自动执行 mixin 中的某些 init 函数,您可以给 mixin 一些 bool 标志,该标志显示 mixin 函数是否已经运行,并且您检查 mixin 的内部 getter/setter 和函数。

另一种可能性是定义一个

late final
属性,该属性使用 mixin 的函数,而 mixin 又使用抽象 getter 来初始化其值。由于后期属性初始化器仅在第一次访问时执行,因此可以保证使用 mixin 的实例在此时完全初始化。

© www.soinside.com 2019 - 2024. All rights reserved.