디자인패턴
커맨드 패턴(Command Pattern)
ppp5500
2022. 4. 4. 20:50
커맨드 패턴은 실행될 기능을 캡슐화함으로써 기능의 실행을 요구하는 호출자(Invoker) 클래스와 실제 기능을 실행하는 수신자(Receiver) 클래스 사이의 의존성을 제거한다. 따라서 실행될 기능의 변경에도 호출자 클래스를 수정 없이 그대로 사용할 수 있도록 해준다.
Command: 실행될 기능에 대한 인터페이스. 실행될 기능을 execute 메서드로 선언함
ConcreteCommand: 실제로 실행되는 기능을 구현. 즉, Command라는 인터페이스를 구현함
Invoker: 기능의 실행을 요청하는 호출자 클래스
Receiver: ConcreteCommand에서 execute 메서드를 구현할 때 필요한 클래스. 즉, ConcreteCommand의 기능을 실행하기 위해 사용하는 수신자 클래스
// 커맨드 패턴 구현
Lamp lamp = new Lamp();
Command lampOnCommand = new LampOnCommand(lamp);
Button button1 = new Button(lampOnCommand);
button1.pressed();
Alarm alarm = new Alarm();
Command alarmOnCommand = new AlarmOnCommand(alarm);
Button button2 = new Button(alarmOnCommand);
button2.pressed();
button1 = new Button(alarmOnCommand);
button1.pressed(); // 알람 기능으로 바뀜
public interface Command
{
public abstract void execute();
}
public class Button
{
private Command theCommand;
public Button(Command theCommand)
{
SetCommand(theCommand);
}
public void SetCommand(Command newCommand)
{
this.theCommand = newCommand;
}
public void pressed()
{
theCommand.execute();
}
}
public class Lamp
{
public void TurnOn()
{
Console.WriteLine("Lamp On");
}
}
public class LampOnCommand : Command
{
private Lamp theLamp;
public LampOnCommand(Lamp theLamp)
{
this.theLamp = theLamp;
}
public void execute()
{
theLamp.TurnOn();
}
}
public class Alarm
{
public void Ringing()
{
Console.WriteLine("Alarm Ringing");
}
}
public class AlarmOnCommand : Command
{
private Alarm theAlarm;
public AlarmOnCommand(Alarm theAlarm)
{
this.theAlarm = theAlarm;
}
public void execute()
{
theAlarm.Ringing();
}
}
실행결과
Lamp lamp = new Lamp();
Command lampOnCommand = new LampOnCommand(lamp);
Button button1 = new Button(lampOnCommand);
button1.pressed();
Alarm alarm = new Alarm();
Command alarmOnCommand = new AlarmOnCommand(alarm);
Button button2 = new Button(alarmOnCommand);
button2.pressed();
button1 = new Button(alarmOnCommand);
button1.pressed(); // 알람 기능으로 바뀜
이 코드에서 button은 실행을 호출하는 Invoker 역할이며 기능의 변경이 필요할 때는 Lamp와 Alarm 클래스만 변경하면 되고, 기능의 추가가 필요할 때는 기존 코드의 변경 없이 새로운 Receiver와 ConcreteCommand만 추가해 주면 된다.