[golang]Interfaceのオススメの使い方2 ~密結合を避ける~

こんにちは。KOUKIです。

とある企業でWeb系のエンジニアをしています。開発言語はGo言語です。

以前、「[golang]Interfaceのオススメの使い方」について紹介しました。

この記事が結構好評だったので、第二弾を記事にしたいと思います。

Interfaceの基礎については、以下の記事を参考にしてください!

Interfaceで密結合を避ける

今回、私がオススメするInterfaceの使い方として、「密結合を避ける」をご紹介したいと思います。

Interfaceを使わない場合

次のサンプルは、密結合が顕著なダサいコードです。

DBInfo3rdPartyは、3rdパーティー製のモジュールだと仮定してください。

このモジュールを取り込んだDBHandlerを定義しており、これをインスタンス化することで、DBの操作(Get, Delete)を可能にしています。

DBの操作メソッドを使うには、main関数内でDBNormal関数を呼び出してインスタンス化する必要があります。その際に、usernameとpasswordを渡しています。

このコードは、一見問題なく見えます。しかし、実はDBNormalにusernameとpasswordを渡してインスタンス化しているところが密結合になっています。

例えば、DBInfo3rdPartyモジュールに変更があった場合は、次の修正作業が発生します。

今回の修正は「簡単」な内容でしたが、修正すべき箇所が3つも発生しました。このようにプログラムの実装が密結合になると修正箇所があちこちに発生します。

Interfaceを使った場合

Interfaceを賢く使うと先ほどの密結合を避けることができます。

違いがお分かりでしょうか。

まず、DBInterfaceを定義しています。このInterfaceには、GetとDelete関数を定義しており、DBHandlerをインスタンス化することで暗黙的にこのInterfaceを実装することができます。なぜなら以下のメソッドを定義しているからです。

Go言語では、Interfaceに定義した関数と同じシグネチャのメソッドを実装することでInterfaceを実装したことにしてくれます(そういう仕様です)。JavaやC#ではimplementsキーワードなどが必要ですよね。

main関数内でDBHandlerをインスタンス化して、DBUseInterface関数に渡しています。DBUseInterfaceの引数をよく見て欲しいのですが、DBInterface Type(Interface)が定義されています。

これが密結合を避ける秘訣です。

先ほどと同じようにDBInfo3rdPartyに修正を加えてみましょう。

いかがでしょうか?今度は、修正箇所はたった一箇所です

Interfaceを引数に渡すメリットがお分りいただけたのではないでしょうか?

おわりに

今回のサンプルプログラムの作りはイマイチだったかもしれません。しかし、Interfaceを使って密結合を避けることの利便性はお分りいただけたのではないでしょうか?

これからもガンガンInterfaceを使っていきましょう!

それでは、また!

次回

オススメ書籍

関連記事