🍼
【Dart】DIコンテナなしで依存性の逆転してみる
まえがき
私は普段業務でJavaかKotlinとSpringBootの組み合わせで開発を行っています。
個人開発では最近Flutterでアプリを作り始めています。DartでもDIというか、依存性の逆転を実現したいと思いました。どうやらDartにはDIコンテナは無いみたいなので自力でやってみようと思います。
実装してみる
抽象クラス
抽象クラスに具象クラスのインスタンスを持つことにしました。
// 抽象クラス、抽象クラスでインスタンスを保持する。
abstract interface class CalcService {
int add(int a, int b);
int subtract(int a, int b);
int multiply(int a, int b);
int divide(int a, int b);
// 具象クラスの入れ物
static late final CalcService _instanse;
static void inject(CalcService inst) {
_instanse = inst;
}
static CalcService getInstace() {
return _instanse;
}
}
具象クラス
抽象クラスを実装した具象クラスです。
// 具象クラス
class CalcServiceImpl implements CalcService {
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int multiply(int a, int b) {
return a * b;
}
int divide(int a, int b) {
return (a / b) as int;
}
}
初期化
初期化では具象クラスのインスタンスの生成を行います。
生成したインスタンスは抽象クラスがもつフィールドに入れておきます。
// アプリケーションが起動するときに呼ばれる
class Initializer {
void init() {
// 具象クラスのインスタンスを抽象クラスにセットする。
// 依存性の注入
CalcService.inject(CalcServiceImpl());
}
}
CalcServiceを使う
void main() {
// 初期化(依存性の注入)
Initializer().init();
// 抽象クラス経由でインスタンスを取得する。
final CalcService service = CalcService.getInstace();
// インスタンスを使う
print(service.add(1, 1));
print(service.multiply(4, 2));
}
クラス図
なんで依存性の逆転したかったんだっけ?
バックエンドの実装がFirebaseだったり、Supabaseだったり、自分でSpring使って実装したり、さまざまな構成を試した見たくて、実装が変わる可能性があったからです。
あくまでバックエンドの勉強のために差し替えるだけですが。
バックエンドの勉強なので、「バックエンドを変えたから、画面のコードにも手を入れないと!」なんてならないためです。
今回のパターンだとCalcServiceImplとInitializerを書き換えればバックエンドは差し替えることができますね。
所感
Spring FrameworkのDIコンテナってやっぱりすごい!
Discussion