かの有名なFizzBuzzを、
C#を使って、デザインパターンのストラテジーパターンで実装してみました。
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
/*
* FizzBuzz (ストラテジーパターン版)
*
* 特徴
* 1.FizzBuzzになるための条件と、条件が成立した場合のアクションをクラスに委譲。
* 2.機能追加はクラス作成してファクトリー部分(コンストラクタ)に追加。
*/
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
int input = 1;
int max = 100;
FizzBuzz objFizBuz = new FizzBuzz();
string msg = "";
try
{
for (int i = input; i <= max; i++)
{
msg += objFizBuz.DoFizzBuzz(i);
}
Console.WriteLine(msg);
}
catch (Exception ex)
{
ex.ToString();
}
}
}
// strategyパターン用IF
interface IStrategy
{
bool IsFizzBuzz(int i);
string DoFizzBuzz();
}
// strategy インターフェイスを用いてアルゴリズムを実装
class Fizz : IStrategy
{
public bool IsFizzBuzz(int i)
{
return (i % 3) == 0;
}
public string DoFizzBuzz()
{
return "Fizz";
}
}
class Buzz : IStrategy
{
public bool IsFizzBuzz(int i)
{
return (i % 5) == 0;
}
public string DoFizzBuzz()
{
return "Buzz";
}
}
class FizzBuzz
{
private List<IStrategy> strategy = new List<IStrategy>();
public FizzBuzz()
{
// クラスを新規作成して、ここに追加すれば良い
this.strategy.Add(new Fizz());
this.strategy.Add(new Buzz());
}
public string DoFizzBuzz(int i)
{
if (i == 0) return "";
string msg = "";
bool isAllFizzBuzz = true;
foreach (IStrategy st in this.strategy)
{
if (st.IsFizzBuzz(i))
{
msg += st.DoFizzBuzz();
}
else
{
isAllFizzBuzz = false;
}
}
// 全ての条件が正の場合
if (isAllFizzBuzz)
{
msg = "";
// 全部のメッセージをマージして出力
foreach (IStrategy st in this.strategy)
{
msg += st.DoFizzBuzz();
}
}
else if (string.Empty == msg) {
msg = i.ToString();
}
return msg + Environment.NewLine;
}
}
}
例えば、Buzzを外したい場合は、
class FizzBuzzのコンストラクタの
this.strategy.Add(new Buzz());
を外すだけ。
また、新しく「Bizz」を追加するとした場合は、
IStrategyを実装(細かいですが継承ではないですよ)したBizzを作成し、
IsFizzBuzzとDoFizzBuzzをそれぞれ実装し、
class FizzBuzzのコンストラクタの叫びたい任意の場所に、
以下を追加するだけ
this.strategy.Add(new Bizz());
これで、実装は本当に必要な箇所のみに絞り、他は全く手をつけずに、
追加、削除、並び替えが出来るようになりました。
めでたしめでたし