はじめに
こんちわす。はじめまして、Souと申します。
遅かれながら初めて記事を書くわけですが、悩んだ挙句、自分がPGする上で一番とっつきにくかった
interfaceについて書こうと思います。そもそも明確な利点がわからなかった経験があり、同じ悩みを抱えたエンジニアはいると思います。。
では実際にコードを見ながらアプローチしていきましょう。言語はc#で書きますが、スキル的に読むのは難しくないと思いますので一緒に頑張りましょう!
利点 其の① メソッド名を強要出来る
よく聞くやつですね。最初は「それだけ??」と思うかもしれません。僕も最初はそうでした。
具体的には、"あらゆる変更に強くなる"という風に置き換えれます。
例えば商品情報をデータベースから取得するという想定で考えましょう。
商品を識別できるユニークな値「id」を引数にし、それを条件に商品情報を取得するといったモノを想定してください。
インターフェース
publicinterfaceISearchItemQuary{ItemExecute(intid);}具象クラス
publicclassSearchItemQuaryFromDataBase:ISearchItemQuary{publicItemExecute(intid){"データベースから商品情報取得処理;"}}実行クラス※使用するフレームワークであったりアーキテクチャによって実行クラスの名前は様々だと思うので今回は「Main」クラスにさせてください。
publicclassMain{privateISearchItemQuary_searchItemQuary;publicMain(ISearchItemQuarysearchItemQuary){_searchItemQuary=searchItemQuary;}//実行処理staticvoidMain(string[]args){//商品IDが1の商品情報を取得_searchItemQuary.Execute(1);}}とします。
だが、ここでパフォーマンスなどの問題があってデータベースからではなくキャッシュサーバーから取得するように変更が必要になりました。
リファクタリングを行う上で大事なのは既存の処理を出来るだけ変えないことです。変更に強くなくてはなりません。
では、さっそくキャッシュから取得するクラスを作りましょう。
publicclassSearchItemQuaryFromCache:ISearchItemQuary{publicItemExecute(intid){"キャッシュサーバーから商品情報取得処理;"}}SearchItemQuaryFromDataBaseクラスと同じインターフェースISearchItemQuaryを使用します。
これによりExecuteメソッドを強要できます。
この時点でDBとCacheで同じメソッド名を持っていることを念頭に置いてください。
これでリファクタリングは終わりです。同じインターフェースを噛ませているので、実行クラスで変える箇所はありません。
※Mainメソッドのコンストラクタの具象クラス(DBかCache)はDIコンテナで結びつけてると想定してください。
簡単に言うとインターフェースと具象クラスをアプリ起動時紐付けれるやつ。初学者の方はあまり気にしなくていいです。
利点 其の② インスタンスを柔軟に選択できる
もう既に①の例で証明できてるのですが、もう一度確認してみましょう。
publicMain(ISearchItemQuarysearchItemQuary){_searchItemQuary=searchItemQuary;}①でDBとCacheの2つのクラスを作成しましたが、前回も述べたようにクラスが増えたからといってMainクラスは何の変更もしていません。
理由はコンストラクタの引数がインターフェースで定義しているためです。
ISearchItemQuary を使用しているクラスであればこのMainクラスは誰でも使用することが出来ます。
まさに柔軟性が垣間見えた瞬間です!
まとめ
まだまだ、TDD(テスト駆動開発)におけるインターフェースの使い方や、factory method、SOLID原則など
参考になるモノはあるので、初学者の方はこの辺からアプローチしてみてはいかがでしょうか?