IBM Korea Skip to main content
       IBM 홈    |  제품 & 서비스  |  고객지원 & 다운로드  |  회원가입  

EJB best practices : Business Delegate 패턴
EJB 디자인에서의 추상 비지니스, 구현, 애플리케이션 로직

Level: Intermediate

Brett McLaughlin
작가/편집자, O'Reilly and Associates
2002년 10월

Column icon애플리케이션 플래닝에 있어서 가장 복잡한 문제 중 하나는 비즈니스와 구현 티어(tier) 사이를 반드시 분리해야 한다는 점이다. Business Delegate 패턴은 애플리케이션의 유지보수와 업그레이드를 어렵게 만드는 커플링(coupling)을 방지한다.

처음부터 이 시리즈를 따라왔던 독자라면 애플리케이션과 구현 로직을 비지니스 로직에서 분리하는 문제가 계속 재기되고 있다는 것을 감지했을 것이다. 예를 들어, 첫 번째는 빈의 구현을 인터페이스에서 분리할 때 원격 객체 디자인의 어려움에 초첨을 맞췄다. 그 문제는 비지니스 인터페이스 패턴(Business Interface pattern)으로 해결했다. 마지막 글에서는 빈속에 포함된 데이터에 사용자들이 액세스 할 수 있도록 하면서 동시에 엔터티 빈이 애플리케이션 레이어에 직접 노출되는 것으로부터 보호해야 할 필요성에 대한 논쟁을 다뤘다.

두 경우 모두, 핵심 문제는 비지니스 로직 구현을 그 로직을 사용하는 코드에서 추출함으로서 해결되었다. 이러한 종류의 추상화(abstraction)는 좋은 애플리케이션 디자인의 기본이다. 특히 EJB 기반 애플리케이션 디자인에 있어서는 특히 그렇다. 여기에서 다시한번 비지니스 인터페이스 패턴과 세션 빈을 이용하여 웹 티어를 Enterprise JavaBeans 컴포넌트에 약결합 하는 방법을 다루겠다.

비지니스 인터페이스 패턴(Business Interface pattern)
비지니스 인터페이스 패턴(Business Interface pattern)을 구현하여 세션 빈과 인터랙팅하는 비지니스 스팩의 인터페이스를 제공할 수 있었다. Listing 1은 그 인터페이스이다:

Listing 1. 라이브러리 비지니스 인터페이스(Library business interface)

package com.ibm.library;

import com.ibm.library.exceptions.NoSuchBookException;

import java.rmi.RemoteException;
import java.util.List;

public interface ILibrary {

      public List getBooks() throws RemoteException;
      public List getBooks(String category) throws RemoteException;

      public Book getBook(String isbn)
          throws NoSuchBookException, RemoteException;

      public boolean checkout(Book book) throws RemoteException;
      public boolean checkout(List books) throws RemoteException;

      // And so on...
}

라이브러리 인터페이스(Library interface)는 어떤 EJB 구조(semantics)도 포함되지 않았다는 것을 주목해라. 대신 모든 구현과 EJB 세부사항들은 인터페이스를 구현한 세션 빈에서 핸들된다. 이제, 엔터프라이즈 애플리케이션의 웹 티어가 라이브러리 인터페이스와 세션 빈에 액세스하는 방법을 보자:

Listing 2. 라이브러리 인터페이스 사용하기

LibraryHome libraryHome =
     (LibraryHome)EJBHomeFactory.getInstance().
	    lookup("java:comp/env/ejb/LibraryHome",
                 LibraryHome.class);
ILibrary library = libraryHome.create();

Listing 2는 우리에게 익숙한 또 다른 클래스를 사용한다. EJBHomeFactory 클래스는 Library 빈용 홈 인터페이스를 찾아서 비지니스와 애플리케이션 로직을 분리한다. Library 인터페이스 구현은 홈 인터페이스에서 얻어질 수 있다.

위 코드는 나쁘지 않다. 이것은 분명 JNDI 초기 콘텍스트를 로딩하는 것보다 발전한 것으로서 홈 인터페이스를 수동으로 얻고 엔터티 빈을 직접 다룬다. 하지만 여기에는 근본적인 약점도 있다. 웹 티어는 여전히 EJB 컴포넌트에 묶여있고 특별히 Library 세션빈이 그렇다. 엔터티 빈을 단계적으로 정지시키고 Java Data Objects를 사용하거나 새로운 EJB 스팩을 만든다면 애플리케이션 코드에 어떤 일이 발생할까? 어쩔 수 없이 깔끔하게 분리된 시스템 아키텍쳐가 필요하다면? 강결합 코드를 작성하는 것이 단기 실행에서 더욱 쉽지만 그렇게 함으로서 애플리케이션의 수명은 감소한다. 바로 이 부분에서 Business Delegate 패턴이 적용될 수 있다.

중개자: Business Delegate 패턴
Business Delegate 패턴은 Business Interface 패턴과는 다르다. Business Interface 패턴은 사용 가능한 비지니스 로직을 정의하는 반면, Business Delegate는 구현 기술에 의존하지 않고 로직에 액세스를 제공한다. 특히 business delegate는 EJB 컨테이너로의 연결 세부사항을 핸들하는 헬퍼 클래스이다, 모든 필요한 리소스를 얻어 필요할 때 제공한다. Listing 3은 시작부분에서 Listing 1Library 인터페이스를 사용한다. 하지만 새로운 LibraryDelegate 클래스와 메소드가 도입되었다는 것을 주목하라.

Listing 3. Library 빈을 위한 business delegate

package com.ibm.library;

import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.naming.NamingException;

public class LibraryDelegate implements ILibrary {

      private ILibrary library;

      public LibraryDelegate() {
          init();
      }

      public void init() {
          // Look up and obtain our session bean
          try {
              LibraryHome libraryHome =
                  (LibraryHome)EJBHomeFactory.getInstance().lookup(
                      "java:comp/env/ejb/LibraryHome", LibraryHome.class);
              library = libraryHome.create();
          } catch (NamingException e) {
              throw new RuntimeException(e);
          } catch (CreateException e) {
              throw new RuntimeException(e);
          } catch (RemoteException e) {
              throw new RuntimeException(e);
          }
      }

      public List getBooks() throws ApplicationException {
          try {
              return library.getBooks();
          } catch (RemoteException e) {
              throw new ApplicationException(e);
          }
      }

      public List getBooks(String category) throws ApplicationException {
          try {
              return library.getBooks(category);
          } catch (RemoteException e) {
              throw new ApplicationException(e);
          }
      }

      public Book getBook(String isbn)
          throws NoSuchBookException, ApplicationException {

          try {
              return library.getBook(isbn);
          } catch (RemoteException e) {
              throw new ApplicationException(e);
          }
      }

      public boolean checkout(Book book) throws ApplicationException {
          try {
              return library.checkout(book);
          } catch (RemoteException e) {
              throw new ApplicationException(e);
          }
      }

      public boolean checkout(List books) throws ApplicationException {
          try {
              return library.checkout(books);
          } catch (RemoteException e) {
              throw new ApplicationException(e);
          }
      }

      // And so on...

      public void destroy() {
          // In this case, do nothing
      }
}

LibraryDelegate 클래스에서, 각각의 메소드는 세션 빈으로 작동요청을 전달함으로서 응답한다. init() 메소드는 초기화와 리소스 모음을 핸들한다. LibraryDelegate가 전체 애플리케이션이 작동하는 방식에 영향을 끼친다. 명료성을 이룩하기 위함이다. Listing 2와 아래의 코드의 차이점을 생각해보자:


ILibrary library = new LibraryDelegate();

LibraryDelegate을 도입함으로서 애플리케이션의 웹 티어에게서 모든 기술 의존성을 제거했다. 결과가 명료하고 안정된 애플리케이션 코드는 물론 애플리케이션 변화가 부드럽게 이루어졌다. 예를 들어, EJB 기술에서 순수한 JDBC 클래스로 마이그레이션을 원한다면 새로운 JDBC 클래스로 business delegate를 재작성할 수 있다. 웹 티어는 그 차이점을 모르고 재컴파일 할 필요도 없다.

참고자료

목 차:
비지니스 인터페이스 패턴(Business Interface pattern)
Business Delegate 패턴
참고 자료
필자 소개
기사에 대한 평가
관련 dW 링크:
EJB best practices series
Subscribe to the developerWorks newsletter
US 원문 읽기
Also in the Java zone:
Tutorials
Tools and products
Code and components
Articles
필자소개
authorBrett McLaughlin은 현재 자바 및 관련 기술을 이용하여 애플리케이션 기반구조 구현을 전문적으로 수행하고 있다. Brett은 Java Apache 프로젝트인 Turbine의 공동 창립자이다.
이 기사에 대하여 어떻게 생각하십니까?

정말 좋다 (5) 좋다 (4) 그저그렇다 (3) 수정보완이 필요하다(2) 형편없다 (1)

  회사소개  |  개인정보 보호정책  |  법률  |  문의