システム開発において、密結合とか疎結合なんて言葉が使われたりします。
密結合・・システム間の構成要素の関連性が高く、結びつきが密なこと
疎結合・・システム間の構成要素の関連性が弱く、結びつきが疎なこと
プログラムを組む際にもなるべく疎結合状態を作るように・・・なんてことがよく言われますね。
で、この思想自体やその利点は私もよくわかっていたんですが、問題はこの思想に基づいたDIとかマイクロサービスの利点なんですよね。特に前者。
簡単なサンプルプログラムを動かしてDI自体がこういうものかというのはわかりました。
が、使いどころがわかりませんでした・・あえてこれ使わないといけない場面ってどんな時なのって思ったんですね。
が、年明けからのプロジェクトのテスト工程でこういう時に使うのか!というのがはっきりわかったのでメモしておきました。このプロジェクトに限らず今まで必要な時はずっと目の前にあったのですが私が気づかなかったんですよね。
DIが一番有効性を発揮するのはローカルと開発、ステージング、本番で何らかの外部サービスと連携をする時だと思います。
例えば、典型的なのは外部のAPIと繋げている時ですね。
と言いますか、ある程度のシステムになりますと、常に3〜5つの外部APIとつながっている事が普通でしょう。
で、この手のAPIですが、だいたいいつ、どの環境で同じURLを叩いてOKなんてケースは稀でしょう。
例えばAPIに利用制限がある(回数やIP的なもの、時間が限られるなんてこともあります)、データを動かしてしまうのでステージング以上じゃないと無理、などなど・・・
そうすると一般的なプログラムで書かれている場合(DI的な思想がなく、APIを直叩きしている場合)、ローカルでは動かないんですよね。これめちゃくちゃイライラします。
んで、今まで下記のような対策を取っておりました。
- ローカルでのテストができないので目視だけ(メソッド単位の単体テストだけ)
- ローカル時はその部分をコメントアウトする
- ローカルでテストする時だけ素のJSONをかく
1は対策になっていないですけどね・・・・現にローカルでは目視の確認だけになってるなんて人も多かったんですね。
2、3なんですけどこれ毎回毎回やるのものすごい大変かつ面倒臭いんですよ。
色々やっているうちに本番にローカル用の処理が入って別の不具合の原因になったり・・・・複数のAPI直さなくちゃいけないとむしろそっちの方が時間を取られるなんてケースがザラです。
先日の結合テストもそういった事が原因でテストがすげー大変だったんですね。APIの部分の修正はしなくても、APIを結局通るんで、そうなると影響する処理のローカルのテストが全部ブロックされちゃいます。
で、ふと思ったんです。
あ、API部分ラッピングして、
- ローカル環境時は生JSONを生成
- 開発、ステージングの時にはAPIを叩く
↑のように書けばOKじゃんって思ったんです。
もともとローカルと開発、ステージングを条件分岐で分けるようなことはしてました。これが最善策だと思ってんですが、DIすれば綺麗に解決じゃないか!ってようやくDIの使いどころがわかりました。
ようはレスポンスの型、IFは同じなんだから内部を隠してしまって見えないようにすればいいじゃん・・実クラス自体は環境設定ファイルで分けて、ローカル用とそれ以外用のクラスをまさしく注入すればって思ったんですよ。
開発やっててなんらかの思想で衝撃を受けることってなかなかないんですけどDIの使いどころがわかった時は本当に目からウロコが落ちた瞬間でした。ずっと目の前にあったのねと・・・
そういえば昨年の夏に働いてた現場では一部、外部サービスとの連携部分をマイクロサービス化してたんですね。そのせいで確かにその部分のテストが楽でした。
私が今携わっているプロジェクト自体はかなり進行しており、DI的な思想でソースを書き直すことは結局叶わなかったんですが、今後はどこかで使っていければと思います。
というか、外部サービスと接続していないサービスなんて探す方が難しいですからね。
これAPIで言いましたけど、他の部分でもローカルと他の環境でクラスの内部が変わるものだったらなんでも使えますね・・
これからはガリガリ使って楽しいDI(orマイクロサービス)ライフを送りたいと思います。