dartのfactoryについてわからんかったのでまとめた。
直訳すると工場。はて?
はじめに
factoryはコンストラクタ定義の際に用いる修飾子であり、Factoryパターン[1]が言語に組み込まれているものらしい。このfactoryコンストラクタはreturnでインスタンスを返す(それは果たしてコンストラクタなのか...)。
ユースケース
シングルトン[2]として扱う場合か、もしくはキャッシュやサブタイプ(派生クラス)のインスタンスを返すのに利用する。つまりは新しいインスタンスを作成するとは限らない場合。
- シングルトンの例
class Creature {
static final Map<String, String> _cretures = <String, String>{};
static final Creature _cache = Creature._internal();
Creature._internal();
factory Creature() {
return _cache;
}
setCreature(String key, String value) => _cretures[key] = value;
getCreature(String key) => _cretures[key];
}
void main() {
var creature = Creature();
creature.setCreature('human', 'taro');
creature.setCreature('dog', 'pochi');
print(creature.getCreature('human'));
print(creature.getCreature('dog'));
// 再度インスタンス生成
var creature2 = Creature();
print(creature2.getCreature('human')); // taro
print(creature2.getCreature('dog')); // pochi
creature2.setCreature('human', 'jiro');
creature2.setCreature('dog', 'hachi');
// 最初にインスタンス化した値を出力
// creature2とcreatureが同一であることがわかる
print(creature.getCreature('human')); // jiro
print(creature.getCreature('dog')); // hachi
}
- サブタイプ(派生クラス)のインスタンス返却の例
abstract class Result {
final String status;
Result(this.status);
factory Result.judge(String status) {
if (status == 'success') {
return Success(status);
} else {
return Failure(status);
}
}
void showStatus() {}
}
class Success extends Result {
Success(String status) : super(status);
@override
showStatus() {
print(super.status);
}
}
class Failure extends Result {
Failure(String status) : super(status);
@override
showStatus() {
print(super.status);
}
}
void main() {
Result result;
result = Result.judge('success');
print(result.runtimeType); // Success
result.showStatus(); // success
}
Named Constructor と どう違う?
主に次のような違いがあるらしい。
Factoryコンストラクタ | Named Constructor | |
---|---|---|
インスタンスメンバへのアクセス | 静的なため、アクセスできない | 任意のメンバ変数およびメソッドにアクセス可能 |
returnの有無 | インスタンスの返却が必要 | 無し |
生成するインスタンスの型 | 該当クラスと違う型を返せる | 該当クラスと同じ型しか返せない |
[1]:デザインパターン「Factory Method」にわかりやすくまとめてくれていました。
[2]:オブジェクト指向におけるデザインパターンの1つであり、対象のクラスのインスタンスが一つになるように設計すること
参考
- 【Dart】Factory Constructorをかんたんに理解する
- 基礎から学ぶFlutter 著:石井幸次