1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

dartのfactoryとは?

Last updated at Posted at 2022-10-15

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つであり、対象のクラスのインスタンスが一つになるように設計すること

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?