LoginSignup
10
10

More than 5 years have passed since last update.

FizzBuzzにデザインパターンをかますと。

Last updated at Posted at 2014-06-24

かの有名な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());

これで、実装は本当に必要な箇所のみに絞り、他は全く手をつけずに、
追加、削除、並び替えが出来るようになりました。

めでたしめでたし

10
10
0

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