메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

한빛랩스 - 지식에 가능성을 머지하다 / 강의 콘텐츠 무료로 수강하시고 피드백을 남겨주세요. ▶︎

IT/모바일

Enterprise Flex RIA 해부(15) : 커맨드와 컨트롤러

한빛미디어

|

2008-10-24

|

by HANBIT

11,467

제공 : 한빛 네트워크
저자 : Tony Hillerson
역자 : 추홍엽
원문 : Anatomy of an Enterprise Flex RIA Part 15: Commands and Controllers

지난 연재에서는 Cairngorm의 비즈니스 위임자와 서비스를 알아봤는데, 이번에는 Cairngorm의 커맨드와 일치하는 부분을 살펴 보겠다.

커맨드와 컨트롤러

Cairngorm의 커맨드들은 ICommand 인터페이스를 구현하는데, 이 인터페이스는 실행 메소드를 지정한다. 커맨드는 IResponder도 구현할 수 있는데, 이것은 결과와 폴트(실패) 메소드를 지정하고 서비스로부터 결과를 받거나 실패하는 경우에 호출되게 한다. 각각의 커맨드는 컨트롤러와 함께 등록되어, FrontController가 해당 작업을 해당 컨트롤러에 위임하게 한다(Service-to-Worker 패턴). [그림 19]는 모든 커맨드와 컨트롤러의 위치를 보여준다.


[그림 19] 커맨드와 컨트롤러의 위치

[표 11]과 [표 12]는 각각의 커맨드들이 무엇을 어떻게 하는지와 어떤 서비스들이 포함되어 있는지를 보여준다.

사용자 부분 커맨드 설명
FindAuthorsByNameCommand 실행시:
BookieDelegate.findAuthorsByName를 호출하며, 이 메소드는 이벤트 데이터로부터 BookieModel의 author 컬렉션을 채우기 위해 DataService를 사용함. 여기서 이벤트 데이터는 저자명을 찾는 검색 텍스트임.
FindBooksCommand 실행시:
이벤트 데이터를 사용하며, 이 데이터는 검색 타입과 검색 데이터를 지정하는 SearchEvent형식이어야 하고, 사용자가 입력한 검색어와 함께 사용되어야 함.

결과시:
반환된 책들로 BookieModel의 books 컬렉션을 설정.
FindSubjectsByNameCommand 실행시:
BookieDelegate.findSubjectsByName를 호출하며, 이 메소드는 이벤트 데이터로부터 BookieModel의 subject 컬렉션을 채우기 위해 DataService를 사용함. 여기서 이벤트 데이터는 제목에 대한 검색어임.
GetAllAuthorsCommand 실행시:
BookieDelegate.getAllAuthors를 호출하며, 이 메소드는 BookieModel의 author 컬렉션을 채우기 위해 DataService를 사용함.
GetAllSubjectsCommand 실행시:
BookieDelegate.getAllSubjects를 호출하며, 이 메소드는 BookieModel의 subject 컬렉션을 채우기 위해 DataService를 사용함.
ReserveBooksCommand 실행시:
이벤트 데이터(책과 사용자를 지정)로부터 예약에 대한 컬렉션을 생성. BookieDelegate.reserveBooks를 호출하며, 이 메소드는 예약을 생성하고 요청하기 위해 DataService를 사용함.
이러한 예약들은 관리 클라이언트에 보여지기 위해 자동으로 푸시되어야 함.
호출 후에 공지가 보여지고 나면 사용자는 예약이 끝난 후에는 더 이상 어플리케이션을 사용할 이유가 없기 때문에 로그아웃 한다고 가정.
SignInCommand 실행시:
BookieDelegate.findPersonByCardNumber를 호출하며, 이 메소드는 카드 번호에 해당하는 사용자를 찾기 위해 RemoteObject 서비스를 사용함.

결과시:
요청이 사용자를 반환하면 해당 사용자는 모델에 저장되고 로그인 화면이 사라짐. 메인 탐색 뷰로 화면의 뷰 상태를 바꾸기 위해 ViewLocator가 사용됨. 사용자가 발견되지 않으면 로그인 화면에 에러 메시지가 표시.
SignOutCommand 실행시:
초기화를 호출함으로써 모델이 지워지고, 모든 화면은 ViewLocators을 통해 찾아지고 지워짐. 메인 ViewLocator는 뷰 상태를 로그인 화면으로 반환.
[표 11] 사용자 부분 커맨드

관리자 부분 커맨드 설명
ClearReservationsReceivedCommand 실행시:
AdminModel의 outstandingReservations를 0으로 설정. 이것은 Admin 뷰의 컨트롤 바에서 보여줄 새 예약 수이며, 관리자가 잠시 자리를 비웠을때 들어온 새 예약수를 보여줌.
DeleteBookCommand 실행시:
데이터 서비스에서 서적을 삭제하는 AdminDelegate.deleteBook 메소드를 호출.
DeletePersonCommand 실행시:
데이터 서비스에서 사용자를 삭제하는 AdminDelegate.deletePerson 메소드를 호출.
DeleteReservationsCommand 실행시:
데이터 서비스에서 예약들을 삭제하는 AdminDelegate.deleteReservations 메소드를 호출.
DeleteSubjectCommand 실행시:
데이터 서비스에서 제목을 삭제하는 AdminDelegate.deleteSubject 메소드를 호출.
GetAllAuthorsCommand 실행시:
사용자 컬렉션을 채우기 위해 PersonAssembler를 사용하는 AdminDelegate.getAllAuthors 메소드를 호출. author 플래그가 true인 사용자로 제한됨.
GetAllBooksCommand 실행시:
모델의 서적 컬렉션을 채우는 AdminDelegate.getAllBooks 메소드를 호출.
GetAllReservationsAwaitingCheckOutCommand 실행시:
reservedOn이 null인 예약 컬렉션을 채우기 위해 데이터 서비스를 사용하는 AdminDelegate.getAllReservationsAwaitingCheckOut 메소드를 호출. 이것은 해당 컬렉션이 체크아웃 대기중임을 의미.
GetAllReservationsCheckedOutCommand 실행시:
reservedOn이 날짜로 되어 있는 예약 컬렉션을 채우기 위해 데이터 서비스를 사용하는 AdminDelegate.getAllReservations CheckedOut 메소드를 호출. 이것은 이 예약들이 벌써 체크아웃 되었음을 의미.
GetAllSubjectsCommand 실행시:
모델의 주제 컬렉션을 채우는 AdminDelegate.getAllSubjects 메소드를 호출
GetAllUsersCommand 실행시:
검색된 사용자로 사용자 컬렉션을 채우기 위해 PersonAssembler를 사용하는 AdminDelegate.getAllUsers를 호출
ReservationNotificationSubscribeCommand 실행시:
ServiceLocator로부터 새 예약이 요청될 때 JMS로부터 메시지를 받는 consumer로의 레퍼런스를 얻어옴. NotificationListener의 reservationConsumer 속성을 설정하는데, 이것은 이런 종류의 메시지에 대한 리스너로서 등록됨.
NotificationListener에 대해서는 뒤에서 더 자세히 말하겠지만, 새 예약이 요청될 때 알림창을 띄울 책임이 있음.
ReservationReceivedCommand 실행시:
NotificationListener가 ViewLocator를 사용하여 예약 알림 메시지를 띄우게 하고, 모델의 새 예약 수를 증가시킴. 이것은 관리자 뷰의 컨트롤 바에서 보여야 함.
[표 12] 관리자 부분 커맨드

bookie 위임자에서 앞서 봤던 메소드들을 호출하는 커맨드를 살펴보자. 제일 먼저 볼 것은 사용자를 시스템에 등록하는 커맨드인 SignInCommand이다.

SignInCommand는 ICommand와 IResponder 둘 다 구현하는 것을 눈여겨 보라. 이것은 이 커맨드가 서비스를 비동기적으로 호출하고 서비스가 끝났을 때 그 결과나 실패에 대한 콜백을 받는다는 것을 의미한다. 비동기적이라는 것은 단순히 Flash Player가 Java를 호출하고 계속해서 실행되기 전에 그것이 끝날때까지 기다릴 방법이 없다는 것을 뜻한다. 실제로 그러길 원하지도 않는다. Flash는 다중 스레드를 가지지 않기 때문에, Flash Player 내에서의 모든 실행은 Java가 응답을 돌려줄 때까지 멈춰있을 것이다. 원격 서비스 상의 메소드를 호출할 때는 항상 "콜백"을 지정하거나 그것이 끝났을때 호출할 메소드를 지정한다. Flash Player는 그 순서를 유지하지만, 일단 서비스 레이어에 호출을 하고나면 호출을 한 시점에서부터 실행이 계속되고 호출을 한 메소드는 종료된다. 이 경우 콜백은 IResponder 인터페이스에 의해 지정된 결과 메소드와 폴트 메소드들이다.

다음은 SignInCommand내의 구현이다.

result 메소드는 result 객체를 가지고 콜백된다. result 객체에는 콜백으로 오는 데이터를 담고 있는 result라는 속성이 있다. Java에서 위임자를 통하여 BookSearchService로, 심지어는 DAO까지로 돌아가는 모든 방법을 살펴보면, 이 호출이 Person객체를 반환하는 것을 볼텐데, 이 객체는 카드 번호와 일치하는 사용자여야 한다.만약 해당 객체가 null이 아니면 카드번호와 일치하는 사용자를 찾은 것이기 때문에 해당 사용자를 결제시키면 된다(훗, 꽤나 안전하구만?). 로그인 프로세스가 어떻게 작동하는지 좀 더 자세하게 볼텐데, 이것은 단지 실행 중에 온 서비스 호출이 반환되었을때 커맨드가 결과를 콜백받는 것을 보여주기 위한 것이다. 폴트 메소드는 뭔가 문제가 있다는 간단한 얼럿을 띄우기만 한다. 그러나 물론 필요하면 이 부분은 더 복잡하게 될 수 있다.

데이터 서비스를 호출하는 커맨드인 GetAllSubjectsCommand를 살펴보자:

GetAllSubjectsCommand는 ICommand만을 구현한다. 그렇기 때문에 이 커맨드는 실행이 끝난뒤 서비스에 의해 콜백을 받을 수 없다. 실행이 얼마나 단순한지도 살펴보자. 모델에서 제목 컬렉션에 대한 참조만 얻어서 위임자에게 전달하기만 하면 되는데, 해당 컬렉션에 들어 있는 것을 호출한다고 기억하면 된다.

Command 패턴은 개별적인 기능 모음들에 대한 실행을 모듈화하고 재사용할 수 있게 만드는 멋진 방법이다. 모든 제목을 얻기 위해 필요한 어떤 코드에서도 해당 커맨드를 호출하는 것 외에 다른 어떤 것도 알 필요가 없으며, 해당 커맨드는 어플리케이션의 어느 곳에서라도 호출될 수 있다. 컬렉션에 넣을 모든 제목들을 얻는 프로세스가, 알 필요가 있는 커맨드를 시작하는 어떤 코드도 바꾸지 않는다면, 그렇기 때문에 그것들은 변경으로부터 분리된다.

다음 번에는 Cairngorm 모델 위치자(locator)에 대해 살펴보고, 모델의 상태에 기반한 뷰를 쉽게 설정할 수 있는 강력한 Flex의 바인딩을 사용하는 법을 알아보겠다. 전체 연재는 언제라도 여기에서 볼 수 있다.
TAG :
댓글 입력
자료실

최근 본 상품0