LoginSignup
0
0

More than 3 years have passed since last update.

FizzBuzzをオブジェクト指向でやってみた

Last updated at Posted at 2021-04-14

FizzBuzzをオブジェクト指向的にやってみた

Qiita始めました
記念すべき初投稿は読んで字の如くです。コロナで籠らざる得なくなった時にポリモーフィズムを勉強したので自分なりのアウトプットしようと思い立ちました。間違っていたり考えが浅かったりするかもしれませんがご愛敬です。

やってみる前に

FizzBuzzとは

英語圏せんだみつおゲームの様なもの

数人で数字を読み上げていき
3で割れる数字は「Fizz」
5で割れる数字は「Buzz」
3でも5でも割れる数字は「FizzBuzz」
を数字の代わりに読み上げる

詰まったり言い淀んだら負けという暇つぶしに丁度良さげな難度のゲームです。
先人達はこの題材で色々な縛りを課してプログラミングするみたいですが今回は特に縛りはありません。強いて言うならオブジェクト指向的にプログラミングしていきます。

オブジェクト指向的にとは

オブジェクト指向 ≒ 値や処理の塊を人の理解できる形にする表現方法
と自分は解釈しています。そのことを反映してプログラミングしていきます。
今回はJavaを使いFizzBuzzというゲームを表現してみたいと思います。

やってみよう

メイン

main.java
public class Main {
    public static void main(String[] args) {
        Game fizzBuzzGame = new Game();
        fizzBuzzGame.setCount(20);
        fizzBuzzGame.start();
    }
}

これだけです。ゲームクラスを呼び出しそのインスタンスに対して数を設定し開始する。
実行すると以下の出力が取れます。

GameStart!!
1
2
Fizz!
4
Buzz!
Fizz!
7
8
Fizz!
Buzz!
11
Fizz!
13
14
FizzBuzz!
16
17
Fizz!
19
Buzz!

うまくいってそうですね。
注目点はメインではゲームクラスを扱うだけで全て終わらせている事です。コードを見辛くするif文やfor文は登場しません。

ゲームクラス

Game.java
class Game {
    private int count;

    public void setCount(int count) {
        this.count = count;
    }
    public void start() {
        System.out.println("GameStart!!");
        for (int i = 1; i <= count; i++) {
            System.out.println(FizzBuzzBase.fizzBuzzCreate(i).call);
        }
    }
}

先程扱ったゲームクラスです。こちらは内部変数としてint型のcountとそのセッター、スタートメソッドを持ちます。クライアントで扱う部分のクラスになります。
スタートメソッドは開始の合図とcount変数分System.out.printlnを実行します。
注目点はスタートメソッド内のfor文のprintln内の部分になりますが下記のFizzBuzzクラスで解説します。

FizzBuzzクラス

FizzBuzz.java(抽象クラス)
abstract class FizzBuzzBase {
    protected String call ;

    public static FizzBuzzBase fizzBuzzCreate(int i) {
        if( i%3 == 0 && i%5 == 0){
            return new FizzBuzz();
        }else if(i%3==0){
            return new Fizz();
        }else if(i%5==0){
            return new Buzz();
        }
        return new Normal(i);
    }
}

抽象クラスFizzBuzzBaseです。実装クラスの継承元となります。
クラス内変数callを持ちます。実装クラスで持つか悩みましたがcountに対して返すクラス1つなのでクラス内変数で1つ持てばいいかと思いこの形になりました。
もう一つは静的メソッド fizzBuzzCreateです。これは実装クラスのファクトリーメソッドです。継承した4つの実装クラスのうちどれかを返します。どの条件にも当てはまらない場合Normalクラスを返します。この部分の条件式がFizzBuzzのルールの部分となります。

FizzBuzz.java(実装クラス)
class Fizz extends FizzBuzzBase{
    Fizz(){
        call="Fizz!";
    }
}
class Buzz extends FizzBuzzBase{
    Buzz(){
        call="Buzz!";
    }
}
class FizzBuzz extends FizzBuzzBase{
    FizzBuzz(){
        call="FizzBuzz!";
    }
}
class Normal extends FizzBuzzBase{
    Normal(int i){
        call= String.valueOf(i);
    }
}

抽象クラスFizzBuzzBaseを継承した各クラス

  • Fizz
  • Buzz
  • FizzBuzz
  • Normal

実装クラスはコンストラクタのみ用意されその中でクラスに応じた文字列をcall変数へ代入します。
後は呼び出しもとでcall変数を読み出せば先程の出力が得られます。これでオブジェクト指向っぽく?完成です。
System.out.println(FizzBuzzBase.fizzBuzzCreate(i).call);

やってみて

普通にif文書けばよくね?
普通に書けばif文を書いて終わりのところをこねくり回したのでコード量がかなり増えましたね(汗)
シンプルなルールなので現状だとオブジェクトで扱うことの良さが紹介できなかった気がします。でも扱ってみると面白いです多態性。ポリモーフィズム万歳!
お付き合いいただいてありがとうございます。お疲れ様でした。

0
0
4

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
0
0