飞镖 - 试图了解工厂'构造函数

时间:2014-03-16 12:52:15

标签: dart

如果我理解正确:

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

例如:

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

以上允许我这样做:

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

这也阻止了我这样做:

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

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

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

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

3 个答案:

答案 0 :(得分:9)

我不认为factory中的问题。

您的代码最初是错误的。

查看此代码并得出结论。

Locomotive locomotive = new SomethingWithSmokeFromChimney();

现在看看这段代码。

Plant plant = new SomethingWithSmokeFromChimney();

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

Cat cat = new Animal();

如果你想要这个。

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

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

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

P.S。

相同的错误结论,但没有factory

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

class Animal {
}

class Cat implements Animal {
}

class Dog implements Animal {
}

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

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

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

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

答案 1 :(得分:4)

我会将Cat视为Animal的默认实现。

当然,您无法Dog dog = new Animal(); new Animal();,因为Cat会返回Dog dog = new Dog();,但您可以Animal animal = new Dog();new SomeClass

编辑渴望发表评论 :)这只是另一个例子,你可以如何利用工厂构造函数。尝试将工厂构造函数视为返回对象的普通函数(顶级函数或静态类函数)。为了让类的用户不知道场景背后发生了什么,允许他像使用{{1}}的构造函数一样使用它。这就是工厂构造函数。想到的第一个用例通常是单例模式或缓存目的的实现,但也是所有其他情况,它查找类的用户,就像他只是创建一个新实例,但实际上他得到了一些构造和以更复杂的方式准备,但他不需要知道。

答案 2 :(得分:2)

工厂构造函数的一个特征是尚未在方法start处创建对象。在该方法中,您可以使用各种机制来创建对象,例如:

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