Chapter 05

第五章 分岐する条件と振る舞いの関連について考える

kuramapommel
kuramapommel
2021.04.24に更新

条件により確定する振る舞い

ここで、 WEAPON_TYPE を条件に分岐した時の振る舞いに着目してみます
WEAPON_TYPE は下記 2 点の振る舞いを起こすための条件に使われていることがわかるかと思います

  • 「攻撃」の振る舞いのため
  • 武器種名を取得する振る舞いのため
// 前の章のコードと同じです

function attack(type: WEAPON_TYPE) {
  // 「攻撃」の振る舞いのため
  switch (type) {
    case WEAPON_TYPE.LONG_SWORD:
      console.log("太刀で攻撃")
      return

    case WEAPON_TYPE.DUAL_BLADES:
      console.log("双剣で攻撃")
      return

    case WEAPON_TYPE.BOW:
      console.log("弓で攻撃")
      return
  }
  
  return
}

function getName(type: WEAPON_TYPE): string {
  // 武器種名を取得する振る舞いのため
  switch (type) {
    case WEAPON_TYPE.LONG_SWORD:
      return "太刀"

    case WEAPON_TYPE.DUAL_BLADES:
      return "双剣"

    case WEAPON_TYPE.BOW:
      return "弓"
  }
  
  return
}

もうちょっと具体的にいうと、 WEAPON_TYPEBOW である時、それぞれの関数が呼ばれたときの振る舞いは下記のように 確定 します

関数 振る舞い
attack "弓で攻撃" とログに出力する
getName "弓" という文字列を取得する

つまり、この二つの 振る舞いを何かひとつのものでまとめる ことができて、 WEAPON_TYPE での分岐ではどの 「まとまり」 を使うのかを決めるだけにとどめます
図で表現するとわかりやすいかもしれません

./images/image01.png
武器ごとの振る舞い「まとまり」を作って、条件分岐でどの「まとまり」を使うかを決定する図

( zenn さん svg 使えないんすね、、、)

このイメージ通りに実装できれば WEAPON_TYPE での分岐を一回にすることができそうですね

[余談] enum に振る舞いをもたせることができる Java とかいう言語

いきなり Java の話になっちゃいますが、 Javaenum はなかなか便利で、固定ではありますが振る舞いを持つことができるんですよね

// ちょっと応用編な内容なので、
// 何やっているかわからない場合は
// 読み飛ばして次の章に行っちゃって ok です!

public class Main {
    public static void main(String[] args) throws Exception {
        var weaponType = WEAPON_TYPE.DUAL_BLADES;
        
        // "双剣で攻撃" とログに出力する
        weaponType.attack.run();

        // "双剣" という文字列を取得する
        var name = weaponType.name;
        System.out.println(name);
    }

    private enum WEAPON_TYPE {
        // enum の定義それぞれが「振る舞い」を持つことができる
        LONG_SWORD(
            () -> System.out.println("太刀で攻撃"),
            "太刀"
            ),
        DUAL_BLADES(
            () -> System.out.println("双剣で攻撃"),
            "双剣"
            ),
        BOW(
            () -> System.out.println("弓で攻撃"),
            "弓"
            );
        
        public final Runnable attack;
        
        public final String name;
        
        private WEAPON_TYPE(
            Runnable attack,
            String name
            ) {
            this.attack = attack;
            this.name = name;
        }
      
    }
}

とはいえ今回は極力 特定の言語の仕様に引きずられない ように解説していきますので、他のアプローチを考えてみましょう