【Flutter/Dart】Factory Constructorsでシングルトンパターンの実装方法!

この記事からわかること
- Flutter/Dartでシングルトンパターンのの実装方法
- Factory Constructorsの特徴と使い方
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Koala
- Xcode:16.0
- Flutter:3.29.2
- Dart:3.7.2
- Mac M1:Sonoma 14.6.1
シングルトンパターンとは?
「シングルトンパターン」とはオブジェクト指向ソフトウェアの設計に関する知見やノウハウに再利用性しやすいようにまとめたGoFのデザインパターンに掲載されている1つです。その中でもシングルトンはクラスインスタンスを1つしか生成しないデザインパターンになります。
詳細は以下の記事を参考にしてください。
Dartでシングルトン設計を実装する
Dartでシングルトン設計を実装するにはfactory
を使用したコンストラクタ(Factory Constructors
)を活用します。実装のポイントになるのは以下です。
- static finalで1つのインスタンスのみを保持
- _internal()というプライベートコンストラクタで外部からのインスタンス生成を制限
- factory Singleton()で常に同じインスタンスを返す
class Singleton {
// インスタンスを保持するための static フィールド
static final Singleton _instance = Singleton._internal();
// プライベートなNamed Constructors
// _を付与しているのでprivateアクセスになる
Singleton._internal();
// factory コンストラクタでシングルトンを提供
// そのまま使えるようにSingleton()として定義
factory Singleton() {
return _instance;
}
int state = 0;
void increment() {
state += 1;
print(state);
}
}
上記のように実装することでSingleton()
でインスタンス化しても内部的には_instance
に格納されているインスタンスを取得できるようになっています。そのためincrement
を実行した場合の挙動から共通のインスタンスであることが確認できると思います。
var obj1 = Singleton(); // 内部的には_instanceを取得している
var obj2 = Singleton(); // 内部的には_instanceを取得している
obj1.increment(); // 1
obj2.increment(); // 2
print(obj1 == obj2); // true(同じインスタンス)
Factory Constructorsとは?
「Factory Constructors」とは通常のコンストラクタとは異なり新しいインスタンスを作成する必要がない場合に活用されます。なのでキャッシュしてあるインスタンスやシングルトン設計のインスタンスを返したい場合などに既存のインスタンスを返却したい場合に使用することができます。またFactory Constructorsの特徴として宣言しているクラスだけでなく、サブクラスを返すことも可能になります。
abstract class Animal {
void speak();
// サブクラス Dog や Catを返すことができる
factory Animal(String type) {
if (type == 'dog') {
return Dog();
} else if (type == 'cat') {
return Cat();
} else {
throw Exception("Unknown animal type");
}
}
}
class Dog implements Animal {
@override
void speak() => print("ワン!");
}
class Cat implements Animal {
@override
void speak() => print("にゃお!");
}
void main() {
Animal animal1 = Animal('dog'); // Dog インスタンスが返る
Animal animal2 = Animal('cat'); // Cat インスタンスが返る
animal1.speak(); // "ワン!"
animal2.speak(); // "にゃお!"
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。