1. 커맨드 패턴이란?
- 실행될 기능을 캡슐화함으로써 주어진 여러 기능을 실행할 수 있는 재사용성이 높은 클래스를 설계하는 패턴.
- 객체의 행위(메서드)를 클래스로 만들어 캡슐화하는 패턴.
- 요청을 요청에 대한 모든 정보가 포함된 독립실행형 객체로 변환하는 행동 패턴.
- 요청의 실행을 지연하거나 대기열에 넣을 수 있도록 하고, 또 실행 취소할 수 있는 작업도 지원한다.
- 요청을 객체의 형태로 캡슐화하여 나중에 이용할 수 있도록 메서드 이름, 매개변수 등 요청에 필요한 정보를 저장 또는 로깅, 취소할 수 있게 해주는 패턴.
2. 커맨드 패턴을 사용하는 경우
- 요청이 서로 다른 사용자, 시간 또는 프로젝트에 따라 달라질 수 있을 경우
- 이벤트를 발생시키는 클래스를 변경하지 않고 재사용하고 싶은 경우
- 여러 커맨드를 조합하여 하나의 커맨드처럼 사용할 필요가 있는 경우
3. 커맨드 패턴의 장점
1) 재사용 : 이벤트가 발생했을 때 실행될 기능이 다양하면서도 변경이 필요한 경우에 이벤트를 발생시키는 클래스를 변경하지 않고 재사용하고자 할 때 유용하다.
2) 확장성 및 유연성 : 실행될 기능을 캡슐화함으로써 기능의 실행을 요구하는 호출자 클래스, 실제 기능을 실행하는 수신자 클래스 사이의 의존성을 제거하므로 실행될 기능의 변경에도 호출자 클래스를 수정없이 그대로 사용할 수 있다.
3) 낮은 결합도 : 요청 발신자와 수신자 사이에 직접적인 연결이 없다.
4. 커맨드 패턴의 단점
- 각각의 개별 요청에 대해 Command 클래스를 만들어하므로, 클래스가 많아질 수 있다.
- 코드 복잡성이 증가할 수 있다.
5. 코드 구현
- 구성
1) Action - 인터페이스 또는 추상 클래스로 정의 후 상속하여 사용, 행위의 외형을 추상화
2) Command - 행위 명령을 실행
3) Reciever - 실제 행위를 정의
4) Invoker - 명령을 호출
- 실행 과정
Invoker -> 명령 호출 -> Command -> 명령 전달 -> Reciever -> 명령 수행
- 소스 코드(C#)
using System;
using System.Collections.Generic;
using System.Threading;
namespace StudyCSharp
{
// Action
public interface Command
{
void Execute();
}
// 커맨드(Command) 1
public class ExerciseStartCommand : Command
{
Exercise _exercise;
public ExerciseStartCommand(Exercise exercise)
{
this._exercise = exercise;
}
public void Execute()
{
_exercise.StartExercise();
}
}
// 커맨드(Command) 2
public class ExerciseEndCommand : Command
{
Exercise _exercise;
public ExerciseEndCommand(Exercise exercise)
{
this._exercise = exercise;
}
public void Execute()
{
_exercise.EndExercise();
}
}
// 수신자(Receiver)
public class Exercise
{
public void StartExercise()
{
Console.WriteLine("운동 시작");
}
public void EndExercise()
{
Console.WriteLine("운동 끝");
}
}
// 호출자(Invoker)
public class Gym
{
private Command _startCommand;
private Command _endCommand;
public void setCommand(Command command1, Command command2)
{
this._startCommand = command1;
this._endCommand = command2;
}
public void arrivedGym()
{
Console.WriteLine("헬스장 도착");
Console.WriteLine("-------------------");
_startCommand.Execute();
}
public void GoHome()
{
_endCommand.Execute();
Console.WriteLine("-------------------");
Console.WriteLine("집에 가자");
}
}
class Program
{
static void Main(string[] args)
{
// 인스턴스 생성
Exercise ex = new Exercise();
Command startCommand = new ExerciseStartCommand(ex);
Command endCommand = new ExerciseEndCommand(ex);
// 호출자 생성
Gym gym = new Gym();
// 커맨드 설정
gym.setCommand(startCommand, endCommand);
// 커맨드 사용
gym.arrivedGym();
Console.WriteLine();
Console.WriteLine("...운동중...");
Console.WriteLine();
gym.GoHome();
}
}
}
<참고 사이트>