2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

リフレクションできないFlutterで汎用的なORMを作る方法

Last updated at Posted at 2020-04-28

Flutterだとリフレクションができないので、自作の薄いORMとが作りづらいのですが、リフレクションなしで汎用的にする方法を紹介します。
Nappsではこの方法を使ってfirestoreの薄いラッパークラスを作っています。

リフレクションできないと何が面倒なのか?

Mapから生成できるEntityBaseを用意したときに、共通のRepositoryクラスでEntityクラスのfromMapを実行しエンティティのインスタンスが取得できたら便利そうですが、スタティックメソッドをジェネリクスを使って呼び出すことはできません。またFlutterではリフレクションもできないため、直接呼び出すこともできません。

abstract class EntityBase {

   factory Entity.fromMap(Map map);

   Map toMap();
}

実際のエンティティのサンプル

 class SampleEntity extends EntityBase {
   final String name;
   
   SampleEntity({@required this.name}

   factory Entity.fromMap(Map map) => SampleEntity(name: map['name'])

   Map toMap() => {
     'name': name
   }
}

Builderクラスを使ってインスタンスを生成する

fromMapがスタティックメソッドになっているためジェネリクスに対応できないので、fromMapをインスタンスメソッドでラップしたBuilderクラスを用意します


abstract class Builder<T> {
   
   T build(Map);
}

実際のビルダークラスのサンプル


class SampleEntityBuilder extends  BuilderBase<SampleEntity> {
   
    SampleEntity build(Map map) => SampleEntity.fromMap(map);
}

Builderでラップすることで、builder.build(map)のように呼び出すことでエンティティのインスタンスを取得できるようになります

Repository

Repositoryはbuilderを受け取ることで、mapからエンティティへの変換が必要になったときに、builder.build(map)を実行するだけで、エンティティのインスタンスを取得することができます。


abstract class RepositoryBase<T extends EntityBase, S extends BuilderBase> {
   
  final S builder;

  RepositoryBase(this.builder);
}

エンティティごとに用意するコード

エンティティごとに用意するコードをまとめると下記の3つになります

 class SampleEntity extends EntityBase {
   final String name;
   
   SampleEntity({@required this.name}

   factory Entity.fromMap(Map map) => SampleEntity(name: map['name'])

   Map toMap() => {
     'name': name
   }
}
 class SampleEntityBuilder extends  BuilderBase<SampleEntity> {
   
    SampleEntity build(Map map) => SampleEntity.fromMap(map);
}

 class SampleRepository extends  RepositoryBase<SampleEntity, SampleBuilder> {
   
    SampleRepository():  super(SampleEntityBuilder());
}

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?