반응형
커맨드 패턴 이란?
Client가 보낸 요청을 객체로 캡슐화하여 이를 나중에 이용할 수 있도록 필요한 정보를 저장, 로깅, 취소할 수 있게 하는 패턴
요청을 캡슐화 하여 호출자(invoker)와 수신자(reveiver)를 분리하는 패턴이다.
- 요청을 처리하는 방법이 바뀌더라도, 호출자의 코드는 변경되지 않는다
구성요소
1. 수신자(Receiver) : 행동을 담당하는 객체 -> 기능을 수행
2. 커맨드(Command) : 수신자의 정보 + 행동이 들어있는 객체
3. 호출자(invoker) : 커맨드를 저장하는 객체 -> 버튼이 어떤 수행을 할 것인지 결정
4. 클라이언트(Client) : 커맨드 객체를 생성하고, 호출자를 통해 수신자에게 할 행동을 결정
예제 코드
1.Button, MyApp 호출자 (invoker)에 해당된다
public class Button {
private Light light;
public Button(Light light){
this.light = light;
}
public void press() {
light.off();
}
public static void main(String [] args) {
Button button = new Button(new Light());
button.press ();
button.press ();
button.press ();
button.press ();
}
}
public class MyApp {
private Game game;
public MyApp(Game game){
this.game = game;
}
public void press() {
game.start();
}
public static void main(String [] args) {
MyApp myApp = new MyApp(new Game());
myApp.press ();
myApp.press ();
myApp.press ();
myApp.press ();
}
}
2. Game. Light 수신자(receiver)에 해당된다
public class Game {
private boolean isStarted;
public void start() {
System.out.println ("게임을 시작합니다.");
this.isStarted = true;
}
public void end() {
System.out.println ("게임을 종료합니다.");
this.isStarted = false;
}
public boolean isStarted() {
return isStarted;
}
}
public class Light {
private boolean isOn;
public void on() {
System.out.println ("불을 켭니다.");
this.isOn = true;
}
public void off() {
System.out.println ("불좀 꺼줄래.");
this.isOn = false;
}
public boolean isStarted() {
return isOn;
}
}
3. invoker코드는 최대한 유지하고 수신자(receiver) 코드만 수정하여 invoker에 적용하자
public interface Command {
void execute();
}
public class Button {
private Command command;
public Button(Command command) {
this.command = command;
}
public void press(){
command.execute();
}
public static void main(String[] args) {
Button button = new Button(new LightOffCommand(new Light()));
button.press();
button.press();
button.press();
}
}
public class GameEndCommand implements Command{
private Game game;
public GameEndCommand(Game game) {
this.game = game;
}
@Override
public void execute() {
game.end();
}
}
public class GameStartCommand implements Command{
private Game game;
public GameStartCommand(Game game) {
this.game = game;
}
@Override
public void execute() {
game.start();
}
}
public class LightOffCommand implements Command{
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
}
public class LightOnCommand implements Command{
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
장점
- 기존 코드를 변경하지 않고 새로운 커맨드를 만들 수 있다
- 수신자의 코드가 변경되어도 호출자의 코드는 변경되지 않는다.
- 커맨드 객체를 로깅, DB에 저장, 네트워크로 전송하는 등 다양한 방법으로 활용할 수도 있다
단점
- 코드가 복잡하고 클래스가 많아진다
Script
커맨드 패턴(Command Pattern)은 Client가 보낸 요청을 객체로 캡슐화하여 이를 나중에 이용할 수 있도록 필요한 정보를 저장, 로깅, 취소할 수 있게 하는 패턴
참고
'디자인패턴' 카테고리의 다른 글
옵저버 패턴(Observer Pattern) (0) | 2022.10.08 |
---|---|
메멘토 패턴(Memento Pattern) (1) | 2022.10.08 |
책임 연쇄 패턴(Chain of Responsibility Pattern) (0) | 2022.10.08 |
템플릿 메소드 패턴(Template Method Pattern) (1) | 2022.09.25 |
전략패턴(Strategy Pattern) (1) | 2022.09.20 |