728x90
반응형
Command Pattern
요청을 캡슐화하여 호출자(invoker)와 수신자(receiver)를 분리하는 패턴
요청을 처리하는 방법이 바뀌더라도, 호출자의 코드는 변경되지 않는다.
BEFORE
MyApp
public class MyApp {
private Game game;
public MyApp(Game game) {
this.game = game;
}
public void press() {
game.start();
}
public static void main(String[] args) {
Button button = new Button(new Light());
button.press();
button.press();
button.press();
button.press();
}
}
Game
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;
}
}
Light
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 isOn() {
return this.isOn;
}
}
Button
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();
}
}
AFTER
Client
public class MyApp {
private Command command;
public MyApp(Command command) {
this.command = command;
}
public void press() {
command.execute();
}
public static void main(String[] args) {
MyApp myApp = new MyApp(new GameStartCommand(new Game()));
}
}
Command
public interface Command {
void execute();
void undo();
}
// LightOnCommand
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
new LightOffCommand(this.light).execute();
}
}
// LightOffCommand
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
new LightOnCommand(this.light).execute();
}
}
// GameStartCommand
public class GameStartCommand implements Command {
private Game game;
public GameStartCommand(Game game) {
this.game = game;
}
@Override
public void execute() {
game.start();
}
@Override
public void undo() {
new GameEndCommand(this.game).execute();
}
}
// GameEndCommand
public class GameEndCommand implements Command {
private Game game;
public GameEndCommand(Game game) {
this.game = game;
}
@Override
public void execute() {
game.end();
}
@Override
public void undo() {
new GameStartCommand(this.game).execute();
}
}
[패턴복습]
장점 | 단점 |
- 기존 코드를 변경하지 않고 새로운 커맨드를 만들 수 있다. - 수신자의 코드가 변경되어도 호출자의 코드는 변경되지 않는다. - 커맨드 객체를 로깅, DB에 저장, 네트워크로 전송하는 등 다양한 방법으로 활용할 수도 있다. |
- 코드가 복잡해지고 클래스가 많아진다. |
[실무에서 쓰이는 경우]
- 자바
- Runnable
- 람다
- 메소드 레퍼런스
- 스프링
- SimpleJdbcInsert
- Simple JdbcCall
728x90
반응형
'Design Patterns > 행동(Behavioral)' 카테고리의 다른 글
[Memento]메멘토패턴 (0) | 2022.11.03 |
---|---|
[Mediator]중재자패턴 (0) | 2022.11.01 |
[Iterator]이터레이터패턴 (0) | 2022.10.25 |
[Interpreter]인터프리터패턴 (0) | 2022.10.25 |
[Chain-of-Responsibility]책임연쇄패턴 (0) | 2022.10.20 |