【Flutter・Dart】DartにおけるAbstract・抽象クラスの理解を深める

Flutter基礎

Flutter × Clean Architectureを現場や個人で使用していて、Abstractを時々拝見します。
意味を理解し今後もうまく活用できればと思いまとめました。

下記のような観点で基本的な理解を深めたいかたは、ぜひご覧ください。

この記事でわかること

  • Abstractの基本・基礎的な理解
  • Abstractの簡単な使用方法(Clean Architecture)

Abstractとは

Abstractとは、Dartにおいて、「インスタンス化できないクラス」を定義するためのキーワードです。

  • 使用する目的:
    • クラス設計上、「共通のインターフェース(型)」として扱うため
  • 特徴:
    • メソッドの実装を省略できる(中身のない関数定義だけ)
    • インスタンス化できない
    • implements や extends で具体クラスに引き継がれて実装される

使用する3つのモチベーション

  • 依存の整理
    • UI層・ドメイン層がインフラ層(Firebaseなど)に依存しない構造にする
  • テスト容易性
    • 実装を差し替えてテスト用のモックに置き換えやすくする
  • スケーラビリティ
    • 実装を簡単に切り替えられるようにして将来の変更に強くする

Abstractの使用例

シチュエーション

  • Flutter × Clean Architecture
  • FirebaseのAuthを監視する
  • RiverpodのProviderで管理する

Abstractを今回使う理由

  • Data層とPresentation層を繋ぐため(疎結合にする)
  • 別のDB(例: supabase)に切り替えても汎用できるようにするため

Data層のFirebaseのAuth情報取得

  • 実際の取得関数をData層で管理(authStateChanges)
  • implementsを使用してAuthRepository(Abstractを使用した抽象クラス)を使用
// FirebaseのAuthの状態を取得
class FirebaseAuthRepositoryImpl implements AuthRepository {
  @override
  Stream<User?> authStateChanges() {
    return FirebaseAuth.instance.authStateChanges();
  }
}

今回の中継役となる抽象クラス

Abstractを使用しData層とPresentation層の中継をする

// FirebaseAuthのData層とPresentation層の間のインターフェース
abstract class AuthRepository {
  Stream<User?> authStateChanges();
}

Presentation層で使用するProvider

UIに渡すためのProvider(Riverpodを使用)

// 中継役を型としたProvider
final authRepositoryProvider = Provider<AuthRepository>((ref) {
  return FirebaseAuthRepositoryImpl();
});

// 実際のxx_page.dartから呼ぶ出すためのStreamProvider(上記Providerを使用)
final authStateProvider = StreamProvider<User?>((ref) {
  return ref.watch(authRepositoryProvider).authStateChanges();
});

まとめ:Abstractを使うメリット

  • 実装に依存せずUI側のコードを書ける(柔軟性アップ)
  • テストのためにMockに差し替え可能(テスト性アップ)
  • Clean Architecture的な設計と相性が良い(保守性アップ)

最後に

Abstractを使用することで下記のようなメリットあります。

  • テストが容易に
  • 依存関係が整理しやすく
  • 別のサービスに展開する汎用性が上がる

ただ個人開発などの小さいアプリでは不要かもですが、実務や汎用性を高めたいアプリ開発においては、必要かもで理解しとくと便利かなと思います。

ではまた。

コメント

タイトルとURLをコピーしました