インタフェース
完全に理解した
2018/09/06
とりすーぷ
自己紹介
• とりすーぷ(@toRisouP)
• 株式会社バーチャルキャスト
• Unityクライアント開発
• 人類を美少女にする仕事をしてます
インタフェース
つかってる?
今回の内容
• インタフェースについて適当につらつらと語る
• クラスの継承との意味の違い
• 使いみち
• 小ネタ
Zenject要素はありません
クラスの継承とのちがい
クラスの継承
• AはBである、という属性を引き継ぐ
• is-aの関係を満たす
• 多重継承できない
• 派生クラスは基底クラスのルールを
変えることはできない
• リスコフの置換原則
インタフェースの実装
• インタフェースはわりと自由
• is-aの関係は無い
• 要求されたふるまいさえ満たせばよい
• 必ず「利用者」が存在する
• インタフェース定義は利用側が行う
インタフェースの用途
インタフェースの用途
• 疎結合化するのによく使う
• オープン・クローズ原則とか、依存関係逆転の原則とか言うアレ
• 利用側で仕様を決めることができる
• 実装の中身について利用側は知らなくていい
• 実装の詳細については別パッケージに押し付けることができる
疎結合化
疎結合化
HumanPackageのやること
• IDriveableの定義
• IDriveableを使って何をするか
疎結合化
VehiclePackageのやること
• IDriveableの実装をする
インタフェースを使うメリット
• 依存関係を整理することができる
• オープン・クローズ原則、依存関係逆転の原則を満たすことができる
• 利用側と実装側のパッケージをそれぞれ並行して作れる
• 分担作業してもあとで破綻しない
• ゲームジャムで特に有効
依存の解決
依存の解決
• インタフェースを使うと必須になる作業
• どの実装クラスを実際に使うの?
• インスタンス化は誰がして、どう管理するの?
手法いくつか
• Service Locatorパターン
• シングルトンに依存関係を書いて、
クラスが自分でシングルトンに問い合わせるやり方
• DI Containerパターン
• DIContainerが各オブジェクトのインスタンス化を管轄する手法
• Zenjectはこれ
どっちがいいのか
• 規模が小さいならService Locatorでもよい
• 実装がラクですぐ使える
• シングルトンへの依存が生まれる点に注意
• DI Containerはハイリスク・ハイリターン
• 柔軟な依存関係の制御が可能
• DI Container(Context)の管理自体がまた難しい
インタフェースの小ネタ
プロパティ
プロパティを定義する
• インタフェースは「プロパティ」の定義ができる
• 必要なパラメータがあればプロパティにしておくと良い
• 一応setもできるけど、おすすめはしない(get onlyが良い)
GetComponent
GetComponent
• GetComponentはインタフェースを指定できる
• 指定インタフェースを実装したコンポーネントがあると取得できる
• Unityの“Tag”代わりに使うこともできなくはない
拡張メソッド
拡張メソッドで機能追加
• インタフェースに拡張メソッドを追加できる
• 実装済みの関数をインタフェースに含めることができる
• traitっぽくしたりすることができる
インタフェースは実装を持てない
拡張メソッドに実装を書くことはできる
インタフェースをtraitっぽく使える
Structとインタフェース
structにインタフェース
• structにインタフェースを被せることもできる
• ただしインタフェース型に代入するとボックス化が起きる
IEquatable<T>
• Structの同値判定用のインタフェース
• 同値判定をカスタマイズできる
• 自動実装されるEquals()よりも、パフォーマンスが向上する
• Structを定義したらこれも実装しよう
実装例
• R#とかRider使ってれば、
ほぼ自動で実装してくれる
• GetHashCode()とかも
勝手に作ってくれる
明示的な実装
明示的な実装 と 暗黙的な実装
• インタフェースは「明示的な実装」ができる
• インタフェース名を指定して実装
• 暗黙的な実装と、明示的な実装とでは挙動が異なる
例
比較
暗黙的な実装 明示的な実装
比較
暗黙的な実装 明示的な実装
アクセスレベルが異なる!
暗黙的な実装
• 暗黙的な実装をした時のアクセスレベルは「public」
• そのままメソッドコールできる
明示的な実装
• 明示的な実装をした場合は、
インタフェース経由じゃないと呼び出せなくなる
• 特殊なアクセスレベルになる
まとめ
• インタフェースの用途を覚えよう
• 疎結合化するのに使える
• Zenjectを使いこなす前に、インタフェースへの理解が必須
• 意外と機能が多い
• インタフェースを使いこなせばパフォーマンス向上する場面もある

インタフェース完全に理解した