3. ● 만능 버튼 만들기
● Command Pattern
● 리모컨 만들기
● Null 객체
● 커맨드 패턴의 활용
4. 만능 버튼 만들기(1)
- 눌리면 특정 기능을 수행하는 버튼 만들기
- 버튼이 눌렸을 때 램프의 불이 켜지는 프로그램
- 버튼을 눌렀을 때 램프가 켜지는 대신 다른 기능을 실행하
게 하려면? 버튼을 눌렀을 때 알람이 시작되게 하려면?
- 버튼을 누르는 동작에 따라 다른 기능을 실행하게 하려면?
버튼을 처음 눌렀을 땐 램프를 켜고, 두 번째 눌렀을 때는
알람을 동작하게 하려면?
5. 만능 버튼 만들기(2)
- 버튼을 눌렀을 때 램프가 켜지는 대신 다른 기능을 실행하
게 하려면? 버튼을 눌렀을 때 알람이 시작되게 하려면?
- 기능을 변경하려고 기존 Button 클래스의 코드를 수정하는
것은 Open Close Principle(OCP, 기존의 코드를 변경하지
않고 기능을 추가) 에 위배됨
6. 만능 버튼 만들기(3)
- 버튼을 누르는 동작에 따라 다른 기능을 실행하게 하려면?
버튼을 처음 눌렀을 땐 램프를 켜고, 두 번째 눌렀을 때는
알람을 동작하게 하려면?
- 기능을 변경하려고 기존 Button 클래스의 코드를 수정하는
것은 Open Close Principle(OCP, 기존의 코드를 변경하지
않고 기능을 추가) 에 위배됨
7. 만능 버튼 만들기 해결책
- 새로운 기능을 추가하거나 변경하더라도 Button 클래스를
그대로 사용
- pressed 메소드에서 구체적인 기능(램프켜기, 알람울리기)
을 직접 구현하는 대신, 버튼을 눌렀을 때 실행될 기능을
Button 클래스 외부에서 제공받아 캡슐화하여 pressed 메
소드에서 호출하는 방법 사용
8. Command Pattern(1)
- 커맨드 패턴은 이벤트가 발생했을 때 실행 될 기능이 다양
하면서도 변경이 필요한 경우에 이벤트를 발생시키는 클래
스를 변경하지 않고 재사용 하고자 할 때 유용
- 커맨드 패턴은 실행될 기능을 캡슐화 함으로써 기능의 실
행을 요구하는 호출자(invoker) 클래스와 실제 기능을 실행
하는 수신자(Receiver) 클래스 사이의 의존성을 제거한다.
따라서 실행될 기능의 변경에도 호출자 클래스를 수정 없
이 그래도 사용할 수 있도록 해준다.
9. Command Pattern(2)
- 매개변수를 써서 여러가지 다른 요구사항을 집어넣을 수
있다.
- 요청 내역을 큐에 저장하거나 로그로 기록할 수도 있으며,
작업취소 기능도 지원 가능하다.
- 커맨드 패턴을 제대로 사용할 수 있으면 메타 커맨드 패턴
(Meta Command Pattern) 이라는 것도 어렵지 않게 구현
할 수 있다.
- 메타 커맨드 패턴을 이용하면 명령들로 이루어진 매크로
(Macro)를 만들어서 여러개의 명령의 한 번에 실행 할 수
10. Command Pattern(3)
- Command : 실행 될 기능에 대한 인터페이스, 실행 될 기능
을 execute 메서드로 선언함
- ConcreteCommand : 실제로 실행되는 기능을 구현, 즉,
Command 라는 인터페이스를 구현함
- Invoker : 기능의 실행을 요청하는 호출자 클래스
- Receiver : ConcreteCommand 에서 execute 메서드를 구
현할 때 필요한 클래스. 즉 ConcreteCommand의 기능을
실행하기 위해 사용하는 수신자 클래스
13. Command Pattern 순차 다이어그램
1) 클라이언트가 원하는 커맨드 객체를 생성
2) 생성된 커맨드 객체를 Invoker 객체에 바인딩
3) 나중에 Invoker 객체에서는 바인딩 된 커맨드 객체의
execute 메서드를 호출
4) execute 메소드는 Receiver 객체의 action 메소드를 호출하
여 원하는 기능 실행
15. Null Object
- 딱히 리턴할 객체는 없지만 클라이언트 쪽에서 null 을 처리
하지 않도록 하고 싶을 때 널 객체를 활용.
- 리모컨의 경우, 처음 리모컨을 가지고 왔을 때는 아무 명령
도 할당되지 않은 상태이므로, execute() 메소드가 호출됐
을 때 아무일도 하지 않지만, 빈 자리를 채우기 위한 용도로
NoCommand 라는 객체를 집어넣어 두면 편하다.
16. 커맨트 패턴의 활용 - 요청을 큐에 저장하기
- 커맨드를 이용하면 computation의 한 부분(리시버와 일련
의 행동)을 패키지로 묶어서 일급 객체 형태롤 전달 하는 것
도 가능.
- 어떤 클라이언트 애플리케이션에서 커맨드 객체를 생성하
고 나서 한참 후에도 그 컴퓨테이션을 호출 할 수 있다.
- 스케줄러나 스레드 풀, 작업큐와 같은 다양한 용도에 적용
할 수 있다.
17. 커맨트 패턴의 활용 - 요청을 로그에 기록하기
- 커맨드 패턴을 사용하면 store() 와 load() 라는 메소드를 추
가하여 어떤 애플리케이션에서의 모든 행동을 기록해놨다
가 그 애플리케이션이 다운되었을 경우, 나중에 그 행동들
을 다시 호출해서 복구를 할 수 있다.
- 로그 기록은 어떤 명령을 실행하면서 디스크에 실행 히스
토리를 기록하며, 애플리케이션이 다운되면 커맨드 객체를
다시 로딩하고 execute 메소드들을 자동으로 순서대로 실
행하면 된다.