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

时间:2016-08-01 20:12:48

标签: 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
    }
}

此服务的用途将在某些其他服务或组件中如此:

WidgetService _service = new WidgetService();

基于我对此示例的理解,上面的行基本上是“新”WidgetService,它通常会产生来自Dart分析器的警告,并且所述服务变量实际上是基于分配的ConcreateWidgetService的实例。 ConcreateWidgetService到WidgetService的工厂构造函数。

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

2 个答案:

答案 0 :(得分:2)

在Dart中,所有类也都是自动接口。创建一个实例 - ' newing up'并不奇怪。 - 一个'界面',因为它实际上只是创建一个类的实例。

一些抽象类的目的是专门定义一个接口,但它们有工厂构造函数,它们返回一个'默认实现'他们自己。

例如:

void main() {
  var v = new Map();
  print(v.runtimeType);
}

打印:_InternalLinkedHashMap - Map的(当前)默认实现。

核心库用户可以创建和使用Map的实例,而无需了解或关心他们实际获得的实现。图书馆作者可以在不破坏任何人的代码的情况下更改实施。

当然,其他类也可以实现Map

对于您的代码示例,WidgetService _service = new WidgetService();不会产生分析器警告。请参阅此example on DartPad(注意我修复了样本中的几个错误。)

我最初感到困惑的是:

factory WidgetService() = ConcreteWidgetService;

而不是:

factory WidgetService() => new ConcreteWidgetService();

但似乎有效。

答案 1 :(得分:2)

在您的示例中,收益是有限的,但在更复杂的情况下,收益会更加明显。

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

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

5..50

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