여러 행동을 호출해야 하는 경우 여러 행동을 커맨드로 추상화하여 사용하는 쪽에서는 커맨드가 어떻게 행동하는 지 관심없이 사용하기만 하도록 구현하는 패턴이다. 이 패턴은 커맨드를 사용하는 쪽에서 커맨드를 실행하기 위해서 어떤 객체가 사용되는지 알아지 않아도 되는 장점이 있다. 커맨드 패턴은 명령의 개념을 캡슐화해서 시스템과 연결된 장치의 논리적인 상호 연결을 분리해낼 수 있다.
물리적 분리
커맨드 패턴을 사용하면 사용자에게서 데이터를 받는 코드와 그 데이터를 검증하고 작업을 하는 코드, 도메인 객체를 분리할 수 있다. 데이터를 받는 코드에서 커맨드의 실행 코드와 검증 코드와 물리적으로 분리 된다.
시간적 분리
사용자에게서 데이터를 입력받는 역할과 그 데이터를 검증하고 작업을 하는 코드를 물리적으로 분리할 수 있다고 했다. 이를 다르게 생각해보면 데이터를 입력받았다고 바로 검증과 실행을 하지 않아도 된다는 의미다. 즉 명령을 일단 다 생성해서 모아놓고 특정 시점에 몰아서 명령을 검증하고 실행할 수 있다는 의미이다.
되돌리기
1 2 3 4
publicclassCommand{ voiddo(); voidundo(); }
커맨드에 실행하는 메서드말고 되돌리기 메서드를 선언해놓으면 롤백 기능도 구현할 수 있다. 위처럼 인터페이스로 실행과 실행 취소 메서드를 선언해놓고 각 명령마다 실행과 실행 취소 로직을 구현해놓으면 된다. 직원 임금 관리 서비스에서 직원을 추가하는 명령이 있다고 할 때 실행시키는 메서드는 직원 객체를 생성하고 저장소에 저장하는 방식으로 구현된다. 실행 취소 메서드는 저장소에 해당 직원의 데이터를 제거하는 방식으로 구현할 수 있을 것이다.
액티브 오브젝트 패턴
액티브 오브젝트 패턴은 커맨드 패턴의 응용된 버전으로 다중 제어 스레드 구현을 위해 등장했다. 액티브 오브젝트 패턴은 하나의 스레드로 멀티 스레드가 이벤트 방식으로 작동하는 것처럼 구현할 수 있어서 런타임 스택을 여러개 만들지 않아도 된다. 즉 멀티 스레드를 활용하고 메모리가 부족한 상황에서 사용할 만한 대안이다.
액티브 오브젝트 패턴은 커맨드를 모아두고 꺼내서 실행하는 엔진과 실행 시킬 커맨드, 마지막으로 실행 시킬 조건을 다루는 커맨드 이렇게 세가지로 구성된다.
엔진
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
publicclassActiveObjectEngine{
privatefinal LinkedList<Command> commands = new LinkedList<>();
자신이 엔진에 의해 실행된 경우가 없다면 현재 시간을 시작 시각으로 기록하고 다시 엔진에 자신을 집어넣는다. 자신이 엔진에 의해 실행된 경우가 있으면 현재 시각과 시작 시각을 비교해서 커맨드 실행 조건에 달성했는 지 체크한다. 조건에 달성했다면 wakeUpCommand 즉 우리가 원래 실행하려고 했던 커맨드를 실핸한다.