Fizz Buzz問題とStrategy パターン

#問題

Fizz Buzz問題というプログラミングの練習問題があります。番号に従い、以下のように返事をするという問題です。

|  番号i        |  返事      |
|:--------------|:-----------|
| 3かつ5の倍数  |  FizzBuzz  |
| 3の倍数       |  Fizz      |
| 5の倍数       |  Buzz      |
| 上記以外      |  i         |

上記は3と5の場合です。これが一般的のようです。iが1から25までは上記の表で答えるとして、26から50は以下の表のよう変則パターンで答えるとします。

|  番号i             |  返事      |
|:-------------------|:-----------|
| 2かつ3かつ5の倍数  |  FizzBuzz  |
| 3かつ5の倍数       |  Fizz      |
| 2かつ3の倍数       |  Buzz      |
| 上記以外           |  i         |

この問題をプログラミングしてみました。

#プログラミング

一例として、Strategy パターンを使ってプログラミングしてみました。

最初にインターフェースを作ります。

```java:HumanFizzBuzzStrategy.java
package fizzbuzz;

public interface HumanFizzBuzzStrategy {
    abstract public String replyBasedOn(int i);
}
```

replyBasedOn()メソッドは番号iに対して返事の文字列を返却するメソッドです。

次に実装クラスを作ります。以下は3と5の場合のクラスです。

```java:HumanFizzBuzzStrategyStandard.java
package fizzbuzz;

public class HumanFizzBuzzStrategyStandard implements HumanFizzBuzzStrategy {

    @Override
    public String replyBasedOn(int i) {
        String s = null;

        if (i % 3 == 0 && i % 5 == 0) {
            s = "FizzBuzz";
        } else if (i % 3 == 0) {
            s = "Fizz";
        } else if (i % 5 == 0) {
            s = "Buzz";
        } else {
            s = String.valueOf(i);
        }

        return s;
    }

}
```

次は変則パターンの実装クラスです。

```java:HumanFizzBuzzStrategyCustom.java
package fizzbuzz;

public class HumanFizzBuzzStrategyCustom implements HumanFizzBuzzStrategy {

    @Override
    public String replyBasedOn(int i) {
        String s = null;

        if (i % 2 == 0 && i % 3 == 0 && i % 5 == 0) {
            s = "FizzBuzz";
        } else if (i % 3 == 0 && i % 5 == 0) {
            s = "Fizz";
        } else if (i % 2 == 0 && i % 3 == 0) {
            s = "Buzz";
        } else {
            s = String.valueOf(i);
        }

        return s;
    }

}
```

上記2つがFizzBuzzを答えるためのStrategyです。これらを使って返事を出力するクラスが以下です。

```java:HumanFizzBuzz.java
package fizzbuzz;

public class HumanFizzBuzz {

    HumanFizzBuzzStrategy strategy;

    public HumanFizzBuzz(HumanFizzBuzzStrategy strategy) {
        this.strategy = strategy;
    }

    public void setStrategy(HumanFizzBuzzStrategy strategy) {
        this.strategy = strategy;
    }

    public void sayFizzBuzzBasedOn(int i) {

        String s = strategy.replyBasedOn(i);
        System.out.println(s);

    }

}
```

以下はテストクラスです。

```java:Test.java
package test;

import fizzbuzz.HumanFizzBuzz;
import fizzbuzz.HumanFizzBuzzStrategyCustom;
import fizzbuzz.HumanFizzBuzzStrategyStandard;

public class Test {

    public static void main(String[] args) {

        HumanFizzBuzz humanFizzBuzz = new HumanFizzBuzz(new HumanFizzBuzzStrategyStandard());

        for (int i = 1; i <=25; i++) {
            humanFizzBuzz.sayFizzBuzzBasedOn(i);
        }

        humanFizzBuzz.setStrategy(new HumanFizzBuzzStrategyCustom());
        for (int i = 26; i <=50; i++) {
            humanFizzBuzz.sayFizzBuzzBasedOn(i);
        }
    }

}
```

以下、実行結果です。

```:結果
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
27
28
29
FizzBuzz
31
32
33
34
35
Buzz
37
38
39
40
41
Buzz
43
44
Fizz
46
47
Buzz
49
50
```