平々毎々(アーカイブ)

はてなダイアリーのアーカイブです。

JavaでデザインパターンでFizzBuzz : Chain Of Responsibility編

いまさらFizzBuzz問題を[[OO厨]]がやるとどんなことになっちゃうのか - yojikのlog
FizzBuzz ループ→再帰→Composite→Strategy→Visitor - プログラマーの脳みそ

わざと長ったらしくJavaで書いてみた。

class Pair<T1, T2> {
  public T1 first;
  public T2 second;
  public Pair(T1 first, T2 second) {
    this.first = first;
    this.second = second;
  }
}

abstract class Handler<T> {
  protected Handler<T> next;
  public Handler<T> linksTo(Handler<T> next) {
    this.next = next;
    return next;
  }
  public abstract void handle(T request);
}

public class FizzBuzz {
  public static void main(String[] args) {
    Handler<Pair<Integer, String>> fizz = new Handler<Pair<Integer, String>>() {
      @Override
      public void handle(Pair<Integer, String> request) {
        int v = request.first.intValue();
        if ((v % 3) == 0) {
          request.second = request.second + "Fizz";
        }
        this.next.handle(request);
      }
    };
    Handler<Pair<Integer, String>> buzz = new Handler<Pair<Integer,String>>() {
      @Override
      public void handle(Pair<Integer, String> request) {
        int v = request.first.intValue();
        if ((v % 5) == 0) {
          request.second = request.second + "Buzz";
        }
        this.next.handle(request);
      }
    };
    Handler<Pair<Integer, String>> last = new Handler<Pair<Integer,String>>() {
      @Override
      public void handle(Pair<Integer, String> request) {
        if (request.second.length() == 0) {
          request.second = request.first.toString();
        }
        System.out.println(request.second);
      }
    };
    fizz.linksTo(buzz).linksTo(last);
    for(int i = 1; i <= 20; i++) {
      Pair<Integer, String> request = new Pair<Integer, String>(new Integer(i), "");
      fizz.handle(request);
    }
  }
}

むりやりC#LINQ。上記のデザインパターンとはズレるけどね。

using System;
using System.Linq;

class Program
{
  static void Main(string[] args)
  {
    Enumerable.Range(1, 20)
      .Select(x => new { First = x, Second = "" })
      .Select(x => (x.First % 3 == 0) ? new { First = x.First, Second = x.Second + "Fizz" } : x)
      .Select(x => (x.First % 5 == 0) ? new { First = x.First, Second = x.Second + "Buzz" } : x)
      .Select(x => (x.Second.Length > 0 ? x.Second : x.First.ToString()))
      .ToList()
      .ForEach(Console.WriteLine);
  }
}