학교/design pattern

[week04] Command pattern

pasongsongeggtak 2022. 9. 30. 13:44

1. Command Pattern

2. Given Hardware & Our Vendor Classes

3. Without Using Command Pattern

4. Implementing Command interface

5. Our Approach

6. Collaborations

7. Extending the Remote Control

8. After Setting the Commands


1. Command Pattern

목적

  • Request를 객체로 인캡슐화하자
  • 각 command 객체는 execute 또는 undo 메서드만 노출함
  • Request가 queuing과 callback과 같은 relationships에 근거해 전형적인 객체로 다루어짐

 

Use when?

  • Requests가 다양한 시간에 다양한 순서로 명세되고, 큐에 보관되고, 실행될 필요가 있을 때
  • Requests의 기록(history)이 필요할 때
  • invoker가 invocation을 다루는 객체로부터 분리되어야할 때

 

 

2. Given HardWare & Our Vendor Classes

여러 서비스들이 합쳐진 리모트 컨트롤

 

 

3. Without Using Command Pattern

  이런 식으로 코드 짜면, button 행동을 수정하고 싶을때마다 client code에 손을 대야 함

if(command == Slot1On)
	light.on();
else if(command== Slot1Off)
	light.off();

 

 

4. Implementing Command interface

// Command interface
public interface Command{
	public void execute();
    //public void undo();
}
public class LightOnCommand implements Command{
	Light light; // Stores info. about its receiver
    
    public LightOnCommand(Light light){
    	this.light = light;
    }
    
    public void execute(){
    	light.on();
    }
}
public class LightOffCommand implements Command{
	Light light;
    public LightOffCommand(Light light){
    	this.light = light;
    }
    public void execute(){
    	light.off();
    }
}
// Using the command object (Building Invoker)
public class SimpleRemoteControl{
	Command slot;
    
    public SimpleRemoteControl(){ }
    
    public void setcommand(Command command){
    	slot = command;
    }
    
    public void buttonWaspressed(){
    	slot.execute();
    }
}
// Client Program
public class RemoteControlTest{
	public static void main(String[] args){
    	SimpleRemoteControl remote = new SimpleRemoteControl();
        Light light = new light();
        LightOnCommand lightOn = new LightOnCommand(light);
        remote.setCommand(lightOn);
        remote.buttonWasPressed();
    }
}

 

 

5. Our Approach

1) Client

  • client는 command 객체를 만들 수 있음
  • command 객체는 receiver의 action 집합으로 구성됨

 

2) Command

  • action들과 Receiver는 command 객체에 함께 붙어 있음
  • command 객체는 execute() 메서드를 제공함
  • execute() 메서드는 action들을 인캡슐화하고, Receiver의 action들을 일으키기 위해 호출됨

 

3) Invoker

  • client는 Invoker 객체의 setCommand() 메서드를 호출해, Invoker 객체로 command 객체를 넘긴다.
  • 어느 시점에, Invoker는 command 객체의 execute() 메서드를 호출한다.

 

4) Receiver

  • Receiver의 action들을 결과로 함

 

 

request를 객체로 인캡슐화 해라.

그러면, clients와 다양한 requests, queue, log requests 등을 파라미터화하고, 실을 수 없는(unloadable) operations을 지원해라.

 

 

6. Collaborations

 

 

7. Extending the Remote Control

public class RemoteControl{

	Command[] oncommands;
    Command[] offcommands;
    
    RemoteControl(){
    	oncommands = new Command[7];
        offcommands = new Command[7];
        
        Command noCommand = new NoCommand();
        for(int i=0; i<7; i++){
        	onCommand[i] = noCommand;
            offCommand[i] = noCommand;
        }
    }
}
public class NoCommand implements Command{
	public void execute(){}
}
public void setCommand(int slot, Command oncommand, Command offcommand){
	oncommand[slot] = oncommand;
    offcommand[slot] = offcommand;
}

public void onButtonWasPushed(int slot){
	oncommand[slot].execute();
}

public void offButtonWasPushed(int slot){
	ffncommand[slot].execute();
}
//Client Program
public class RemoteLoader{
	public static void main(String[] args){
    	// create invoker
        RemoteControl remotecontrol = new RemoteControl();
        
        // create receivers
        Light livingRoomLight = new Light("Living Room");
        Light kitchenLight = new Light("Kitchen");
        
        // create commands
        Command livingRoomLightOn = new LightOnCommand(livingRoomLight);
        Command livingRoomLightOff = new LightOffCommand(livingRoomLight);
        Command kitchenlightOn = new LightOnCommand(kitchenLight);
        Command kitchenlightOff = new LightOffCommand(kitchenLight);
    
    	// linking the invoker with the commands
        remotecontrol.setCommand(0, livingRoomLightOn, livingRoomLightOff);
        remotecontrol.setCommand(1, kitchenlightOn, kitchenlightOff);
        remotecontrol.onButtonWasPushed(0);
        remotecontrol.offButtonWasPushed(0);
        remotecontrol.onButtonWasPushed(1);
        remotecontrol.offButtonWasPushed(1);
    }
}

 

 

8. After Setting the Commands