์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- API Aggregation
- OOP
- ํญํดํ๋ฌ์ค
- pull model
- ๊ธฐ๋ฅ ํ ์คํธ
- ํญํดํ๋ฌ์ค ํ๊ณ
- ์ฑ๊ธํค ๋น
- fanout on read
- ํญํ ํ๊ธฐ
- TDD
- ํญํดํ๋ฌ์ค ๋ฐฑ์๋
- ์์ฐจ์งํฅ
- ํญํด+
- ํญํด ๋ฐฑ์๋
- ํญํ ๋ฐฑ์๋
- ๋น ์ค์ฝํ
- ํญํ
- ํญํดํ๋ฌ์ค ํ๊ธฐ
- ํผ๋ ๊ตฌํ
- ๋ฐ์ดํฐ ์ฟผ๋ฆฌ
- ํญํดํ๋ฌ์คํ๊ธฐ
- ๋์์ธ ํจํด
- push model
- ์์ฑ ํจํด
- ํญํด ํ๋ฌ์ค ํ๊ธฐ
- ํญํด
- ํญํดํ๋ฌ์ค๋ฐฑ์๋
- fanout on write
- ํ๋กํ ํ์ ๋น
- ํญํด ํ๊ธฐ
- Today
- Total
deVlog
[๋์์ธ ํจํด] ํ์ ํจํด - Command Pattern (์ปค๋งจ๋ ํจํด) ๋ณธ๋ฌธ
[๋์์ธ ํจํด] ํ์ ํจํด - Command Pattern (์ปค๋งจ๋ ํจํด)
์๋ฃจ๋ฐ 2025. 4. 2. 21:03๋ชฉ์ฐจ
๐ ๊ฐ์
์ปค๋งจ๋ ํจํด(Command Pattern)์ ์์ฒญ์ ๊ฐ์ฒด๋ก ์บก์ํํ์ฌ ๋งค๊ฐ๋ณ์ํ๋ ํด๋ผ์ด์ธํธ๋ฅผ ๋ง๋ค๊ณ , ์์ฒญ ๋ด์ญ์ ํ์ ์ ์ฅํ๊ฑฐ๋ ๋ก๊ทธ๋ก ๊ธฐ๋กํ ์ ์๊ฒ ํ๋ ํ๋ ๋์์ธ ํจํด์ด๋ค. ์ฆ, ์คํ๋ ๊ธฐ๋ฅ์ ์บก์ํํ์ฌ ํธ์ถ์(Invoker)์ ์์ ์(Receiver) ์ฌ์ด์ ์์กด์ฑ์ ์ ๊ฑฐํ๋ ํจํด์ด๋ค.
ํน์ง
- ๋ช ๋ น(์์ฒญ)์ ๊ฐ์ฒด๋ก ํํํ์ฌ ์บก์ํํ๋ค.
- ์คํ๋ ๊ธฐ๋ฅ์ ๋ณ๊ฒฝ์๋ ํธ์ถ์ ์ฝ๋๋ฅผ ์์ ํ ํ์๊ฐ ์๋ค.
- ๋ช ๋ น์ ์ ์ฅ, ๋ก๊น , ์ทจ์ ๋ฑ ๋ค์ํ ํ์ฅ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์๋ค.
๐ฉ๐ป๐ป ์ฝ๋๋ก ์์๋ณด์
๋ฆฌ๋ชจ์ปจ์ผ๋ก ๋ค์ํ ๊ฐ์ ์ ํ์ ์ ์ดํ๋ ์์ ๋ฅผ ํตํด ์ปค๋งจ๋ ํจํด์ ์ดํด๋ณด์.
// 1. ์ปค๋งจ๋ ์ธํฐํ์ด์ค
interface Command {
void execute();
void undo();
}
// 2. ์์ ์(Receiver) ํด๋์ค๋ค
class Light {
private String location;
public Light(String location) {
this.location = location;
}
public void on() {
System.out.println(location + " ์กฐ๋ช
์ด ์ผ์ก์ต๋๋ค.");
}
public void off() {
System.out.println(location + " ์กฐ๋ช
์ด ๊บผ์ก์ต๋๋ค.");
}
}
class Television {
public void on() {
System.out.println("TV๊ฐ ์ผ์ก์ต๋๋ค.");
}
public void off() {
System.out.println("TV๊ฐ ๊บผ์ก์ต๋๋ค.");
}
public void setChannel(int channel) {
System.out.println("TV ์ฑ๋์ด " + channel + "๋ฒ์ผ๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค.");
}
}
// 3. ๊ตฌ์ฒด์ ์ธ ์ปค๋งจ๋ ํด๋์ค๋ค
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
class TVOnCommand implements Command {
private Television tv;
public TVOnCommand(Television tv) {
this.tv = tv;
}
@Override
public void execute() {
tv.on();
}
@Override
public void undo() {
tv.off();
}
}
class TVOffCommand implements Command {
private Television tv;
public TVOffCommand(Television tv) {
this.tv = tv;
}
@Override
public void execute() {
tv.off();
}
@Override
public void undo() {
tv.on();
}
}
class TVChangeChannelCommand implements Command {
private Television tv;
private int channel;
private int previousChannel;
public TVChangeChannelCommand(Television tv, int channel) {
this.tv = tv;
this.channel = channel;
}
@Override
public void execute() {
// ์ค์ ๊ตฌํ์์๋ ์ด์ ์ฑ๋์ ์ ์ฅํ ์ ์์
tv.setChannel(channel);
}
@Override
public void undo() {
// ์ด์ ์ฑ๋๋ก ๋์๊ฐ๋ ๊ธฐ๋ฅ (์ฌ๊ธฐ์๋ ๊ฐ๋จํ ๊ตฌํ)
System.out.println("์ด์ ์ฑ๋๋ก ๋์๊ฐ๋๋ค.");
}
}
// 4. ํธ์ถ์(Invoker) ํด๋์ค
class RemoteControl {
private Command[] onCommands;
private Command[] offCommands;
private Command undoCommand;
public RemoteControl() {
onCommands = new Command[5];
offCommands = new Command[5];
// NoCommand ๊ฐ์ฒด๋ก ์ด๊ธฐํ
Command noCommand = new NoCommand();
for (int i = 0; i < 5; i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
undoCommand = noCommand;
}
public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
public void onButtonWasPushed(int slot) {
onCommands[slot].execute();
undoCommand = onCommands[slot];
}
public void offButtonWasPushed(int slot) {
offCommands[slot].execute();
undoCommand = offCommands[slot];
}
public void undoButtonWasPushed() {
undoCommand.undo();
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("\n------ ๋ฆฌ๋ชจ์ปจ ------\n");
for (int i = 0; i < onCommands.length; i++) {
sb.append("[slot " + i + "] " + onCommands[i].getClass().getName() + " "
+ offCommands[i].getClass().getName() + "\n");
}
sb.append("[undo] " + undoCommand.getClass().getName() + "\n");
return sb.toString();
}
}
// Null Object ํจํด์ ์ ์ฉํ NoCommand ํด๋์ค
class NoCommand implements Command {
@Override
public void execute() {
// ์๋ฌด ๋์๋ ํ์ง ์์
}
@Override
public void undo() {
// ์๋ฌด ๋์๋ ํ์ง ์์
}
}
// 5. ํด๋ผ์ด์ธํธ
public class CommandPatternExample {
public static void main(String[] args) {
// ๋ฆฌ๋ชจ์ปจ ์์ฑ
RemoteControl remoteControl = new RemoteControl();
// ์์ ์ ๊ฐ์ฒด๋ค ์์ฑ
Light livingRoomLight = new Light("๊ฑฐ์ค");
Light kitchenLight = new Light("์ฃผ๋ฐฉ");
Television tv = new Television();
// ์ปค๋งจ๋ ๊ฐ์ฒด๋ค ์์ฑ
LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight);
LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight);
LightOnCommand kitchenLightOn = new LightOnCommand(kitchenLight);
LightOffCommand kitchenLightOff = new LightOffCommand(kitchenLight);
TVOnCommand tvOn = new TVOnCommand(tv);
TVOffCommand tvOff = new TVOffCommand(tv);
TVChangeChannelCommand tvChannel9 = new TVChangeChannelCommand(tv, 9);
// ๋ฆฌ๋ชจ์ปจ์ ์ปค๋งจ๋ ์ค์
remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff);
remoteControl.setCommand(1, kitchenLightOn, kitchenLightOff);
remoteControl.setCommand(2, tvOn, tvOff);
// ๋ฆฌ๋ชจ์ปจ ์ ๋ณด ์ถ๋ ฅ
System.out.println(remoteControl);
// ๋ฆฌ๋ชจ์ปจ ๋ฒํผ ๋๋ฅด๊ธฐ
System.out.println("------ ๋ฆฌ๋ชจ์ปจ ๋ฒํผ ํ
์คํธ ------");
remoteControl.onButtonWasPushed(0); // ๊ฑฐ์ค ์กฐ๋ช
์ผ๊ธฐ
remoteControl.offButtonWasPushed(0); // ๊ฑฐ์ค ์กฐ๋ช
๋๊ธฐ
remoteControl.onButtonWasPushed(1); // ์ฃผ๋ฐฉ ์กฐ๋ช
์ผ๊ธฐ
remoteControl.undoButtonWasPushed(); // ์ฃผ๋ฐฉ ์กฐ๋ช
๋๊ธฐ (์คํ ์ทจ์)
remoteControl.onButtonWasPushed(2); // TV ์ผ๊ธฐ
// TV ์ฑ๋ ๋ณ๊ฒฝ์ ๋ณ๋๋ก ๊ตฌํํด์ผ ํจ
tvChannel9.execute();
remoteControl.offButtonWasPushed(2); // TV ๋๊ธฐ
}
}
- Command ์ธํฐํ์ด์ค๋ ์คํ(execute())๊ณผ ์คํ ์ทจ์(undo()) ๋ฉ์๋๋ฅผ ์ ์ํ๋ค.
- ์์ ์ ํด๋์ค(Light, Television)๋ ์ค์ ์์ ์ ์ํํ๋ ์ฝ๋๋ฅผ ๊ฐ์ง๋ค.
- ๊ตฌ์ฒด์ ์ธ ์ปค๋งจ๋ ํด๋์ค๋ค(LightOnCommand, TVOffCommand ๋ฑ)์ ์์ ์ ๊ฐ์ฒด๋ฅผ ๊ฐ์ง๋ฉฐ ์ด๋ฅผ ํตํด ์์ ์ ์ํํ๋ค.
- ํธ์ถ์(Invoker) ์ญํ ์ ํ๋ RemoteControl์ Command ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๊ณ ํ์ํ ์์ ์ ์คํํ๋ค.
- NoCommand ํด๋์ค๋ Null Object ํจํด์ ์ ์ฉํ์ฌ null ์ฒดํฌ๋ฅผ ์ค์ด๊ณ ์ฝ๋๋ฅผ ๋จ์ํํ๋ค.
โ๏ธ ์ฅ/๋จ์
โ ์ฅ์
- ํธ์ถ์์ ์์ ์์ ๋ถ๋ฆฌ(Decoupling)
- ๋ช ๋ น์ ์คํํ๋ ๊ฐ์ฒด(ํธ์ถ์)์ ์ค์ ์์ ์ ์ํํ๋ ๊ฐ์ฒด(์์ ์)๋ฅผ ๋ถ๋ฆฌํ๋ค.
- ์ด๋ก ์ธํด ์์คํ ์ ๊ฒฐํฉ๋๊ฐ ๋ฎ์์ง๊ณ ์ ์ฐ์ฑ์ด ์ฆ๊ฐํ๋ค.
- ๋ช
๋ น์ ํ์ฅ ์ฉ์ด์ฑ
- ๊ธฐ์กด ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ ์๋ก์ด ๋ช ๋ น์ ์ฝ๊ฒ ์ถ๊ฐํ ์ ์๋ค.
- ์๋ฅผ ๋ค์ด, ์์ด์ปจ ์ ์ด ๋ช ๋ น์ ์ถ๊ฐํ๋๋ผ๋ RemoteControl ํด๋์ค๋ ์์ ํ ํ์๊ฐ ์๋ค.
- ๋ช
๋ น์ ์กฐํฉ ๊ฐ๋ฅ
- ์ฌ๋ฌ ๋ช ๋ น์ ์กฐํฉํ์ฌ ๋ณตํฉ ๋ช ๋ น(Macro Command)์ ๋ง๋ค ์ ์๋ค.
- ์: "์ํ ๋ชจ๋" ๋ฒํผ์ผ๋ก ์กฐ๋ช ๋๊ธฐ, TV ์ผ๊ธฐ, ๋ณผ๋ฅจ ์กฐ์ ๋ฑ์ ํ ๋ฒ์ ์คํ
- ์คํ ์ทจ์(Undo) ๋ฐ ์ฌ์คํ(Redo) ์ง์
- ๋ช ๋ น ๊ฐ์ฒด๊ฐ ์ํ๋ฅผ ์ ์ฅํ๋ฏ๋ก ์ด์ ์์ ์ ์ทจ์ํ๋ ๊ธฐ๋ฅ์ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค.
- ๋ช ๋ น ์คํ ๊ธฐ๋ก์ ์คํ์ ์ ์ฅํ๋ฉด ๋ค์ค ์คํ ์ทจ์๋ ๊ฐ๋ฅํ๋ค.
- ๋ช
๋ น ๋ก๊น
๋ฐ ํธ๋์ญ์
์ง์
- ๋ช ๋ น์ ๊ฐ์ฒด๋ก ์ ์ฅํ๋ฉด ๋ช ๋ น์ ๋ก๊น ๊ณผ ์์คํ ๋ณต๊ตฌ๊ฐ ๊ฐ๋ฅํด์ง๋ค.
- ํธ๋์ญ์ ์์คํ ์์๋ ๋ช ๋ น ์งํฉ์ ์ ์ฅํ๊ณ ์คํจ ์ ๋กค๋ฐฑํ ์ ์๋ค.
โ ๋จ์
- ํด๋์ค ์ ์ฆ๊ฐ
- ๊ฐ ๋ช ๋ น๋ง๋ค ๋ณ๋์ ํด๋์ค๊ฐ ํ์ํ๋ฏ๋ก ์์คํ ์ ํด๋์ค ์๊ฐ ๋ง์์ง ์ ์๋ค.
- ๊ฐ๋จํ ๊ธฐ๋ฅ์๋ ์๋ก์ด ํด๋์ค๋ฅผ ๋ง๋ค์ด์ผ ํ๋ฏ๋ก ์ค๋ฒํค๋๊ฐ ๋ฐ์ํ ์ ์๋ค.
- ๋ณต์ก์ฑ ์ฆ๊ฐ
- ๋จ์ํ ํจ์ ํธ์ถ์ด ์ฌ๋ฌ ํด๋์ค์ ์ํธ์์ฉ์ผ๋ก ๋ณํ๋ฏ๋ก ์์คํ ์ด ๋ณต์กํด์ง ์ ์๋ค.
- ํนํ ์ฒ์ ํจํด์ ์ ํ๋ ๊ฐ๋ฐ์์๊ฒ๋ ์ดํดํ๊ธฐ ์ด๋ ค์ธ ์ ์๋ค.
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ฆ๊ฐ
- ๊ฐ ๋ช ๋ น๋ง๋ค ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ฏ๋ก ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ์ฆ๊ฐํ ์ ์๋ค.
- ๋ช ๋ น์ ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋ ๊ฒฝ์ฐ ๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ์ํ๋ค.
- ๋๋ฒ๊น
์ด๋ ค์
- ํธ์ถ ์ฒด์ธ์ด ๊ธธ์ด์ง๋ฉด ๋๋ฒ๊น ์ด ์ด๋ ค์์ง ์ ์๋ค.
- ํนํ undo/redo ๊ธฐ๋ฅ์ด ์์ผ๋ฉด ์ํ ์ถ์ ์ด ๋ณต์กํด์ง ์ ์๋ค.
๐ ์ ๋ฆฌ
์ปค๋งจ๋ ํจํด์ ์์ฒญ์ ๊ฐ์ฒด๋ก ์บก์ํํ์ฌ ๋ค์ํ ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์๋ ์ ์ฐํ ์์คํ ์ ๊ตฌ์ถํ๋ ๋์์ธ ํจํด์ด๋ค.
์ด ํจํด์ ํธ์ถ์์ ์์ ์๋ฅผ ๋ถ๋ฆฌํ์ฌ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๊ณ , ๋ช ๋ น์ ์คํ, ์ทจ์, ๋ก๊น , ํธ๋์ญ์ ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ ์ง์ํ๋ค. ๋์ ํด๋์ค ์๊ฐ ๋ง์์ง๊ณ ์์คํ ์ด ๋ณต์กํด์ง ์ ์๋ ๋จ์ ์ด ์๋ค.
โ ์ธ์ ์ฌ์ฉํ๋ฉด ์ข์๊น?
- ์์ ์ ๋ํ ์คํ ์ทจ์(undo)๊ฐ ํ์ํ ๋
- ๋ช ๋ น ๊ธฐ๋ก, ๋ก๊น , ํธ๋์ญ์ ์์คํ ์ด ํ์ํ ๋
- ๋ช ๋ น์ ์ง์ฐ ์คํ์ด๋ ์ค์ผ์ค๋ง์ด ํ์ํ ๋
- ๋งค๊ฐ๋ณ์ํ๋ ๊ฐ์ฒด๋ฅผ ํตํ ๋์ ์ํ์ด ํ์ํ ๋
- ๋ช ๋ น์ ํ์ ์ ์ฅํ๊ณ ์์ฐจ์ ์ผ๋ก ์คํํด์ผ ํ ๋
โ ์ธ์ ํผํด์ผ ํ ๊น?
- ๋จ์ํ ์์ ์ ๊ณผ๋ํ ๋ณต์ก์ฑ์ ์ถ๊ฐํ ๋
- ๋ช ๋ น ๊ฐ์ฒด๊ฐ ๋๋ฌด ๋ง์์ ธ์ ๊ด๋ฆฌ๊ฐ ์ด๋ ค์ธ ๋
- ์คํ ์ทจ์๋ ๋ก๊น ๋ฑ์ ๊ธฐ๋ฅ์ด ํ์ ์์ ๋
- ์ฑ๋ฅ์ด ์ค์ํ๊ณ ๋ช ๋ น ๊ฐ์ฒด์ ์ค๋ฒํค๋๊ฐ ๋ฌธ์ ๊ฐ ๋ ๋