본문 바로가기

IT 살이/04. 기술 - 아키텍처

커맨드 패턴

이번 포스트는 개인적인 메모다. 나름대로 핵심들이라고 생각되는 사항들을 다짜고짜 거두절미하고 나열한다( 시간나면 좀 자세히 정리해야 겠다. 언제가 될지 모르겠지만...-_-;;)

디자인 패턴의 각 유형을 정의내린다는 것은 참 힘들다. 차라리 어떤 점이 편리한지 응용성이 어떤지를 정리하는 것이 더 쉬우면서도 유용한 것 같다. 달봉이는 지금 스마트클라이언트 어플리케이션의 클라이언트측 프레임워크를 제작해서 사용하고 있다. 그 구현 내용중에서 커맨드 패턴이라는 것을 사용하고 있다. 해서 이 포스트에서는 나름대로 정리를 좀 해 놔야 할 것 같다. 안해 놓으면 잊어버리고 같은 문제로 또 언젠가는 고민하게 된다( 요즘은 눈에 띄게 기억력이 떨어진 것 같다 쓰으...).

■ 기본 커맨드 패턴

1. 커맨드 객체는 특정 객체에 대한 특정 작업 요청을 함께 캡슐화한다.

1324395282

[그림] 커맨드 객체 구조

실제로, 요청을 처리하는 리시버(receiver)에 대한 참조와 Execute() 메소드를 가지고 있다. Execute()에서는 리시버의 메소드를 호출함으로써 필요에 따라서는 일련의 메소드를 복수해 호출해서 비즈니스 요청을 수행한다. 커맨드 객체를 호출하는 측에서는 단지 Execute() 메소드만 호출하면 된다. 그 커맨드가 구체적으로 Execute()를 어떻게 구현하는지는 알 필요가 없다.

2. 작업을 요청하는 쪽(리모콘)과 작업을 하는 쪽(TV, CD 플레이어)을 커맨드 객체를 통해서 분리할 수 있다.

3. 캡슐화시 매개변수를 써서 여러 가지 다른 요구사항을 집어넣을 수도 있다.

ConcreteCommand(매개변수);

4. 커맨드 패턴을 사용하면 요청 내역을 큐에 저장해서 스케쥴러, 작업큐같은 프로그램을 만들거나 또는 작업 내역을 스택성 로그로 기록해서 도중에 에러가 발생하면 롤백하는 구조의 프로그램을 만들 수도 있다. 이것을 좀더 정교하게 만들면 트랜잭션 시스템을 구현하는 것도 가능하다.

레퍼런스

Head First Design Patterns 스토리가 있는 패턴 학습법

-Oreilly, 한빛 미디어

■ 커맨드 패턴 변형

앞에서는 커맨드 객체가 리시버(Receiver)에 대한 참조와 그 리시버를 이용해서 요청을 구현해야 하는 Execute()가 있어야 한다. 이런 경우는 리시버에 대한 참조를 가지고 있어야 한다는 점에서 리시버와 커맨드 객체와의 커플링이 존재하게 된다. 이런 커플링을 없애기 위해서 때로는 리시버와 Execute() 대신에 단일 이벤트 멤버로 대신할 수 있다.

1258535158

[그림] 커맨드 객체

1. One handler : 하나의 이벤트 핸들러에서 여러 UI 이벤트(메뉴, 툴바)를 핸들링할 수 있다.

2. the business logic for handling the command : 그 하나의 이벤트 핸들러에 해당 명령을 핸들링할 수 있는 비즈니스 로직을 중앙 관리할 수 있다.

■ 커맨드 패턴 구현의 핵심 요소

커맨드 관리자

- 애플리케이션에서 필요로 하는 모든 커맨드들의 중앙 저장소

- 애플리케이션이 커맨드 목록을 관리할 수 있는 컬렉션용 API를 제공.

레퍼런스

Command Management

Use Design Patterns to Simplify the Relationship Between Menus and Form Elements in .NET