개요
요청을 객체로 캡슐화하여, 클라이언트를 다양한 요청으로 매개변수화할 수 있게 하며, 요청을 큐에 넣거나 로그로 기록하고, 실행 취소(undo)를 지원합니다.
적용 상황
- 객체를 매개변수화하기 위해 실행할 동작을 추상화합니다.
- 서로 다른 시점에 요청을 지정, 정렬 및 실행합니다.
- 실행 취소(undo) 작업을 지원합니다.
- 시스템이 다운될 경우 수정 사항을 재실행할 수 있도록 수정 로그를 지원합니다.
- 기본 원시 작업 위에 고수준 작업을 구축하여 시스템을 구성합니다.
코드 예제
전등을 켜고 끄는 시나리오를 통해 명령 패턴을 구현해 보겠습니다.
1. 명령 인터페이스 선언
/// <summary>
/// 실행할 작업을 선언하는 인터페이스
/// </summary>
public interface ICommand
{
void Execute();
}
2. 명령 구현
/// <summary>
/// 수신자 객체와 특정 동작을 연결합니다. Execute 메서드를 호출하여 동작을 실행합니다.
/// </summary>
public class LightOnCommand : ICommand
{
private readonly Light _light;
public LightOnCommand(Light light)
{
_light = light;
}
public void Execute()
{
_light.TurnOn();
}
}
3. 명령 호출 및 실행 요청
/// <summary>
/// 명령을 실행하도록 요청합니다.
/// </summary>
public class RemoteControl
{
private ICommand _command;
public void SetCommand(ICommand command)
{
_command = command;
}
public void PressButton()
{
_command.Execute();
}
}
4. 수신자
/// <summary>
/// 요청과 관련된 작업을 실제로 수행하는 객체. 어떤 클래스도 수신자가 될 수 있습니다.
/// </summary>
public class Light
{
public void TurnOn()
{
Console.WriteLine("전등을 켭니다.");
}
public void TurnOff()
{
Console.WriteLine("전등을 끕니다.");
}
}
5. 클라이언트 호출
/// <summary>
/// 명령 패턴 테스트
/// </summary>
static void Main(string[] args)
{
// 수신자 생성
Light livingRoomLight = new Light();
// 명령 생성 및 수신자 바인딩
ICommand lightOnCommand = new LightOnCommand(livingRoomLight);
// 호출자 생성
RemoteControl remote = new RemoteControl();
// 명령 설정 및 실행
remote.SetCommand(lightOnCommand);
remote.PressButton();
Console.ReadLine();
}
요약
명령 패턴은 요청을 객체로 캡슐화하여 발신자와 수신자를 분리하는 강력한 패턴입니다. 이를 통해 요청의 큐잉, 로깅, 실행 취소 등 고급 기능을 쉽게 구현할 수 있습니다.