LoginSignup
11
6

More than 5 years have passed since last update.

基本的に、Interface の名前を I(名前) とか、(名前)Interface とかするのやめよう。

Posted at

皆さん命名規則守ってますか?
分かりやすいコードを書くためには必要ですよね。

今回は命名規則の中でも、Interfaceについて考えてみましょう。

※タイトルでは言い切ってますが、結局自分たちが書きやすい方法が正解です。
一つ、規約について考えるきっかけにしてみてくださいな。

本題の前に、よく見るサンプルの書き方

多くのプログラミング言語で使用されるInterfaceですが、
皆さんどのように名前つけてますか?

IとかInterfaceをつける書き方

例えばHogeというクラスがあったとして、このクラスにつけるInterfaceを作るとすると、

例1
public class Hoge implements IHoge {
    public void doSomething() {
        // 何かする
    }
}

public interface IHoge {
    void doSomething();
}

とか、

例2
public class Home implements HogeInterface {
    public void doSomething() {
        // 何かする
    }
}

public interface HogeInterface {
    void doSomething();
}

とか、こんな感じですかね?
(サンプルはJavaで書きます)

Hogeクラスにつけるインタフェースですから、

  • 頭にIをつける
  • おしりにInterfaceをつける

のどちらかをして、インタフェースだと分かるようにしておきましょうと。

まぁこれはいいでしょう。特に文句ないですね。

IとかInterfaceをつける書き方その2

ではこれだとどうでしょう?

例3
public class Dog implements DogInterface {
    public void walk() {
        // 歩く
    }

    public void run() {
        // 走る
    }
}

public interface DogInterface {
    void walk();
    void run();
}

あぁっ!? さっきと同じなのに、なんか気持ち悪い!
となりますよね?なりませんか?

では、こう書いたらどうでしょう?

例4
public class Dog implements Animal {
    public void walk() {
        // 歩く
    }

    public void run() {
        // 走る
    }
}

// 同じ機能を持った猫も作れる!
public class Cat implements Animal {
    public void walk() {
        // 歩く
    }

    public void run() {
        // 走る
    }
}

// Interfaceの名前を、より適切にする
public interface Animal {
    void walk();
    void run();
}

Interfaceの名前をAnimalにしたことによって、
Catのクラスに継承しても違和感が無い状態になりました。

問題の書き方

ここまで納得いただけたでしょうか。
では、次に今回問題にしたい書き方。

例5
public class Dog implements AnimalInterface {
    public void walk() {
        // 歩く
    }

    public void run() {
        // 走る
    }
}

public class Cat implements AnimalInterface {
    public void walk() {
        // 歩く
    }

    public void run() {
        // 走る
    }
}

// 末尾に Interface をつける
public interface AnimalInterface {
    void walk();
    void run();
}

一つ目と二つ目のハイブリッドみたいな形ですね。
この書き方はどうでしょうか。

特に問題なさそうですか?
ではこのAnimalInterfaceを実際に呼び出してみましょう。

例6-1
// メソッドだけ抜き出し
public void doSomething(){
    AnimalInterface dog = new Dog();
    dog.walk();
}
例6-2
public interface Cage(){    // カゴ(檻)ですね
    void add(AnimalInterface animal);    // カゴに動物を追加
}

どちらの例にしても、ここで欲しいのは動物です。
それがInterfaceであるかどうかは、呼び出し側からしてみれば「どうでもいい」情報です。

そうではなく、

例7-1
// メソッドだけ抜き出し
public void doSomething(){
    Animal dog = new Dog();
    dog.walk();
}
例7-2
public interface Cage(){
    void add(Animal animal);
}

このほうが見通しが良い訳です。
それに(こっちの方が重要ですが)呼び出し側が、呼び出すものがInterfaceかどうかなんて気にしなくてすみます。
ですから、Interface名にI(名前)とか、(名前)Interfaceとするのは、
基本的に余り良くないだろう、と言う事です。

HogeInterfaceの書き方は本来のInterfaceの書き方ではない?

そもそも、なぜInterfaceとかをつけるとかつけないとか、そんな話になったのでしょうか。
そうです。最初に挙げた、Hogeクラスに対してInterfaceをつける場合、
クラスとインタフェースを区別するためにHogeInterfaceとします、というお話からです。

そもそも、Interfaceは、ある事象に対して、それが実装するべき内容を定義するためのものですから、
ある一つのクラスの為だけにInterfaceが作られるという事自体が稀な事なのかもしれません。

例えばDogという実装を書く場合InterfaceとしてAnimalを定義する事と、DogInterfaceを定義する事は、明らかに別の事になります。
どちらも今回はDogクラスの為に定義されているものの、

  • Animal: 扱うべき存在の抽象概念についての定義
  • DogInterface: Dogクラスという具体的存在についての定義

であり、定義している内容に違いがあると言う事です。

Interfaceの本来の役割から考えると、扱う存在の抽象概念を定義する使い方の方が、この場合、より適切でしょう。
よって、Hogeという具体的なクラスが存在する前提で作られているHogeInterfaceは本来の使い方から少しずれた使い方なのです。

IとかInterfaceを、つけてはいけないのか?

では、IHogeとかHogeInterfaceのような書き方はあり得ないのでしょうか?

いえ、これが必要になるパターンがありますね?

そうです。DIです。

DIする場合には、互いの依存を切り離すために、Interfaceを介してやりとりする場合がほとんどです。
この時、注入されるべきは明らかにDogである部分に対してAnimalインタフェースを使ってしまうとCatクラスを注入されてしまう可能性があります(Dogにしかないメソッドを実行させたい場合などは、そもそもコンパイルが通りませんね)。

よって、このような場合ではDogInterfaceを介してやりとりさせることで、確実にDogが入ってくることを保証できます。

まとめ

  • 基本的にInterfaceを作る際にはI(名前)とか(名前)Interfaceの形にしない
  • Interface名は扱うべき抽象概念を表した名前をつける
  • DIなど、確実にクラスと1:1で紐付いたInterfaceが必要な場合は、この限りでない

ちなみに

色々書きましたが、Javaを使ってる方ならListインタフェースとか思い出してもらったら分かりやすいですよね。
後半でInterfaceとは何か?みたいな話に突っ込んでるので、異論等々あるかと思います。
その場合は心の中で(こいつアホだな)と思うだけでなく、出来ればコメントで教えて下さい。

11
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6