FizzBuzzで学習するJavaその2

FizzBuzzをリファクタリングするを参考にします。

Win7-32にインストールしたのでideoneを使わないでコマンドプロンプトで確認する。

とにかく書く

Main.java

public class Main {
 public static void main(String[] args){
  for (int i=1; i<=100; i++){
   if (i % 15 == 0 ) {
    System.out.println("FizzBuzz");
   } else if ( i % 3 == 0 ) {
    System.out.println("Fizz");
   } else if (i % 5 == 0 ) {
    System.out.println("Buzz");
   } else {
    System.out.println(i);
   }
  }
 }
}

使い方

コマンドラインでじっこう

javac Main.java
java Main

書いておかないとね。

変数化

変数にしてみる。

public class Main {
 private static final String FIZZ_TEXT = "Fizz";
 private static final String BUZZ_TEXT = "Buzz";
 private static final int FIZZ_NUMBER = 3;
 private static final int BUZZ_NUMBER = 5;
 private static final int LOOP_COUNT = 100;

 public static void main(String[] args){
  for (int i=1; i<=LOOP_COUNT; i++){
   String text;
   if (i % (FIZZ_NUMBER * BUZZ_NUMBER) == 0) {
    text = FIZZ_TEXT + BUZZ_TEXT;
   } else if ( i % FIZZ_NUMBER == 0) {
    text = FIZZ_TEXT;
   } else if (i % BUZZ_NUMBER == 0) {
    text = BUZZ_TEXT;
   } else {
    text = String.valueOf(i);
   }
   System.out.println(text);
  }
 }
}

ここでRubyとかJavaScriptみたいなHashできないかなーと模索するがよくわからない。
どうやらRubyのMap、Hashリテラルに該当するようなものは組み込みでないらしい。(えー残念)

メソッド化

このくらいでいいんじゃないかなーと勝手に思う。

public class Main {
 private static final String FIZZ_TEXT = "Fizz";
 private static final String BUZZ_TEXT = "Buzz";
 private static final int FIZZ_NUMBER = 3;
 private static final int BUZZ_NUMBER = 5;
 private static final int LOOP_COUNT = 100;

 public static void main(String[] args){
  for (int i=1; i<=LOOP_COUNT; i++){
   System.out.println(toText(i));
  }
 }
 
 private static String toText(int i) {
  String text;
  if (i % (FIZZ_NUMBER * BUZZ_NUMBER) == 0) {
   text = FIZZ_TEXT + BUZZ_TEXT;
  } else if ( i % FIZZ_NUMBER == 0) {
   text = FIZZ_TEXT;
  } else if (i % BUZZ_NUMBER == 0) {
   text = BUZZ_TEXT;
  } else {
   text = String.valueOf(i);
  }
  return text;
 }
}

クラス化

これは中途半端な感じがするので外部クラス化の方が良いと思います。

public class Main {
 private static final int LOOP_COUNT = 100;

 public static void main(String[] args){
  for (int i=1; i<=LOOP_COUNT; i++){
   FizzBuzz fizzbuzz = new FizzBuzz(i);
   System.out.println(fizzbuzz);
  }
 }
 
 private static class FizzBuzz {
  private static final String FIZZ_TEXT = "Fizz";
  private static final String BUZZ_TEXT = "Buzz";
  private static final int FIZZ_NUMBER = 3;
  private static final int BUZZ_NUMBER = 5;

  private final int number;
  
  private FizzBuzz(int number) {
   this.number = number;
  }
  
  @Override
  public String toString() {
   String text;
   if (this.number % (FIZZ_NUMBER * BUZZ_NUMBER) == 0) {
    text = FIZZ_TEXT + BUZZ_TEXT;
   } else if ( this.number % FIZZ_NUMBER == 0) {
    text = FIZZ_TEXT;
   } else if (this.number % BUZZ_NUMBER == 0) {
    text = BUZZ_TEXT;
   } else {
    text = String.valueOf(this.number);
   }
   return text;
  }
 }
}

外部クラス化

そんな名称でいいのか?
Main.java

public class Main {
 private static final int LOOP_COUNT = 100;

 public static void main(String[] args){
  for (int i=1; i<=LOOP_COUNT; i++){
   FizzBuzz fizzbuzz = new FizzBuzz(i);
   System.out.println(fizzbuzz);
  }
 }
}

FizzBuzz.java
不要な変数「text」も削る

public class FizzBuzz {
 private static final String FIZZ_TEXT = "Fizz";
 private static final String BUZZ_TEXT = "Buzz";
 private static final int FIZZ_NUMBER = 3;
 private static final int BUZZ_NUMBER = 5;

 private final int number;
 
 private FizzBuzz(int number) {
  this.number = number;
 }
 
 @Override
 public String toString() {
  if (this.number % (FIZZ_NUMBER * BUZZ_NUMBER) == 0) {
   return FIZZ_TEXT + BUZZ_TEXT;
  } else if ( this.number % FIZZ_NUMBER == 0) {
   return FIZZ_TEXT;
  } else if (this.number % BUZZ_NUMBER == 0) {
   return BUZZ_TEXT;
  } else {
   return String.valueOf(this.number);
  }
 }
}

コマンドで

javac Main.java
javac FizzBuzz.java
java Main

テストは?

JUnitがあるのは知っているけどEclipsに突っ込まないとだめらしいのでまた今度。

感想

Cを思い出す。
ハッシュリテラルがないのが悲しい。
「;」の記述は想像していたよりも嫌じゃない。