미처 완성되지 못한 알고리즘

command 패턴의 간단한 예들 본문

IT/디자인 패턴

command 패턴의 간단한 예들

-June- 2017. 10. 2. 18:24

Undo기능을 추가할 때 유용하다.



    abstract class Command

    {

        protected Receiver m_receiver;

        public Command(Receiver receiver) { m_receiver = receiver; }

        public abstract void Execute();

    }


    class ConcreteCommand : Command

    {

        public ConcreteCommand(Receiver receiver) : base(receiver) { }

        public override void Execute()

        {

            m_receiver.Action();

        }

    }


    class Receiver

    {

        public void Action()

        {

            Console.WriteLine("Called Receiver.Action()");

        }

    }


    class Invoker

    {

        private Command m_command;

        public void SetCommand(Command command)

        {

            m_command = command;

        }


        public void ExecuteCommand()

        {

            m_command.Execute();

        }

    }



    class Program

    {

        static void Main(string[] args)

        {

            Receiver receiver = new Receiver();

            Command command = new ConcreteCommand(receiver);

            Invoker invoker = new Invoker();


            invoker.SetCommand(command);

            invoker.ExecuteCommand();


        }//main

    }



////////////////////////////////////////////////////////////////////////////////////////////////////



//이 예제에서는 reciever가 없다.



        public class Command

    {

        public virtual void Execute() { }

    }


    public class CmdFire : Command

    {

        void Fire() { Console.WriteLine("Fire"); }

        public override void Execute()

        {

            Fire();

        }

    }


    public class CmdJump : Command

    {

        void Jump() { Console.WriteLine("Jump"); }

        public override void Execute()

        {

            Jump();

        }

    }


    public class CmdSkill : Command

    {

        void Skill() { Console.WriteLine(); }

        public override void Execute()

        {

            Skill();

        }

    }


    public class CmdEvade : Command

    {

        void Evade() { Console.WriteLine("Evade"); }

        public override void Execute()

        {

            Evade();

        }

    }


    public class ButtonManager     //Invoke 역할

    {

        Command m_btnX, m_btnY, m_btnA, m_btnB;

        public void Setcommand()

        {

            m_btnX = new CmdFire();

            m_btnY = new CmdJump();

            m_btnA = new CmdEvade();

            m_btnB = new CmdSkill();

        }


        public bool KeyProcess(ConsoleKey key)

        {

            if (key == ConsoleKey.Escape) return true;

            if (key == ConsoleKey.X) m_btnX.Execute();

            if (key == ConsoleKey.Y) m_btnY.Execute();

            if (key == ConsoleKey.A) m_btnA.Execute();

            if (key == ConsoleKey.B) m_btnB.Execute();

            return false;

        }

    }



    class Program

    {

        static void Main(string[] args)

        {

            ButtonManager button = new ButtonManager();

            button.Setcommand();

            bool isExit = false;


            while(!isExit)

            {

                isExit = button.KeyProcess(Console.ReadKey(true).Key);  //ReadKey(true)를 할 경우 콘솔창에 누른 키 값이 출력되지 않는다.

            }

        }//main

    }




///////////////////////////////////////////////////////////////////////////////////////////////////////



public class Point

    {

        public int x;

        public int y;


        public Point(int x, int y) { this.x = x;  this.y = y; }

    }

    public class Command //abstact도 상관이 없음.

    {

        public virtual void Execute(Unit unit, Point pos) { }

        public virtual void Undo(Unit unit) { }

    }


    public class cmdMove : Command

    {

        Point prevPos;

        public override void Execute(Unit unit, Point newpos)

        {

            prevPos = unit.m_position;

            unit.MoveTo(newpos);

        }


        public override void Undo(Unit unit)

        {

            unit.MoveTo(prevPos);

        }

    }


    public class Unit

    {

        public Point m_position { get; set; }

        public Unit(Point pos)

        {

            m_position = pos;

        }


        public void MoveTo(Point pos)

        {

            m_position = pos;

            Console.WriteLine("유닛을 {0}, {1}로 이동합니다.", m_position.x, m_position.y);

        }

    }


    public class UnitControl

    {

        Stack<Command> m_cmdStack = new Stack<Command>();

        public Command GetCommand(ref bool isUndo)

        {

            ConsoleKey key = Console.ReadKey().Key;

            if(key == ConsoleKey.M)

            {

                Command cmd = new cmdMove();

                m_cmdStack.Push(cmd);

                return cmd;

            }

            if(key == ConsoleKey.U)

            {

                isUndo = true;

                return m_cmdStack.Count > 0 ? m_cmdStack.Pop() : null;

            }


            return null;

        }

    }


    class Program

    {

        static void Main(string[] args)

        {

            UnitControl unitctr = new UnitControl();

            Unit m_marine = new Unit(new Point(0, 0));


            while(true)

            {

                bool isUndo = false;

                Command cmd = unitctr.GetCommand(ref isUndo);

                if(cmd != null)

                {

                    if (isUndo)

                        cmd.Undo(m_marine);


                    else

                        cmd.Execute(m_marine, new Point(new Random().Next(0,10), new Random().Next(0, 20)));

                }

            }

        }//main

    }

'IT > 디자인 패턴' 카테고리의 다른 글

옵저버 패턴의 간단한 예들  (0) 2017.09.29
어댑터 패턴의 간단한 예들  (0) 2017.09.29
팩토리 메소드 패턴 간단한 예  (0) 2017.09.28
간단한 싱글톤 예제들  (0) 2017.09.25