簡體   English   中英

Dart - 試圖理解'factory'構造函數的價值

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

如果我理解正確:

"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類設計的接口嗎?

我不認為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();

PS

同樣錯誤的結論,但沒有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;
  }
}

我會將Cat視為Animal的默認實現。

當然你不能做Dog dog = new Animal(); 因為new Animal(); 返回一只Cat但你可以做Dog dog = new Dog(); Animal animal = new Dog();

編輯渴望評論
:)這只是另一個例子,你可以如何利用工廠構造函數。 嘗試將工廠構造函數視為返回對象的普通函數(頂級函數或靜態類函數)。 為了讓類的用戶不知道場景背后發生了什么,允許他像使用new SomeClass的構造函數一樣使用它。 這就是工廠構造函數。 想到的第一個用例通常是單例模式或緩存目的的實現,但也是所有其他情況,它查找類的用戶,就像他只是創建一個新實例,但實際上他得到了一些構造和以更復雜但他不需要注意的方式准備。

工廠構造函數的一個特征是尚未在方法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();
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM