Search results for 'command'

행위(Behavioral) 패턴 - Command

2007/05/06 20:58

Chain of Responsibility 패턴은 클래스들의 체인들을 따라서 요청들을 진행하지만, Command 패턴은 특별한 모듈로 하나의 요청을 진행. 그것은 하나의 객체 내부의 특정한 동작을 위한 하나의 요청을 둘러싸고 알려진 public 인터페이스를 줌. 그것이 수행하게 될 실제적인 동작에 대한 알고 있는 것 없이 요청들을 만들 수 있는 능력을 클라이언트에게 주게 함. 그리고 어떤 방식으로든 클라이언트 프로그램에 영향을 주는 것 없이 동작을 변경할 수 있도록 해야함.

1. 동기
명령과 요청 자체를 객체 안에 캡슐화하여 포함시킬 수 있음. 그러면 이 명령 객체를 받은 클라이언트 객체들은 명령의 내용에 따라 각기 다르게 행동할 수 있으며 명령들을 큐에 저장하거나 로그에 기혹하여 나중에 사용할 수 있음. 또한 명령을 수행하기 이전 상태로 복원(undo)할 수 있음

2. 고려해야 할 사항

  • 다이나믹하게 새로운 액션을 추가하고 기존 액션을 수정하는 작업이 쉬워야 함.
  • 클라이언트가 요청해야 할 수 있는 많은 액션들이 존재하지만 클라이언트가 요청하는 방법은 간단해야 함.
  • 클라이언트는 자신의 요청이 어떻게 핸들링 되는지에 대하여 몰라야 함.
  • 클라이언트가 요청하기 위해 사용할 인터페이스는 간단해야 함.
  • 이전에 수행된 액션들을 원 상태로 되돌리거나 다시 수행하기 위해 수행했던 액션들에 대한 기록을 유지.

3. 구조

사용자 삽입 이미지

Client.java (Language : java)
  1. public class Client {
  2.    public static void main(String[] args) {
  3.       Command checkOut = new CheckOutCommand();
  4.       LibraryCommandInvoker invoker = new LibraryCommandInvoker();
  5.       invoker.executeCommand(checkOut);
  6.       invoker.redoNextCommand();
  7.       invoker.undoLastCommand();
  8.    }
  9. }
LibraryCommandInvoker.java (Language : java)
  1. public class LibraryCommandInvoker {
  2.    private int lastCommand;
  3.    private ArrayList history = new ArrayList();
  4.    
  5.    public void executeCommand(Command lc) {
  6.       lc.execute();
  7.       history.add(lc);
  8.       lastCommand = history.size() - 1;
  9.       System.out.println("execute =>" + lastCommand);
  10.    }
  11.    
  12.    public void redoNextCommand() {
  13.       System.out.println("redo =>" + lastCommand + " " + history.size());
  14.       if (lastCommand < history.size()) {
  15.          ((Command)(history.get(lastCommand))).execute();
  16.          history.add(history.get(lastCommand));
  17.          lastCommand++;
  18.       }
  19.    }
  20.    
  21.    public void undoLastCommand() {
  22.       System.out.println("undo =>" + lastCommand);
  23.       ((Command)(history.get(lastCommand))).undo();
  24.       history.remove(lastCommand);
  25.       lastCommand--;
  26.    }
  27. }
Command.java (Language : java)
  1. public interface Command {
  2.    public void execute();
  3.    public void undo();
  4. }
CheckOutCommand.java (Language : java)
  1. public class CheckOutCommand implements Command {
  2.    public void execute() {
  3.       System.out.println("execute check out command");
  4.    }
  5.    
  6.    public void undo() {
  7.       System.out.println("cancel check out command");
  8.    }
  9. }


4. 자바 프로그래밍 언어에서의 사용 예

사용자 삽입 이미지

  • GoF Command 패터는 Apache Struts 웹 어플리케이션 프레임웍과 같은 다양한 엔터프라이 프레임 웍에서 사용됨.
  • Floyd Marinescu가 쓴 EJB Design Patterns라는 책에서는 Command 패턴을 EJB Command 패턴이라고 문서화하고 있음.
  • EJB Command 패턴은 클라이언트와 EJB 레이어간 결합도를 줄임으로써 비즈니스 로직 변경으로 인한 개발 프로세스를 단순화시키기 위한 방법을 제공.
  • GoF Command 패턴과 EJB Command 패턴의 주요 차이점은 EJB Command 패턴에서 Invoker 클래스가 stateless 세션 빈임.

5. 결과

  • 장점
    케이스 로직을 줄일 수 있음.
    확장(extensibility)이 용이.
    명령어 취소(undo) 오퍼레이션을 쉽게 제공할 수 있음.
    여러 개의 명령어를 큐에 놓음으로써 명령을 비동기적으로 수행할 수 있음.
  • 단점
    객체 생성, 파괴, 사용에 있어서 많은 오버헤드가 발생할 수 있음.
    어플리케이션의 구조가 더 복작해 짐.
이올린에 북마크하기

happyness Programming/J2EE Patterns , ,

2007/05/06 20:58 2007/05/06 20:58
[로그인][오픈아이디란?]