본문 바로가기
Programming/DesignPattern

[디자인 패턴] 커맨드(Command) 패턴

by Blemish 2021. 5. 20.

Goal

  • 커맨드 패턴을 이해한다.

 

커맨드(Command) 패턴

요청을 객체의 형태로 캡슐화하여 사용자가 보낸 요청을 나중에 이용할 수 있도록 이름, 매개변수 등 요청에 필요한 정보를 저장 또는 로깅, 취소할 수 있게 하는 패턴

 

 

  • 커맨드 패턴은 실행될 기능을 캡슐화함으로써 기능의 실행을 요구하는 호출자(Invoker)와 실제 기능을 실행하는 수신자(Receiver) 사이의 의존성을 제거한다.
  • 이벤트가 발생하였을 때 실행될 기능이 다양하면서도 변경이 필요할 때 이벤트를 발생하는 클래스를 수정하지 않고 재사용할 때 유용하다.

 

Example

 

램프의 불이 켜지는 프로그램을 구현해보자.

클래스 다이어그램

램프에 불이 켜지는 프로그램을 개발하려면 버튼을 눌려졌음을 인식하는 Button 클래스와 불을 켜는 기능을 제공하는 Lamp 클래스를 구현해야 한다.

OnPressed를 누르면 Lamp 클래스의 TurnOn 함수가 호출되어 램프에 불이 켜진다.

Lamp, Button 코드

이번엔 버튼을 누르면 램프 불을 끄는 기능을 기능을 추가해보자.

 

Lamp 클래스는 불을 끄는 기능만 추가하면 된다. 하지만 Button 클래스는 버튼을 눌렀을 때 On 버튼을 눌렀는지 또는 Off 버튼을 눌렀는지에 대해서 확인해주는 코드가 추가적으로 구현되어야 한다. 

따라서 기존의 코드를 수정해야 하므로 OCP에 위배된다.  

 

OnPressed에 매개변수를 추가하여 매개변수 값에 따라 불이 켜지거나 꺼지는 기능을 할 수 있도록 구현하였다.

 

Question

  • 기존 코드를 수정하지 않고 기능을 추가할 수 있는 방법이 있을까? -> Button 클래스의 OnPressed 메서드에서 직접 기능을 수행하도록 하지 않고 기능을 외부에서 제공받아 캡슐화해 OnPressed 메서드에서 호출하는 방법을 사용

 

커맨드(Command) 패턴을 사용하고 기존의 램프를 켜고 끄는 기능 외에 취침등을 켜는 기능을 추가해보자.

 

  •  Button 클래스의 Execute(기존 OnPressed를 대체) 메서드에서 직접적으로 램프를 켜고, 끄고, 취침등을 켜는 기능을 수행하지 않고 Command 인터페이스의 Execute 메서드를 호출하도록 수정하였다.
  •  Command 인터페이스를 구현하는 LampSleepingCmd, LampTurnOnCmd, LampTurnOffCmd를 구현하고 Lamp 클래스를 참조하여 각 클래스에서 필요한 기능을 호출할 수 있도록 구현하였다.
  •  버튼을 눌렀을 때 필요한 임의의 기능은 Command 인터페이스를 구현한 클래스의 객체를 Button 객체에 설정해서 실행할 수 있다.

 

 

댓글