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

EJB best practices :delegation의 한계
business delegate의 대안

Level: Intermediate

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

Column iconbusiness delegate pattern은 EJB 추상화에 있어서 대중적인 솔루션이지만 한계도 있다. Brett McLaughlin은 그 한계를 이야기한다. 또한 이를 대체 할 방안도 검토될 것이다.

EJB best practices 시리즈에서는 business delegate pattern에 대해 자주 다루었다. 질리도록.. :) 이 글은 business delegate이 프로그래밍이 쓰일 수 없는 상황에 대한 글이다.

실제의 delegate
지금까지의 예제 애플리케이션에서, 비지니스 로직은 세션 빈에서 명확하게 정의되었고 business delegate의 메소드는 세션 빈의 메소드를 단순히 모방했다. 이러한 유형의 시나리오에서는, 빈의 비지니스 인터페이스와 business delegate은 강결합된다. 비지니스 인터페이스의 메소드들이 변할 때 business delegate의 메소드들 역시 변해야 한다. 이 디자인이 이론적으로는 작동에 문제가 없지만 실제 EJB 프로그래밍과는 거리가 멀다.

좀더 일반적인 시나리오는, 세션 빈이 단일 유닛의 비지니스 로직을 수행하도록 조합될 수 있는 사용가능한 메소드들의 모음을 포함하는 것이다. 각 세션 빈 메소드는 더 큰 트랜잭션의 일부를 제공한다. 클라이언트는 단일 오퍼레이션으로 보인다. 이 상황에서 business delegate pattern을 구현은 조금 부족한 방법이다.

EJB 기술의 이론과 실제
이론적으로 EJB 애플리케이션은 전적으로 컴포넌트 구동이고 실제로 코딩하기 전에 설계된다. 엔터티빈은 세션 퍼케이드(facade) 빈을 통해 언제나 액세스 되며 그러한 빈들은 추가 세션 빈들에 의해서 좀더 논리적인 비지니스 단위로 그룹핑된다. 이 시나리오에 따르면 클라이언트에게 노출되는 유일한 메소드는 purchaseBook()addUser() 같은 비지니스 구동의 메소드이다.

하지만 실제로 우리가 볼 수 있는 것은 스파게티 모양의 코딩일 것이다. 엔터티 빈은 처음부터 다시 설계되고 그런다음 세션 빈들이 엔터티 빈들의 상단에 놓인다. 종종 그 사이에 디자인이나 플래닝 시간이 있기는 하다. 엔터티 빈은 언제나 클라이언트에 노출되는 것은 아니며, 비지니스 로직은 여러 개의 메소드가 세션빈(예를 들어, getBookISBN(), reserveBook(), decreaseInventory(), makePurchase() 순으로)에 호출 될 것을 요청한다. 하나의 비지니스 스팩의 메소드를 호출하는 대신 클라이언트는 모든 서버 애플리케이션의 비지니스 로직을 모두 고쳐야한다.

business delegate이 작동하지 않을 때
이 경우 business delegate과 관련한 문제는, 이것이 위임은(delegate)하지만 실제로는 비지니스를 수행하지는 않는다는 점이다. delegate은 클라이언트가 세션 빈의 메소드에 액세스하도록 하지만 클라이언트는 여전히 그러한 메소드를 비지니스 유닛으로 어셈블링해야한다. 다양한 프로그래머들이 여러가지 방식으로 메소드를 어셈블하고 정렬하기 때문에 클라이언트는 다양한 방식으로 비지니스 프로세스를 실행할 것이다. 어떤 클라이언트는 중요한 단계를 생략하기도 하고 어떤 클라이언트는 프로세스 시간을 늘리는 새로운 단계를 추가할 수도 있다. 다중 클라이언트를 통해 일관성있는 애플리케이션 퍼포먼스를 보장하려면 당신의 애플리케이션의 비지니스 로직을 인터프리팅하는 짐을 덜어줘야한다.

우리에게 필요한 것은 business delegate처럼 보이면서 작동하지만 실제로는 클라이언트에게 비지니스 관점의 애플리케이션을 제공하는 클래스이다. 여기에서는 그러한 유형의 클래스를 command delegate 이라고 하겠다. 세션 빈으로 직접 액세스하는 대신에 command delegate은 여러 세션 빈 메소드로 위임되는 명령어(command)를 제공한다.

command delegate
command delegate이 business delegate 보다 나은 프로그래밍 솔루션이라는 것을 입증하는 시나리오를 검토해보자. Listing 1은 Inventory 빈용 비지니스 인터페이스이다. 온라인 오디오-비디오 매장 재고(Inventory)를 관리한다 :

Listing 1. Inventory 빈의 비지니스 인터페이스

package com.ibm.inventory;

import java.rmi.RemoteException;

public interface IInventory {

      public String getItemId(String productName)
	    throws RemoteException;

      public boolean reduceInventory(String itemId, int quantity)
	    throws RemoteException;

      public boolean increaseInventory(String itemId, int quantity)
	    throws RemoteException;

      // Overloaded version: reduce inventory by one
      public boolean reduceInventory(String itemId)
	    throws RemoteException;

	// Overloaded version: increase inventory by one
	public boolean increaseInventory(String itemId)
		throws RemoteException;
}

Listing 2는 구매 (purchasing) 빈에 대한 비지니스 인터페이스이다:

Listing 2. 구매자(Purchaser) 빈의 비지니스 인터페이스

package com.ibm.purchaser;

import java.rmi.RemoteException;

public interface IPurchaser {

      public boolean makePayment(PurchaseInfo purchaseInfo, float amount)
	    throws RemoteException;

      public boolean makeCredit(PurchaseInfo purchaseInfo, float amount)
	    throws RemoteException;
}

위 구매 시나리오는 여러 단계로 구성되어있다. 우선, 구매 아이템의 아이디가 검색된다. 그런다음 결제가 이루어진다. 마지막으로, 결제가 완료되면 구매 아이템에 대한 재고가 감소하게된다. business delegate pattern을 사용하여 이 시나리오를 핸들한다면 두 가지 business delegate 클래스가 필요하고 적어도 세 개의 메소드 호출이 필요하다.

command delegate 패턴을 선택하는 것도 좋은 방법이다. business delegate이 클라이언트에게 비지니스 로직의 개별 청크로의 액세스를 허용하는 반면 command delegate 클래스는 세션 빈을 통해서 작동하고 비지니스 로직을 한데 모으며 이를 클라이언트에게 실행 메소드로서 제공한다. (Listing 3):

Listing 3. PurchaserDelegate 클래스

package com.ibm.purchase;

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

import com.ibm.purchaser.*;
import com.ibm.inventory.*;

public class PurchaserDelegate {

      private IPurchaser purchaser;
	private IInventory inventory;

      public PurchaserDelegate() {
          init();
      }

      public void init() {
          // Look up and obtain our session beans
          try {
            PurchaserHome purchaserHome =
              (PurchaserHome)EJBHomeFactory.getInstance().lookup(
                "java:comp/env/ejb/PurchaserHome", PurchaserHome.class);
            purchaser = purchaserHome.create();

            InventoryHome inventoryHome =
              (InventoryHome)EJBHomeFactory.getInstance().lookup(
                "java:comp/env/ejb/InventoryHome", InventoryHome.class);
            inventory = inventoryHome.create();
          } catch (NamingException e) {
              throw new RuntimeException(e);
          } catch (CreateException e) {
              throw new RuntimeException(e);
          } catch (RemoteException e) {
              throw new RuntimeException(e);
          }
      }

	public boolean purchase(String itemName, float price, 
	PurchaseInfo purchaseInfo)
	    throws InsufficientFundsException, PurchaserException {

		try {
		    String itemID = inventory.getItemId(itemName);
			if (purchaser.makePurchase(purchaseInfo, price)) {
			    inventory.reduceInventory(itemID);
				return true;
			} else {
			    throw new InsufficientFundsException();
			}
		} catch (RemoteException e) {
		    throw new PurchaserException(e);
	    }
      }

      // Other business-specific methods

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

좀더 현실적인 예제에서는 물론 비지니스 로직은 더욱 복잡하다. 예를들어 클라이언트가 구매 아이템을 선적하는 문제를 다뤄야 한다면 쇼핑 카트는 한 번에 한 개 이상의 아이템을 갖고있어야 한다. 또는 아이템 디스카운트, 자동 재고 조사, 주문 프로세스등을 처리하는 기능이 있어야 한다. 두 개의 빈이 아닌 세개 또는 네개의 빈과 더욱 많은 메소드와 인터랙팅도 필요하다. 하지만 애플리케이션의 복잡성과 관계없이 command delegate pattern은 하나의 메소드 호출로 이들을 처리할 수 있다. command delegate pattern을 이용하면 비지니스와 EJB 티어의 복잡함이 애플리케이션 클라이언트로 옮겨가지 않는다. 그것은 분명 좋은 프로그래밍 기술이 아닐 수 없다.

다양한 EJB 디자인 패턴을 통해 소팅하고 어떤 것이 실제 시나리오에 적함한지를 구별하는 것은 다소 혼란스럽다. 새로운 패턴을 툴박스에 추가하고 다양한 상황에 맞춰 시도할 때 알맞은 솔루션을 찾아가게 될 것이다. command delegate pattern은 복잡한 비지니스 로직을 적용하는 애플리케이션에 적합하다.

참고자료

목 차:
실제의 delegate
business delegate이 작동하지 않을 때
command delegate
참고 자료
필자 소개
기사에 대한 평가
관련 dW 링크:
EJB best practices series
Enterprise JavaBeans fundamentals
Best practices in EJB exception handling
Subscribe to the developerWorks newsletter
US 원문 읽기
Also in the Java zone:
Tutorials
Tools and products
Code and components
Articles
필자소개
Photo of Brett McLaughlin Brett McLaughlin은 현재 자바 및 관련 기술을 이용하여 애플리케이션 기반구조 구현을 전문적으로 수행하고 있다. Brett은 Java Apache 프로젝트인 Turbine의 공동 창립자이다.
이 기사에 대하여 어떻게 생각하십니까?

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

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