Dart - 试图理解'factory'构造函数的价值

5 dart

如果我理解正确:

"A factory constructor affords an abstract class to be 
    instantiated by another class, despite being abstract." 
Run Code Online (Sandbox Code Playgroud)

例如:

abstract class Animal {
   String makeNoise(String sound);
   String chooseColor(String color);
   factory Animal() => new Cat(); 
}

class Cat implements Animal {
   String makeNoise(String noise) => noise;
   String chooseColor(color) => color;
}
Run Code Online (Sandbox Code Playgroud)

以上允许我这样做:

Cat cat = new Animal();
var catSound = cat.makeNoise('Meow');
var catColor = cat.chooseColor('black');
print(catSound); // Meow
Run Code Online (Sandbox Code Playgroud)

它也阻止我这样做:

class Dog implements Animal {
 int age;
 String makeNoise(String noise) => noise;
 String chooseColor(color) => color;
}

Dog dog = new Animal(); // <-- Not allowed because of the factory constructor
Run Code Online (Sandbox Code Playgroud)

所以,如果我对所有这些都是正确的,我会被问到为什么动物的额外代码?

如果您打算使用只创建猫的动物的工厂构造函数,为什么不只有一个具有所需方法/属性的Cat类?

或者,Animal类的目的是如上所述的工厂构造函数,真的是专门为Cat类设计的接口吗?

mez*_*oni 9

我不认为这个问题factory.

你的代码最初是错的.

看看这段代码并得出结论.

Locomotive locomotive = new SomethingWithSmokeFromChimney();
Run Code Online (Sandbox Code Playgroud)

现在看看这段代码.

Plant plant = new SomethingWithSmokeFromChimney();
Run Code Online (Sandbox Code Playgroud)

你错误地认为地球上的所有动物(甚至是狗)都是猫.

Cat cat = new Animal();
Run Code Online (Sandbox Code Playgroud)

如果你想要这个.

Cat cat = new Animal();
Dog dog = new Animal();
Run Code Online (Sandbox Code Playgroud)

然后(如果我正确理解你)你也想要这个.

// Cat cat = new Animal();
// Dog dog = new Animal(); 
Dog dog = new Cat();
Run Code Online (Sandbox Code Playgroud)

PS

同样错误的结论却没有factory.

void main() {
  Cat cat = new Animal();
  Dog dog = new Animal();
}

class Animal {
}

class Cat implements Animal {
}

class Dog implements Animal {
}
Run Code Online (Sandbox Code Playgroud)

但是这段代码(取决于文件)可能被认为是正确的.

void main() {
  Cat cat = new Animal("cat");
  Dog dog = new Animal("dog");
}

abstract class Animal {
  factory Animal(String type) {
    switch(type) {
      case "cat":
        return new Cat();
      case "dog":
        return new Dog();
      default:
        throw "The '$type' is not an animal";
    }
  }
}

class Cat implements Animal {
}

class Dog implements Animal {
}
Run Code Online (Sandbox Code Playgroud)

抽象类的工厂构造函数可以返回(默认情况下)此抽象类的一些默认实现.

abstract class Future<T> {
   factory Future(computation()) {
    _Future result = new _Future<T>();
    Timer.run(() {
      try {
        result._complete(computation());
      } catch (e, s) {
        result._completeError(e, s);
      }
    });
    return result;
  }
}
Run Code Online (Sandbox Code Playgroud)


Gün*_*uer 4

我将Cat其视为Animal.

当然你不能这样做Dog dog = new Animal();,因为new Animal();返回 aCat但你可以这样做Dog dog = new Dog();Animal animal = new Dog();

编辑以渴望发表评论
:)这只是如何利用工厂构造函数的另一个示例。尝试将工厂构造函数视为返回对象的普通函数(顶级函数或静态类函数)。为了使类的用户不知道幕后发生的事情,允许他像构造函数一样使用它new SomeClass。这就是工厂构造函数。我想到的第一个用例通常是单例模式或缓存目的的实现,但也包括所有其他情况,它查找类的用户,就好像他只是创建一个新实例,但实际上他得到了一些构造的东西,并且以一种更复杂但他不需要知道的方式准备。