개발/DesignPatterns

7. Command Pattern(커맨드 패턴)

huiyu 2014. 7. 20. 11:02

Command Design Pattern

(커맨드 패턴)


Define

 커맨드 패턴을 이용하면 요구사항을 객체로 캡슐화 할 수 있으며, 매개변수를 써서 여러 가지 다른 요구 사항을 집어넣을 수도 있습니다. 또한 요청 내역을 큐에 저장하거나 로그로 기록할 수도 있으며, 작업취소 기능도 지원 가능합니다.


Structure


 - 커맨드 객체는 일련의 행동을 특정 리시버하고 연결시킴으로써 요구사항을 캡슐화 한 것을 의미한다.

- 행동과 리시버를 한 객체에 집어넣고, 외부에는 execute()메소드 하나만 외부에 공개한다. 이 메소드 호출에 의해 리시버에서 일련의 작업이 처리된다.
- 외부에서는 어떤 객체가 리시버인지, 그 리시버가 무슨일을 하는지 알 수 없고 그냥 execute()메소드만 호출하면 요구사항이 처리된다.

Advantage

 - 사용자의 요청을 객체화, 그 객체만 있으면 해당 커맨드가 어떤 작업을 수행했는지 알 수 있다.

- 취소작업이나 로그기능 구현이 가능하다.

Code-Java


- Command Pattern을 이용하여 집안 물건을 컨트롤 하는 리모컨을 구현해보자!

- Command Interface
public interface Command {
	public void execute();
	public void undo();
}


- ConcreteCommand(Light Class, GarageDoor Class) : Command 인터페이스를 구현한 객체로 집안의 불을 키고끄는 일과 차고를 관리하는 일을 한다.

- Receiver(Light, GarageDoor class)

 Light Class

public class Light {
	public void on(){}
	public void off(){}
}

class LightOnCommand implements Command{
	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{
	Light light;
	
	public LightOffCommand(Light light) {
		this.light = light;
	}
	
	@Override
	public void execute(){
		light.off();
	}

	@Override
	public void undo() {
		light.on();
	}
	
}

Garage Door Class

package headfirst.designpatterns.chapter6.example;

public class GarageDoor {
	public void up() {
	}
	public void down(){
	}
	public void stop(){
	}
	public void lightOn(){
	}
	public void lightOff(){
	}
}

class GarageDoorOpenCommand implements Command{
	GarageDoor garageDoor;
	public GarageDoorOpenCommand(GarageDoor garageDoor) {
		this.garageDoor = garageDoor;
	}
	
	@Override
	public void execute(){
		garageDoor.up();
	}

	@Override
	public void undo() {
		// TODO Auto-generated method stub
		
	}
	
}


- Invoker(SimpleRemoteControl) : 명령이 들어있으며, Command객체를 가지고 있어 execute()로 명령을 실행한다.

class SimpleRemoteControl{
	Command slot;
	
	public SimpleRemoteControl(){ }
	
	public void setCommand(Command command){
		slot = command;
	}
	
	public void buttonWasPressed(){
		slot.execute();
	}
}


- Main

public class Main {
	public static void main(String[] args) {
		SimpleRemoteControl remote = new SimpleRemoteControl();
		Light light = new Light();
		GarageDoor garageDoor = new GarageDoor();
		LightOnCommand lightOn = new LightOnCommand(light);
		GarageDoorOpenCommand garageOpen = new GarageDoorOpenCommand(garageDoor);
		
		remote.setCommand(lightOn);
		remote.buttonWasPressed();
		remote.setCommand(garageOpen);
		remote.buttonWasPressed();
	}
}


+ 매크로 커맨드,  Redo/Undo, Null class

728x90
반응형