シングルトンの作成
ここでは Dart でシングルトンを実装する方法について説明します。
シングルトンとは?
シングルトンというのは Dart 特有のものではなく、ソフトウェアのデザインパターンの1つです。 シングルトンパターンといえば、「あるクラスのインスタンスをアプリケーション内でひとつになるように制限する」ことをいいます。
一般的に (多くの言語では)、あるクラスをシングルトンとして実装するには、次のように実装します。
- クラスのスタティックメンバとしてインスタンスのキャッシュを保持する。
- コンストラクタへのアクセスを制限する。
- インスタンスのキャッシュを返すメソッドを実装する。(この場合この働きをするメソッドのことを「ファクトリーメソッド」といいます)
シングルトンは複数のインスタンスがあると都合が悪い状況、例えば、アプリケーショングローバルの状態管理、データストアの作成などで使われます。
Dart でのシングルトンの実装
Dart では、コンストラクタに factory とマークすることによって、ファクトリーメソッドを実装することが可能になります。
具体例は次のようになります。
次の例では MyStore という名前のクラスは、シングルトンとして実装されています。
class MyStore {
static final Map<String, dynamic> _items = <String, dynamic>{};
static final MyStore _cache = MyStore._internal();
MyStore._internal();
factory MyStore() {
return _cache;
}
set(String key, dynamic data) => _items[key] = data;
get(String key) => _items[key];
}
コンストラクタは factory と指定されています。また、MyStore._internal() としてデフォルトのコンストラクタをプライベートアクセスにしています。
これを使う側は次のようになります。
void main() {
var store1 = MyStore();
store1.set('name', 'Dart Taro');
store1.set('age', 30);
print(store1.get('name'));
print(store1.get('age'));
print('---');
var store2 = MyStore();
print(store2.get('name'));
print(store2.get('age'));
}
この実行結果は次のようになります。
Dart Taro 30 --- Dart Taro 30
呼び出し側をぱっと見ただけでは、store1 と store2 で、2つのインスタンスを作成しているように見えますが、 実際には実行結果のように、全く同じインスタンスにアクセスできています。