Goでstructのinterface実装を検証する方法
2022年04月18日 9:51
こんにちは、ISSUEの寒河江です。
日頃Goでの運用知見を貪欲に調べています。今回はGolangでstructがインターフェースの実装を満たしているかを検証する方法について記事を書いてみました。
システムの規模が大きくなると、可読性の低下などから実装漏れをしやすくなります。それがさらに可読性を悪化させる負のスパイラルとなります。
なのでstructのinterface実装漏れを防ぐなど、こういった小さなことの積み重ねが大事になってきます。
例を挙げます。下記にPerson interface、そのinterfaceの実装を満たすUser structを定義します。
出力
正常にコンパイルが通りました。
今度はPerson interfaceにGetEmail
を追加します。今度はUser structにGetEmail()
が実装されていないのでPerson interfaceを満たしません。
しかし実行してもコンパイルは通ってしまいます。
出力
本来ならここでエラーを起こしてinterfaceの実装漏れに気づきたいところです。上記は単純なコードでファイルも1つしかないので実装漏れがあることに気づくのは簡単だと思います。しかし、これが数十ファイルになったらどうでしょうか。1つ1つのstrcutがPersonのinterfaceを満たしているかを確認するのは大変な作業で効率的ではありませんよね。。
ここからが本題になります。interfaceを満たさないstructを検証する2つの方法を書いていきます。両方ともinterface実装が確認できなければコンパイルが通りません。
structをinterfaceの型指定で定義する方法です。これはUberで紹介されている方法で有名だと思います。
上記のコードを実行すると、コンパイルエラーになります。
もちろんGetEmail
を追加すると通ります。
出力
こちらの方法が一行でかけてシンプルな方法だと思います。
GetNameとGetEmailは共にレシーバーはポインタ型(*User)です。レシーバーがポインタ型でない場合は下記のような書き方で検証することができます。
2つ目の方法です。ある程度の規模のシステムではレイヤードアーキテクチャやクリーンアーキテクチャなどの構造を通ることが多いと思います。その場合、repositoryをusecaseにDIして利用するケースが多いかと思います。その際、初期化関数の返り値をinterfaceに指定することでstructを検証できます。
下記はusecase層のinterface検証になります。
こちらの方法でinterfaceの検証を行うこともできます。この方法なら、初期化とinterface検証の両方を同時に行うことができます。
handlerなど、場合によって初期化関数は作らない場合もあるかと思うので状況に応じて使い分けていただければと思います!
以上、Goでstructのinterface実装を検証する方法についてでした!
診断を受けるとあなたの現在の業務委託単価を算出します。今後副業やフリーランスで単価を交渉する際の参考になります。また次の単価レンジに到達するためのヒントも確認できます。
目次を見る