Flutterのグローバル変数とシングルトンの使い方を完全ガイド!初心者でもわかる状態管理の基本
生徒
「Flutterでアプリ全体からアクセスできる変数ってどうやって作るんですか?」
先生
「Flutterでアプリ全体に渡って変数を共有したい場合は、グローバル変数やシングルトンという仕組みを使う方法があります。」
生徒
「どっちを使えばいいんですか?違いがよくわからなくて…」
先生
「ではFlutterでのグローバル変数とシングルトンの違いや使い分け方を、丁寧に見ていきましょう!」
1. Flutterにおけるグローバル変数とは?
Flutter(フラッター)でグローバル変数とは、アプリ全体のどこからでもアクセスできる変数のことです。main.dartなどのファイルで、関数やクラスの外に変数を定義することで、どのウィジェットや関数からでも参照・変更が可能になります。
ただし、グローバル変数は使い方を誤ると予期しないバグや状態の不整合を引き起こす可能性があるため、注意が必要です。
例えば次のように定義します。
String username = "ゲストユーザー";
この変数は、他のファイルからでもそのままアクセス・書き換えが可能です。便利ですが、設計には気をつけましょう。
2. グローバル変数のメリットとデメリット
メリット:
- アプリ全体から簡単にアクセスできる
- 状態管理ライブラリを使わずにデータ共有が可能
デメリット:
- 状態の追跡が難しくなる
- テストがしにくくなる
- 依存性注入やOOP原則から逸脱しやすい
そのため、グローバル変数の使用は一時的なデモ用や設定値などにとどめ、複雑な状態管理には適しません。
3. Flutterでのシングルトンパターンの使い方
Flutterで安全に状態を共有したい場合は、シングルトンを使うのが一般的です。シングルトンはアプリ内でただ1つのインスタンスしか存在しないことを保証する設計パターンです。
Dartでは次のようにシングルトンを作成できます:
class AppSettings {
// プライベートなコンストラクタ
AppSettings._privateConstructor();
// インスタンス保持
static final AppSettings _instance = AppSettings._privateConstructor();
// 外部からアクセスするためのgetter
static AppSettings get instance => _instance;
// 任意のプロパティ
String theme = "light";
}
使うときは以下のようにアクセスします:
AppSettings.instance.theme = "dark";
print(AppSettings.instance.theme); // dark
このように、AppSettings.instanceを通じて、どこからでも安全にアクセスできます。
Flutterを「実務レベル」で使えるようになりたい人や、 iPhone / Android両対応アプリ開発の流れをまとめて学びたい人には、 定番の実践書がこちらです。
Flutter実践開発をAmazonで見る※ Amazon広告リンク
4. シングルトンのメリットと用途
メリット:
- 状態が1箇所で管理できる
- テストがしやすい
- 設計として明確
よくある用途:
- アプリ全体で共有したい設定情報(ダークモードなど)
- ユーザー情報
- APIクライアントのインスタンス
Flutterアプリで複数の画面間に共通データを持ちたいとき、シングルトンはとても有効な手段です。
5. ProviderやRiverpodとの使い分け
FlutterではProviderやRiverpodといった状態管理ライブラリもよく使われます。これらはリビルドの最適化や依存注入が簡単に行えるため、アプリが複雑になる場合は導入が推奨されます。
しかし、次のようなケースではシングルトンで十分なこともあります:
- 状態が少なく頻繁に変わらない
- アプリ規模が小さい
- 外部ライブラリを使いたくない
逆に、UIの再構築が頻繁に発生するような場合はChangeNotifierやStateNotifierなどを活用しましょう。
6. シングルトンのバリエーション:Lazy Initialization
シングルトンを必要になったタイミングで初期化する「遅延初期化(Lazy Initialization)」というパターンもあります。
class Logger {
static Logger? _instance;
Logger._privateConstructor();
static Logger get instance {
_instance ??= Logger._privateConstructor();
return _instance!;
}
void log(String message) {
print("LOG: $message");
}
}
このように書くことで、初回アクセス時にのみインスタンスが生成されます。
7. 実用例:ユーザー情報をシングルトンで保持
Flutterでログイン状態を保持する例として、以下のようなUserManagerクラスを作成することができます:
class UserManager {
static final UserManager _instance = UserManager._internal();
factory UserManager() {
return _instance;
}
UserManager._internal();
String? userId;
String? userName;
void login(String id, String name) {
userId = id;
userName = name;
}
void logout() {
userId = null;
userName = null;
}
}
アクセス例:
UserManager().login("u123", "山田太郎");
print(UserManager().userName); // 山田太郎
8. Flutterでグローバル状態を適切に管理するには
Flutterでは、グローバル変数とシングルトンを上手に使い分けることが重要です。
- 簡単なデータや定数 → グローバル変数
- アプリ全体の共有状態 → シングルトン
- 複雑な再描画や通知が必要 → ProviderやRiverpod
アプリの規模や複雑さに応じて選ぶことで、Flutter開発がより安定し、保守性の高いコードになります。