interfaceを使用して、Switch文を多用したコードの可読性を上げる方法を記載します。
サンプルコード
ワンちゃんの種類に応じて、可愛さ、攻撃力、知名度を返す関数を考えます。
ワンちゃんの種類はDogType
のEnumに定義し、Dog
クラスの各関数がそれぞれ値を返します。
package org.example.interfaceExample;
public enum DogType {
kyabaria,
tiwawa,
doberman
}
package org.example.interfaceExample;
public class Dog {
public int cutePoint(DogType dogType) {
switch (dogType) {
case tiwawa -> {
return 5;
}
case kyabaria -> {
return 100;
}
case doberman -> {
return 1;
}
default -> {
return 0;
}
}
}
public int attackPoint(DogType dogType) {
switch (dogType) {
case tiwawa -> {
return 2;
}
case kyabaria -> {
return -50;
}
case doberman -> {
return 1000;
}
default -> {
return 0;
}
}
}
public int popularity(DogType dogType) {
switch (dogType) {
case tiwawa -> {
return 1000;
}
case kyabaria -> {
return 1;
}
case doberman -> {
return 20;
}
default -> {
return 0;
}
}
}
}
package org.example;
import org.example.interfaceExample.Dog;
import org.example.interfaceExample.DogType;
import org.example.voExample.*;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
var dog = new Dog();
System.out.println("kyabaria cutePoint " + dog.cutePoint(DogType.kyabaria));
System.out.println("kyabaria attackPoint " + dog.attackPoint(DogType.kyabaria));
System.out.println("tiwawa cutePoint " + dog.cutePoint(DogType.tiwawa));
}
}
kyabaria cutePoint 100
kyabaria attackPoint -50
tiwawa cutePoint 5
上記プログラムは動作しますが、保守性を考えると問題があります。まず3つの関数にSwitch文が重複しています。また犬の種類が追加された際にはDogType
に追加された際には、各関数にそれぞれパターンを追加しないといけませんが、うっかり忘れる可能性があります。これらの問題をinterfaceを使用する事で解消することが出来ます。
まずDog
interfaceを作成し、必要な関数を定義します。
package org.example.interfaceExample;
public interface Dog {
int cutePoint();
int attackPoint();
int popularity();
String name();
}
次に犬の種類ごとにクラスを作成し、Dog
interfaceを実装するようにします。
package org.example.interfaceExample;
public class Kyabaria implements Dog{
@Override
public int cutePoint() {
return 100;
}
@Override
public int attackPoint() {
return -50;
}
@Override
public int popularity() {
return 1;
}
@Override
public String name() {
return "kyabaria";
}
}
package org.example.interfaceExample;
public class Tiwawa implements Dog{
@Override
public int cutePoint() {
return 5;
}
@Override
public int attackPoint() {
return 2;
}
@Override
public int popularity() {
return 1000;
}
@Override
public String name() {
return "tiwawa";
}
}
package org.example.interfaceExample;
public class Doberman implements Dog {
@Override
public int cutePoint() {
return 1;
}
@Override
public int attackPoint() {
return 1000;
}
@Override
public int popularity() {
return 20;
}
@Override
public String name() {
return "doberman";
}
}
interfaceを使用する事で、重複したswitchをなくすことができました。また、必要な関数を定義できていない場合には、コンパイラが見つけてくれるようになります。
実際にクラスを使用する場合には次のようになります。
package org.example;
import org.example.interfaceExample.*;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Dog> dogs = List.of(new Kyabaria(), new Tiwawa(), new Doberman());
dogs.forEach(dog -> {
System.out.println(dog.name()
+ " cutePoint " + dog.cutePoint()
+ " attackPoint " + dog.attackPoint()
+ " popularity " + dog.popularity());
});
}
}
Kyabaria
、Tiwawa
、Doberman
を全て同じDog
型として扱っています。このように異なるクラスを同じ型として扱う仕組みを多態といいます。多態を使用する事でswitchなどを用いた条件をすっきりとまとめることができます。