4.8. インターフェースを適切に使う
『目的』
適切なインターフェースを使用して変更の影響を最小限にとどめましょう。
『Before』
これは、型で変数を宣言しています。
public HashMap getHogeMap() {
HashMap map = new HashMap();
map.put("hogeKey", "bar");
return map;
}
HashMap map = getHogeMap();
:
HashMap map = getHogeMap();
:
インターフェースの特定の実装の型を使って変数を宣言すると、
後で実装を変更するのが困難になってしまいます。
たとえば、HashMapではなくIdentityHashMapを使うことになったとします。
変更はこうなります。
public IdentityHashMap getHogeMap() { // 修正
IdentityHashMap map = new IdentityHashMap(); // 修正
map.put("hogeKey", "bar");
return map;
}
IdentityHashMap map = getHogeMap(); // 呼び出し側も修正
:
IdentityHashMap map = getHogeMap(); // 呼び出し側も修正
:
型を直すことになるので宣言部を全て直す必要が生じてしまいますね。
修正箇所がふくれあがってしまうわけです。
『After』
では、インターフェースを使って宣言した場合を見てみましょう。
これは、インターフェースで変数を宣言しています。
public Map getHogeMap() {
Map map = new HashMap();
map.put("hogeKey", "bar");
return map;
}
Map map = getHogeMap();
:
Map map = getHogeMap();
:
HashMapではなくIdentityHashMapを使うことになったとします。
変更はこうなります。
public Map getHogeMap() {
Map map = new IdentityHashMap(); // 修正
map.put("hogeKey", "bar");
return map;
}
Map map = getHogeMap();
:
Map map = getHogeMap();
:
修正は1箇所で済みました。
HashMapとIdentityHashMapは、クラス固有のメソッドを有していないのでこの方法を適用すべきです。
ですが、インターフェースで定義されたメソッドに加えてクラス独自のメソッドを利用しているものは、
この限りではありません。
『まとめ』
適切なインターフェースがあるのならば、パラメータ・返値・変数・フィールドは
すべてインターフェースを使って宣言してください。インターフェースで宣言すれば、
変更の必要が生じても最小限の修正で済みますし、柔軟になります。
適切なインターフェースがないときは、クラスの型で宣言してください。