简体   繁体   English

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

[英]Dart - Trying to understand the value of 'factory' constructor

If I am understanding correctly: 如果我理解正确:

"A factory constructor affords an abstract class to be 
    instantiated by another class, despite being abstract." 

As example: 例如:

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;
}

The above allows me to do this: 以上允许我这样做:

Cat cat = new Animal();
var catSound = cat.makeNoise('Meow');
var catColor = cat.chooseColor('black');
print(catSound); // Meow

And it also prevents me from doing this: 它也阻止我这样做:

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

So if I am correct with all this, I am led to ask why the extra code for Animal? 所以,如果我对所有这些都是正确的,我会被问到为什么动物的额外代码?

If you intend on using a factory constructor for animal, which creates only cats, why not just have a Cat class with the required methods/properties? 如果您打算使用只创建猫的动物的工厂构造函数,为什么不只有一个具有所需方法/属性的Cat类?

Or, is the purpose of the Animal class with a factory constructor like above, really an interface specifically designed for Cat class only? 或者,Animal类的目的是如上所述的工厂构造函数, 真的是专门为Cat类设计的接口吗?

I don't think that the problem in the factory . 我不认为factory的问题。

Your code initially was wrong. 你的代码最初是错的。

Look at this code and make your conclusions. 看看这段代码并得出结论。

Locomotive locomotive = new SomethingWithSmokeFromChimney();

Now look at this code. 现在看看这段代码。

Plant plant = new SomethingWithSmokeFromChimney();

You mistakenly believe that all animals on the earth (even the dogs) are cats. 你错误地认为地球上的所有动物(甚至是狗)都是猫。

Cat cat = new Animal();

If you want this. 如果你想要这个。

Cat cat = new Animal();
Dog dog = new Animal();

Then (if I correctly understand you) you also want this. 然后(如果我正确理解你)你也想要这个。

// Cat cat = new Animal();
// Dog dog = new Animal(); 
Dog dog = new Cat();

PS PS

The same wrong conclusions but without factory . 同样错误的结论,但没有factory

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

class Animal {
}

class Cat implements Animal {
}

class Dog implements Animal {
}

But this code (depending on documenation) may be considered correct. 但是这段代码(取决于文件)可能被认为是正确的。

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 {
}

The factory constructor of the abstract class can return (by default) some default implementation of this abstract class. 抽象类的工厂构造函数可以返回(默认情况下)此抽象类的一些默认实现。

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;
  }
}

I would see Cat as the default implementation of Animal . 我会将Cat视为Animal的默认实现。

Of course you can't do Dog dog = new Animal(); 当然你不能做Dog dog = new Animal(); because new Animal(); 因为new Animal(); returns a Cat but you can do Dog dog = new Dog(); 返回一只Cat但你可以做Dog dog = new Dog(); or Animal animal = new Dog(); Animal animal = new Dog();

EDIT to long for a comment 编辑渴望评论
:) This is just one other example how you can utilize factory constructor. :)这只是另一个例子,你可以如何利用工厂构造函数。 Try to see the factory constructor as a normal function (top level function or static class function) that returns an object. 尝试将工厂构造函数视为返回对象的普通函数(顶级函数或静态类函数)。 To make the user of the class unaware of what is going on behind the scene allow him to use it like a constructor with new SomeClass . 为了让类的用户不知道场景背后发生了什么,允许他像使用new SomeClass的构造函数一样使用它。 That is what a factory constructor is. 这就是工厂构造函数。 The first use cases that comes to mind are usually an implementation for the singleton pattern or for caching purposes but also all other cases where it looks for the user of the class as if he just creates a new instance but in fact he gets something constructed and prepared in a way that is more complicated but he needs not to be aware of. 想到的第一个用例通常是单例模式或缓存目的的实现,但也是所有其他情况,它查找类的用户,就像他只是创建一个新实例,但实际上他得到了一些构造和以更复杂但他不需要注意的方式准备。

The one characteristic of a factory constructor is that the object is not already created at the method start. 工厂构造函数的一个特征是尚未在方法start处创建对象。 In the method you can have various mechanisms to create the object, like for example: 在该方法中,您可以使用各种机制来创建对象,例如:

abstract class Animal {
  String makeNoise(String sound);
  String chooseColor(String color);
  factory Animal() {
    var random = new math.Random();
    if (random.nextBool() == true) 
      return new Cat();
    else
      return new Dog();
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM