2
0

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 1 year has passed since last update.

FlutterでDIを理解する

Last updated at Posted at 2023-05-31

DIとは?

DIとはDependency Injectionの略で、日本語にすると依存性の注入です。
この言葉を聞いても「なるほど依存性の注入か!」と(僕だったら)なるわけがないのでググってみました。
記事の中には以下のことが書いてありました。

DIとは、プログラミングにおけるデザインパターン(設計思想)の一種で、オブジェクトを成立させるために必要となるコードを実行時に注入(Inject)してゆくという概念のことである。

う〜ん、、いまいちピンとこないですよね。。。
端的に言うならば、依存関係を切って実行時に外部からオブジェクトを入れるようにすることです。

依存関係って何?

いきなりですが、下のコードを見てください。

car.dart
class EngineA {
  void start() {
    print("車が走ります。");
  }

  void stop() {
    print("車が止まります。");
  }
}

class Car {
  late EngineA _engine;

  Car() {
    _engine = EngineA();
  }

  void engineOn() {
    return _engine.start();
  }

  void engineOff() {
    return _engine.stop();
  }
}

一見何の問題もなさそうですが、問題があります。
CarクラスのEngineAが故障したとしたらこのCarクラスは使い物にならなくなってしまいます。
そして、Carクラスの内部を編集してEngineAをEngineBに変更しないといけません。
そして、またEngineBクラスが故障したら、EngineCに、、、、って大変ですよね!
てか、そんなことやりたくないですよね?(少なくても俺はやりたくない。。。)
このめんどくさい関係が依存関係であり、CarクラスはEngineAクラスに依存しています

例えば、このめんどくさい依存関係が人間関係だったらどうしますか?
すぐに依存関係を切り離しますよね?(中にはずっと依存するような人もいるかもしれないが、、、、)

それがDIです。
(テストがしやすいとか、オブジェクトを差し替えて注入するだけで良いとかメリットはいっぱいあるけど、
それよりも、まず依存してるの嫌じゃない??)

DIしようぜ!!

まずは、Engineという抽象クラスが必要です。(Engineという概念を定義しよう。)
抽象クラスを定義する際はabstractキーワードを指定します。
インターフェースを作成しておく感じです。

engine.dart
abstract class Engine {
  void start();
  void stop();
}

そして、Carクラスの引数は抽象クラスであるEngineに変更しよう。

car.dart
class Car {
  late Engine _engine;
  Car(this._engine);
  
  void engineOn() {
    return _engine.start();
  }

  void engineOff() {
    return _engine.stop();
  }
}

engine.dartで実装したインターフェースの実際の処理はEngineAに移譲します。

engineA.dart
class EngineA implements Engine{
  @override
  void start() {
    print("エンジンAの車が走ります。");
  }

  @override
  void stop() {
    print("エンジンAの車が止まります。");
  }
class EngineB implements Engine{
  @override
  void start() {
    print("エンジンBの車が走ります。");
  }

  @override
  void stop() {
    print("エンジンBの車が止まります。");
  }
}

エンジンAの車の時はEngineAインスタンスをポイってしてあげて、エンジンBの時はEngineBのインスタンスをポイってしてあげるだけでOKです。

main.dart
void main() {
  final car = Car(EngineA());
  car.engineOff();//エンジンAの車が止まります。
}

これで綺麗に依存関係を切り離すことができました。

さいごに

お腹減った。。。。
では、次の記事でお会いしましょう。

2
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?