DIとは?
DIとはDependency Injectionの略で、日本語にすると依存性の注入です。
この言葉を聞いても「なるほど依存性の注入か!」と(僕だったら)なるわけがないのでググってみました。
記事の中には以下のことが書いてありました。
DIとは、プログラミングにおけるデザインパターン(設計思想)の一種で、オブジェクトを成立させるために必要となるコードを実行時に注入(Inject)してゆくという概念のことである。
う〜ん、、いまいちピンとこないですよね。。。
端的に言うならば、依存関係を切って実行時に外部からオブジェクトを入れるようにすることです。
依存関係って何?
いきなりですが、下のコードを見てください。
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キーワードを指定します。
インターフェースを作成しておく感じです。
abstract class Engine {
void start();
void stop();
}
そして、Carクラスの引数は抽象クラスであるEngineに変更しよう。
class Car {
late Engine _engine;
Car(this._engine);
void engineOn() {
return _engine.start();
}
void engineOff() {
return _engine.stop();
}
}
engine.dartで実装したインターフェースの実際の処理はEngineAに移譲します。
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です。
void main() {
final car = Car(EngineA());
car.engineOff();//エンジンAの車が止まります。
}
これで綺麗に依存関係を切り離すことができました。
さいごに
お腹減った。。。。
では、次の記事でお会いしましょう。