本エントリではデザインパターンの一つである「Singleton」をFlutterアプリで実装する方法を説明する。
Singletonパターンとは
あるクラスのインスタンスが一つだけ生成されること。
インスタンスが一つだけしか存在しないため、インスタンスが管理する変数などへのアクセス経路も管理しやすい。
使用ケース
Singletonは以下のようなケースで使用されることが多い。
- クラスのサイズが大きいケース
- 設定情報やログ情報など、情報を単一にまとめることに意味のあるケース
使用する際の注意
ただしSingletonはアンチパターンと考えられる場合もあるので、利用する際には注意してほしい。
アンチパターンとして扱われている理由としては例えば「インスタンスが一つなので、モックのインスタンスが作成できずunit testがやりにくい」、といった点が挙げられる。
Flutterアプリでの実装例
例としてアプリケーション上の画面の設定情報をSingletonクラスで作成する。
仮の設定項目としては
- 言語(日本語or英語)
- ダークモード(有効or無効)
- 文字サイズ(10 ~ 30の整数)
があるものとする。
コード
作成したクラスは以下。
ポイント
Singletonクラスを実装する上でのポイントは以下。
以下で順に説明する。
factoryキーワードをコンストラクタの前に記述する
factory
キーワードを使用することでコンストラクタが呼ばれた際に既存のインスタンスを返却している。
なので一度SettingInfo
のインスタンスが生成されると、以降の呼び出しでは既存のインスタンスが返却されるようになるので、結果として何度コンストラクタを呼ばれてもアプリケーション内でインスタンスを一つにすることができる。
factoryキーワードについて
factory
キーワードは必ずしもコンストラクタが呼ばれた際に毎回新しいインスタンスを返すわけではない場合に使用する。このキーワードがコンストラクタの前に記載されていない場合、コンストラクタで値をreturn
することはできない。
_internal()コンストラクタを用意する
クラス内で使用する名前付きコンストラクタを用意する。分かりやすく_internal()
と命名することが多い。
このコンストラクタはprivateにするため先頭にアンダーバーを記述する。
クラス内で生成するクラスはprivateにする
クラス外からのインスタンス取得は全てfactory
コンストラクタを経由させたいので、クラス内に生成したインスタンスはprivateにする必要がある。
そこでインスタンス名の先頭にアンダーバーを記述する。