🐈

中規模まで使えるFlutterアーキテクチャを解説

2024/10/13に公開

はじめに

Flutterでアプリケーション開発を進める中で、どのアーキテクチャを採用すべきか迷っている方も多いのではないでしょうか。

アーキテクチャの選定は、開発のスケーラビリティや保守性を考慮して選ぶことが重要です。

この記事では2年ほど実務でFlutterを触ってきた経験をもとに、中規模アプリケーションまで使えるアーキテクチャを解説します。

シンプルかつ柔軟性を持ち、今後の拡張にも対応できるアーキテクチャをご紹介するのでぜひご参考にしてください。

アーキテクチャの概要

アーキテクチャの概要

図のI/Fはインターフェースの略です。

このアーキテクチャはMVVMとレイヤードアーキテクチャを組み合わせたもので、各コンポーネントがそれぞれ役割を持ち、効率的で拡張性の高いシステムを構築することを目的としています。

以下にそれぞれの要素を詳しく説明します。

画面

画面の依存関係

画面はFlutterアプリの1画面を指します。

このコンポーネントでは、ViewModelApp Stateの情報を取得し、それをユーザーに表示します。
また、ユーザーの入力や操作をViewModelに伝える役割も果たします。

共通Widget

共通Widgetの依存関係

共通Widgetはアプリの中で複数の場所で使われる共通のUI部品です。

例えば、ボタンやヘッダーなど、複数の画面で共通して表示されるコンポーネントが該当します。
これらは、サイズや色などのプロパティをパラメータ化することで、アプリのどの部分でも柔軟に再利用できるよう設計されます。
Widget内で完結するUIロジックもここで管理されます。

ViewModel

ViewModelの依存関係

ViewModelは画面の表示内容や動作を制御する重要なコンポーネントです。

ViewModelは画面の状態を管理し、その状態が変更されると画面に通知します。
これにより、状態変化に応じたUIの更新が可能になります。
具体的には、データの取得やビジネスロジックの呼び出しを担当し、UIとバックエンドをつなぐ役割を果たします。

App State

App Stateの依存関係

App Stateはアプリケーションの起動中に保持される状態を管理するコンポーネントです。

例えば、ユーザーの認証情報やテーマ設定など、アプリ全体で共有される情報が該当します。

View Controller

View Controllerの依存関係

View Controllerは特定のUI操作に焦点を当てたコンポーネントで、画面遷移やモーダルの表示などを管理します。

ViewModelから操作指示を受け、具体的なUIイベントや処理を実行します。
この分離により、UI操作のロジックを整理しやすくなり、コードの可読性が向上します。

サービス

サービスの依存関係

サービスはユーザーのアクションから始まる一連の処理を定義する層です。

例えば、データの取得や外部APIの呼び出し、ビジネスロジックの実行などがここで行われます。
ViewModelは必要に応じてサービスを呼び出し、複雑な処理を委譲します。

モデル

モデルの依存関係

モデルはアプリケーションのドメインを表現するデータ構造を定義します。
データそのものの構造やビジネスロジックに必要な属性を持ちます。
このデータ構造は他のレイヤーに依存せず、システム全体の中心となる要素です。

リポジトリ

リポジトリの依存関係

リポジトリはデータの永続化や取得を抽象化する層です。

データベースやAPIとのやり取りを直接行わず、リポジトリを通じてデータアクセスが行われることでデータソースの変更が容易になります。
これにより、データの取得方法を柔軟に変更することが可能になります。

モジュール

モジュールの依存関係

モジュールは特定の機能を抽象化し、アプリ全体での再利用を可能にするコンポーネントです。

例えば、外部ライブラリのラップや特定の処理ロジックを隠蔽し、他のコンポーネントがモジュールの実装に依存しないようにする役割を果たします。

フレームワーク

フレームワークの依存関係

フレームワークは各レイヤーのコードの書き方や構造を標準化するためのクラスやMixinを提供します。

また、ロガーやエラーハンドリングなど、アプリ全体で必要とされる共通機能も含まれます。
これにより、アプリケーション全体の一貫性とメンテナンス性が向上します。

アーキテクチャルール

このアーキテクチャの設計においては次のようなルールが適用されます。

  • 画面ViewModelは1対1の関係であり、画面は特定のViewModelに依存します。
  • ViewModelはFlutterのUI関連パッケージを直接インポートしてはいけません。
    これにより、UIとビジネスロジックの分離が保たれます。
  • ViewModelは、単純なデータ操作の場合はサービスを経由せず、直接リポジトリを参照することが許可されます。
  • App Stateの読み取りは画面から直接行いますが、書き込みは必ずViewModelを介して行います。
  • モデルは他のレイヤーに依存してはいけません。

これらのルールに従うことで、メンテナンス性や拡張性に優れたシステムが構築可能になります。

まとめ

本記事では中規模アプリケーションまで対応可能なFlutterアーキテクチャについて解説しました。

アーキテクチャはアプリケーション開発において非常に重要です。
しかし、複数人での開発において、開発者全員がアーキテクチャに対して同じ理解をもち、ルールを守って開発し続けることは容易ではありません。
そのため、理解しやすく、かつ柔軟性のあるアーキテクチャを選ぶことがプロジェクトの成功に繋がるでしょう。

また、このアーキテクチャを採用する際のプロジェクト構成を別の記事で解説していますので、ぜひ参考にしてください。

最後に、この記事で紹介したアーキテクチャが少しでも参考になれば幸いです。

参考資料

Discussion