#背景
会社でDI(Dependency Injection)についての話が出たが、
イマイチちゃんと分かっていなかったのでお勉強することにした
#そもそもDIって何よ
・依存性の注入(直訳)
・結合度の低下によるコンポーネント化の促進
・単体テストの効率化
・特定のフレームワークへの依存度低下
・DIコンテナってのがあるらしい(へぇ)
個人的には、単体テストがしやすくなるってところに惹かれた。
後、実装時に(見かけ上)コンポーネント化されたとしても、
各々依存しあってたらあまりメリットないもんね。
(筋子じゃダメなんだ、いくらでないとダメだ、というイメージは本当に無駄)
#早速書いてみる
何はともあれ、書いてみる。
まずは、依存しまくっている例。
class Country:
def getCountry(self):
return "Japanese"
class Position:
def getPosition(self):
return 'SuperStar'
class HorseName:
def getName(self):
return 'Caesario'
class GreatRealCondition:
def __init__(self):
self.c = Country()
self.p = Position()
self.h = HorseName()
def getGreatRealCondition(self):
return self.c.getCountry() + "\n" + self.p.getPosition() + "\n" + self.h.getName() + "!"
if __name__ == '__main__':
g = GreatRealCondition()
print(g.getGreatRealCondition())
Japanese
SuperStar
Caesario!
何の文章か分からない方はyoutubeで
「ジャパニーズスーパースターシーザリオ!」で検索。
GreatRealConditionクラスは、
・Countryクラス
・Positionクラス
・HorseNameクラス
これらのクラスと密な関係(三密)になっている。
ということは、これらのクラスは、バラバラに見えて、実はほぼ一つのクラスである、と言える。
再利用も出来ないし、そもそもテストも出来ない(値を変えてみたり、なんてことは今のところ出来ない)。
Countryクラスなどにセッターを入れれば値を変えることはできるが、もはやGreatRealConditionクラスのテストではないよね。
なので、依存度を下げてみる。
class Country:
def getCountry(self):
return "Japanese"
class Position:
def getPosition(self):
return 'SuperStar'
class HorseName:
def getName(self):
return 'Caesario'
class GreatRealCondition:
def __init__(self, c: Country, p: Position, h: HorseName):
self.c = c
self.p = p
self.h = h
def getGreatRealCondition(self):
return self.c.getCountry() + "\n" + self.p.getPosition() + "\n" + self.h.getName() + "!"
if __name__ == '__main__':
c = Country()
p = Position()
h = HorseName()
g = GreatRealCondition(c, p, h)
print(g.getGreatRealCondition())
Japanese
SuperStar
Caesario!
先ほどと同じ結果になった。
ここで大きく変わったことは、
GreatRealConditionクラスが他クラスを持たなくなったこと
に尽きる。
さっきまで、3密クラスに依存していて、他に使い道がなかったGreatRealConditionクラスが、
コンストラクタで3密クラスを持たせるようにすることで、いろんな用途が出来た。
(本当はいろんなパターンで試そうと思ったのだが、長くなりそうなのでまた今度)
とまあ、コンストラクタを使って、「依存性を注入」したわけです。
最初はこんな感じ。
#今後
今回はコンストラクタを使用して注入したんだけど、
setterで注入だったり、インタフェース定義して注入したりといろいろ方法があるみたいなので是非試してみようと思います。
あと、pythonだと結構DIめんどいかも。
(慣れてないだけか)
#Thanks!!
参考になった記事はこちらです。
ありがとうございます。
https://qiita.com/mkgask/items/d984f7f4d94cc39d8e3c