미처 완성되지 못한 알고리즘
command 패턴의 간단한 예들 본문
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 |