带有工厂构造函数的抽象类的好处?

Dar*_*int 8 oop dart dart-polymer angular-dart

我最近遇到了一些使用抽象类作为接口的例子,但也向抽象接口添加了工厂构造函数,因此它可以在某种意义上被“更新”。例如:

abstract class WidgetService {
    factory WidgetService() = ConcreteWidgetService;

    Widget getWidget();
    void saveWidget(Widget widget);
}

class ConcreteWidgetService extends BaseWidgetService implements WidgetService {

    WidgetService();

    Widget getWidget() {
        // code to get widget here
    }

    void saveWidget(Widget widget) {
        // code to save widget here
    }
}
Run Code Online (Sandbox Code Playgroud)

此服务的使用将在其他一些服务或组件中,如下所示:

WidgetService _service = new WidgetService();
Run Code Online (Sandbox Code Playgroud)

根据我对这个示例的理解,上面的行基本上会“新建”一个 WidgetService,它通常会从 Dart 分析器中产生一个警告,并且所说的服务变量实际上是一个基于 ConcreateWidgetService 分配给WidgetService 的工厂构造函数。

这种方法有好处吗?根据我的 OOP 经验,当我不知道我将获得的具体类型时,我使用抽象类/接口进行编程。在这里,我们似乎立即将具体类型分配给抽象工厂构造函数。我想我的第二个问题是在这种情况下为什么不直接在这里使用 ConcreteWidgetService 而不是重复所有方法签名?

Gün*_*uer 12

在你的例子中,好处是有限的,但在更复杂的情况下,好处变得更加明显。

工厂构造函数允许您更好地控制构造函数返回的内容。它可以返回子类的实例或已经存在的(缓存的)实例。

它可以根据构造函数参数返回不同的具体实现:

abstract class WidgetService {
  WidgetService _cached;

  factory WidgetService(String type) {
    switch (type) {
      case 'a':
        return ConcreteWidgetServiceA();
      case 'b':
        return ConcreteWidgetServiceB();
      default:
        return _cached ??= DummyWidgetServiceA();
    }
  }

  Widget getWidget();

  void saveWidget(Widget widget);
}
Run Code Online (Sandbox Code Playgroud)

你的例子似乎是一种准备最终扩展到这种更灵活的方法。