Design pattern/행동 패턴

[디자인 패턴] 15장 명령 패턴

미스터로즈 2021. 5. 20. 18:35

공부하기 위해서 요약정리해놓은 것입니다..

 

정확하고 꼼꼼한 자료는 쉽게 배워 바로 써먹는 디자인 패턴을 확인하시고

코드는 github.com/infohojin/patterns 을 참고해 주세요.

 

명령 패턴은 행동의 호출을 캡슐화하여 실행하는 패턴입니다.

 

명령

명령 패턴은 행동을 객체로 캡슐화하여 전달합니다.

객체지향 프로그래밍에서는 데이터와 행위를 하나의 객체로 묶어 캡슐화합니다. 객체는 동작의 행위와 행위를 실행하는 호출 메서드를 함께 만드는데, 구현하는 방법은 작업의 객체화라고 합니다.

 

기존에는 동작 명령을 한수나 메서드로 구현했습니다. 하지만 명령 패턴에서는 동작 명령을 하나의 클래스 형태로 표현하며 수행하는 동작을 메서드 형태가 아닌 객체 형태로 별도 생성합니다.

 

명령 패턴은 내부 동작을 위한 모든 정보를 하나의 객체로 캡슐화하고 분리된 객체를 실제 수행으로 전환합니다.

명령 패턴은 유사한 동작을 하나의 객체로 묶어 실행하는 행위 패턴입니다.

 

명령 패턴은 동작을 하나의 객체로 캡슐화하여 행위를 실행합니다. 명령 패턴은 실제 작업을 수행하는 객체와 이를 실행하는 객체로 분리하여 설계합니다.

 

분리된 작업 객체와 실행 객체는 의존성 주입을 통해 명령 객체에 위임을 요청합니다. 명령 객체는 실행 메서드에서 위임된 객체를 실행함으로써 실제 동작을 처리합니다.

 

명령 패턴은 매개변수 형태로 전달합니다. 전달 받은 객체를 바로 실행하는 것이 아니라 명령 객체로 프로퍼티에 저장한 후 임의의 시점에서 일괄 실행하는 형태입니다.

 

명령 패턴은 객체의 실행 동작 시점을 분리하여 지연시키는데, 이는 절차지향적 개발에서 콜백함수를 처리하는 것과 같습니다.

 

명령 패턴은 작업의 요청과 처리를 분리하고 요청하는 작업들을 객체로 캡슐화합니다. 객체의 실제 동작과 호출 실행 부분을 분리하면 동작의 실행 시점을 제어할 수 있습니다.

명령 패턴은 코드의 동작을 순차적으로 실행하지 않고 큐에 쌓아놓았다가 특정 시점에 호출합니다.

 

명령 패턴은 4가지의 구성 요소를 갖고 있으며, 이 구성 요소는 명령 객체의 인스턴스를 저장하고 호출을 관리합니다.

 

- 인터페이스

- 명령

- 리시버

- 인보커

 

인터페이스

명령 패턴은 동일한 명령 구조와 호출을 위해 인터페이스를 정의합니다. 인터페이스는 명령 패턴의 핵심이며, 통일화된 실행 동작을 유지하는 데 중요한 구성 요소입니다.

 

명령 패턴은 일관적인 코드 실행과 재사용을 위해 실행 메서드 호출을 하나로 통일 하는데, 인터페이스를 적용해 실행 메서드의 통일화를 강제적으로 적용합니다.

 

실행되는 모든 객체는 인터페이스의 적용을 받고, 실행 객체는 execute() 메서드를 반드시 구현해야 합니다.

 

명령

명령으로 실행되는 실체 객체를 구현합니다. 명령 객체는 일급 객체로 분류합니다.

 

객체를 생성할 때는 인터페이스에서 정의된 실행 메서드를 반드시 같이 구현하여 작성합니다. 이는 명령 패턴이 객체를 실행하는 유일한 메서드입니다.

 

명령 객체는 Command 인터페이스를 이용해 동일한 서브 클래스로 공유하는 것과 같습니다.

인터페이스를 적용하여 다수의 명령 객체를 통일합니다.

 

리시버

명령 패턴은 처리해야 하는 명령을 하나의 객체로 캡슐화합니다. 명령의 실행 동작을 내부적으로 구현하는 것과 달리 외부로부터 객체를 위임 받아 대신 호출합니다.

 

실제 객체는 클라이언트에서 미리 생성되고 명령 객체의 인자로 전달됩니다.

 

 

우리는 간단한 명령 하나를 실행한 것이지만, 그 안에서는 상당수의 복잡한 기능이 처리될 수도 있습니다.

앞에 나온 명령 객체처럼 동작 객체를 위임 받아 함께 실행합니다.

 

인보커

명령 패턴은 다수의 명령 객체를 관리합니다. 인보커는 생성된 명령 객체를 저장하고 관리하는 역활을 합니다.

 

인보커는 작업을 저장하는 객체입니다. 명령 객체를 생성하여 인보커에 등록하면 저장된 명령 객체를 관리할 수 있습니다.

인보커는 내부족으로 명령 객체를 담고 있는 배열입니다. 또한 배열에 새로운 명령 객체를 추가합니다.

 

명령의 동작을 다른 말로 이벤트라고 합니다. 이러한 이벤트 명령은 이벤트 목록에 저장되고 명령을 순차적으로 처리합니다.

 

인보커에는 실제 동작의 리시버 객체를 저장합니다.

 

클라이언트

클라이언트는 명령 패턴에서 새로운 명령 객체를 생성하고 생성된 명령 객체를 다시 리시버에 전달하며 인보커에 저장된 명령 객체 실행을 요청합니다.

 

클라이언트는 명령 객체를 생성하고 리시버 객체에 명령 인자값으로 명령 객체를 전달하는 역활을 합니다. 또한 생성된 명령 객체를 인보커에 저장하며 실행과 관리를 대신 처리합니다.

 

익명 클래스에 인터페이스를 적용하여 명령 객체를 직접 인보커에 전달합니다. 인보커 배열에 저장된 명령 객체는 호출할 수 있는 execute() 메서드를 갖고 있습니다.

익명함수로 구현된 인보커의 모든 명령 객체는 반복자 패턴을 응용하여 매크로 호출해봅니다.

 

undo

명령 패턴은 각각의 명령 동작을 캡슐화하여 실행합니다. 명령을 실행할 수 있다는 것은 반대로 취소도 가능하다는 의미입니다.

 

윈도우와 같은 응용 프로그램을 보면 메뉴에 실행 명령과 이를 취소할 수 있는 undo 기능이 같이 있는 것을 확인할 수 있습니다.

 

명령 객체에 꼭 1개의 실행 메서드만 만들어서 사용할 필요는 없습니다. 다수의 메서드를 인터페이스 형태로 선언해 다양한 실행 동작을 지정할 수 있습니다.

 

장단점

명령 패턴은 요청과 실행이 서로 의존하지 않는 구조를 만들 때 매우 유용합니다.

 

기존의 코드 수정 없이 명령 객체를 추가해 실행 동작을 확장할 수 있습니다. 또한 여러 개의 명령을 하나의 리스트로 묶어 실행합니다.

 

명령 패턴은 다수의 명령이 존재할 때 클래스의 개수가 증가합니다. 클라이언트는 명령 클래스의 인스턴스를 생성하며 명령 실행은 인보커가 처리합니다.