星期一, 4月 13, 2015

[DP] 狀態模式

根據 Head First Design Pattern 書本內容,來練習狀態模式

擷取 Head First 上的類別圖

[DP] 狀態模式-1



Project 內容

[DP] 狀態模式-2

State 內容

IState interface
namespace DP_State
{
    public interface IState
    {
        string descript{get;}

        void insertQuarter();
        void ejectQuater();
        void turnCrank();
        void dispense();
    }
}

NoQuarterState Class
namespace DP_State
{
    public class NoQuarterState : IState
    {
        private GumballMachine _GumballMachine;
        public string descript
        {
            get { return "Machine is waiting for quarter"; }
        }

        public NoQuarterState(GumballMachine GumballMachine)
        {
            this._GumballMachine = GumballMachine;
        }

        public void insertQuarter()
        {
            Console.WriteLine("You inserted a quarter");
            this._GumballMachine.setState(this._GumballMachine.getHasQuarterState());
        }

        public void ejectQuater()
        {
            Console.WriteLine("Sorry ,you haven't inserted a quarter yet");
        }

        public void turnCrank()
        {
            Console.WriteLine("You turn the crank,but there is no quarter inserted");
        }

        public void dispense()
        {
            Console.WriteLine("Please insert a quarter first");
        }
    }
}

HasQuarterState Class
namespace DP_State
{
    public class HasQuarterState : IState
    {

        private GumballMachine _GumballMachine;
        public string descript
        {
            get { return "Quarter is inserted"; }
        }

        private Random _RandomWinner = new Random(DateTime.Now.Millisecond);

        public HasQuarterState(GumballMachine GumballMachine)
        {
            this._GumballMachine = GumballMachine;
        }

        public void insertQuarter()
        {
            Console.WriteLine("You can't insert another quarter");
        }

        public void ejectQuater()
        {
            Console.WriteLine("Quarter returned");
            _GumballMachine.setState(_GumballMachine.getNoQuarterState());
        }

        public void turnCrank()
        {
            Console.WriteLine("You turned...");
            int winner = _RandomWinner.Next(10);
            if (winner == 0 && this._GumballMachine.getCount() > 1)
            {
                _GumballMachine.setState(_GumballMachine.getWinnerState());
            }
            else
            {
                _GumballMachine.setState(_GumballMachine.getSoldState());
            }
        }

        public void dispense()
        {
            Console.WriteLine("NO gumball dispensed");
        }
    }
}

SoldState Class
namespace DP_State
{
     public class SoldState : IState
     {
         private GumballMachine _GumballMachine;
         public string descript
         {
             get { return "Maching is ready to release gumball"; }
         }

         public SoldState(GumballMachine GumballMachine)
         {
             this._GumballMachine = GumballMachine;
         }

         public void insertQuarter()
         {
             Console.WriteLine("Please wait,we're already giving you a gumball");
         }

         public void ejectQuater()
         {
             Console.WriteLine("Sorry, you already turned the crank");
         }

         public void turnCrank()
         {
             Console.WriteLine("Turning twice doesn't get you another gumball");
         }

         public void dispense()
         {
             this._GumballMachine.releaseBall();

             if (this._GumballMachine.getCount() > 0)
             {
                 this._GumballMachine.setState(_GumballMachine.getNoQuarterState());
             }
             else
             {
                 Console.WriteLine("Oops, out of gumballs");
                 this._GumballMachine.setState(_GumballMachine.getSoldOutState());
             }
         }
    }
}

SoldOutState Class
namespace DP_State
{
    public class SoldOutState : IState
    {
        private GumballMachine _GumballMachine;
        public string descript
        {
            get { return "Machine is sold out"; }
        }

        public SoldOutState(GumballMachine GumballMachine)
        {
            this._GumballMachine = GumballMachine;
        }

        public void insertQuarter()
        {
            Console.WriteLine("You can't insert a quarter , the machine is sold out");
        }

        public void ejectQuater()
        {
            Console.WriteLine("You can't eject ,you haven't inserted a quarter yet");
        }

        public void turnCrank()
        {
            Console.WriteLine("You turned, but there are no gumballs");
        }

        public void dispense()
        {
            Console.WriteLine("No gumball dispensed");
        }
    }
}

WinnerState Class
namespace DP_State
{
    public class WinnerState : IState
    {
        private GumballMachine _GumballMachine;
        public string descript
        {
            get { return "Winner Mode, you get two gumball"; }
        }

        public WinnerState(GumballMachine GumballMachine)
        {
            this._GumballMachine = GumballMachine;
        }

        public void insertQuarter()
        {
            Console.WriteLine("Please wait,we're already giving you a gumball");
        }

        public void ejectQuater()
        {
            Console.WriteLine("Sorry, you already turned the crank");
        }

        public void turnCrank()
        {
            Console.WriteLine("Turning twice doesn't get you another gumball");
        }

        public void dispense()
        {
            Console.WriteLine("You're a winner! You get two gumballs for your quarter");
            this._GumballMachine.releaseBall();
            if (this._GumballMachine.getCount() > 0) 
            {
                this._GumballMachine.releaseBall();
                if (this._GumballMachine.getCount() > 0)
                {
                    this._GumballMachine.setState(this._GumballMachine.getNoQuarterState());
                }
                else
                {
                    Console.WriteLine("Oops, out of gumballs");
                    this._GumballMachine.setState(this._GumballMachine.getSoldOutState());
                }
            }
            else
            {
                Console.WriteLine("Oops, out of gumballs");
                this._GumballMachine.setState(this._GumballMachine.getSoldOutState());
            }
        }
    }
}


GumBallMachine 內容
namespace DP_State
{
    public class GumballMachine
    {
        private IState _SoldOutState;
        private IState _NoQuarterState;
        private IState _HasQuarterState;
        private IState _SoldState;
        private IState _WinnerState;

        private IState _State;
        private int _count = 0 ;

        public GumballMachine(int numberGumballs)
        {
            this._SoldOutState = new SoldOutState(this);
            this._NoQuarterState = new NoQuarterState(this);
            this._HasQuarterState = new HasQuarterState(this);
            this._SoldState = new SoldState(this);
            this._WinnerState = new WinnerState(this);

            // 初始化狀態是該機器沒有放進任何糖果,所以狀態是售盡
            this._State = this._SoldOutState;

            // 假如初始化過程有放進糖果,狀態會沒有25分狀態
            this._count = numberGumballs;
            if (this._count > 0) this._State = this._NoQuarterState; 
        }

        public void insertQuarter()
        {
            _State.insertQuarter();
        }

        public void ejectQuarter()
        {
            _State.ejectQuater();
        }

        public void turnCrank()
        {
            _State.turnCrank();
            _State.dispense();
        }

        public void setState(IState State)
        {
            this._State = State;
        }

        public IState getSoldOutState()
        {
            return this._SoldOutState;
        }

        public IState getNoQuarterState()
        {
            return this._NoQuarterState;
        }

        public IState getHasQuarterState()
        {
            return this._HasQuarterState;
        }

        public IState getSoldState()
        {
            return this._SoldState;
        }

        public IState getWinnerState()
        {
            return this._WinnerState;
        }

        public int getCount()
        {
            return this._count;
        }

        public void releaseBall()
        {
            Console.WriteLine("A gumBall comes rolling out the slot...");
            if (this._count > 0) this._count--;
        }

        public void fillBall(int count)
        {
            this._count += count;
        }

        public override string ToString()
        {
            string message = string.Format("Inventory:{0} gumballs \n", this._count);
            message += string.Format("Machine State:{0} \n", this._State.descript);
            return message;
        }
    }
}

執行
namespace DP_State
{
    class Program
    {
        static void Main(string[] args)
        {

            GumballMachine Machine = new GumballMachine(5);

            Console.WriteLine(Machine.ToString());

            Machine.insertQuarter();
            Machine.turnCrank();
            Console.WriteLine(Machine.ToString());

            Machine.insertQuarter();
            Machine.turnCrank();
            Machine.insertQuarter();
            Machine.turnCrank();
            Console.WriteLine(Machine.ToString());
        }
    }
}
[DP] 狀態模式-3

沒有留言:

張貼留言