본문 바로가기

Dev.../소프트웨어 아키텍처

[SA강좌] Part 4-9 Service Layer 패턴

서비스 레이어(Service Layer) 패턴

서비스 레이어 패턴의 정의

가능한 오퍼레이션의 집합을 만들고, 각 오퍼레이션에 있는 어플리케이션의 응답에 대응하는 서비스 레이어를 사용하여 어플리케이션의 경계를 정의하는 패턴이다.

그림 -12. 서비스 레이어 패턴의 구조

서비스 레이어 패턴의 설명

엔터프라이즈 어플리케이션은 전형적으로 데이터 저장과 로직 구현을 위한 다른 종류의 인터페이스를 요구한다. 인터페이스의 예는 데이터 로더, 사용자 인터페이스, 게이트웨이 통합 등등이다. 이들 인터페이스는 다른 목적을 가지고 있음에도 불구하고, 이들 인터페이스들은 자주 어플리케이션과의 상호작용을 필요하다.

서비스 레이어는 어플리케이션의 경계를 정의하고, 클라이언트 레이어와 인터페이스를 인식하는 이용 가능한 오퍼레인션들의 집합이다. 서비스 레이어는 어플리케이션의 비즈니스 로직, 프리젠테이션의 처리, 레이어의 오퍼레이션에 있는 응답 조정을 캡슐화한다.

  • 도메인 모델의 상위에 있는 추상화된 레이어
  • 어플리케이션은 도메인 모델에 직접 접근 대신에 단지 서비스 레이어를 사용
  • 예제 : 세션빈즈

장점

  • 도메인 모델 위에서 트랜잭션 스크립트와 같은 함수
  • 다양한 도메인 개체들을 연결함( : 아답트 클래스)
  • 다양한 도메인 개체들에서 공용 CRUD 코드를 공유
  • 원격 호출을 위해 설계됨

단점

  • 도메인 모델위에 레이어 추가가 복잡함
  • 서비스 구현 확장 – CRUD 부분에서 서비스 레이어 있는 함수 호출을 필요로

서비스 레이어 패턴은 언제 사용하는가?

서비스 레이어의 이점은 많은 종류의 클라이언트에서 이용이 가능한 어플리케이션의 오퍼레이션 공통 집합을 정의하고, 각 오퍼레이션을 어플리케이션 응답에 대응한다. 이러한 응답은 다중 트랜잭션의 자원들에 거처서 자동적으로 처리하는데 필요한 어플리케이션의 로직을 포함한다.

서비스 레이어 패턴의 예제:세금 인식

인식서비스 클래스의 메소드들은 오퍼레이션들의 어플리케이션 로직을 기술하고, 도메인 개체 클래스들을 대표한다. 아래는 도메인 로직을 위한 도메인 모델 패턴에서의 예제이다.

 

publuc class ApplicationService {

protected EmailGateway getEmailGateway() {

// return an intance of EmailGateway

}

proteceted IntegrationGateway getIntegrationGateway() {

// return an instance of IntegrationGateway

}

}

public interface EmailGateway {

void sendEmailMessage(String toAddress, String subject, String body);

}

public interface IntegrationGateway {

void publishRevenueRecogitionCalculation(Contract contract);

}

public class RecognitionService extends ApplicationService {

public void caculateRevenueRecognitions(long contractName) {

Contract contract = Contract.readForUpdate(contractNumber);

contract.caluateRecognitions();

getEmailGateway().sendEmailMessage(

contract.getAministrationEmailAddress(),

"RE:Contract #" + contractNumber,

contract + "has had revenue recognitions calculated.");

getIntegrationGateway().publishReveneueRecognition(contract);

}

public Money recognizedRevenue(long contractNumber, Date asOf) {

return Contract.read(contractNumber).recognizedRevenue(asOf);

}

}