스프링 계층 구조, business 로직 분리



Spring의 layered architecture와 비즈니스 로직 분리


먼저, Layered Architecture가 뭔지 자세히 보도록 하겠다.

계층 구조란?

가장 잘 알려진 아키텍처 패턴은 계층 구조 패턴으로, n-계층 아키텍처 패턴으로도 알려져 있다. 이 패턴은 거의 모든 Java EE 애플리케이션의 표준이어서 거의 모든 설계자, 디자이너, 그리고 개발자에게 많이 알려져 있다. 계층 구조 패턴은 전통적인 IT communication와 대부분의 회사에서 발견되는 구조를 접목함으로써, 기업 애플리케이션 개발을 하는데 가장 일반적으로 많이 사용이 된다.

더 자세히

계층 구조 패턴의 구성요소들은 수평적인 레이어를 구성하며, 각 레이어는 애플리케이션에서 특별한 역할을 수행한다(presentation logic이나 business logic). 계층 구조 패턴이 이 패턴에서 꼭 존재해야 하는 레이어의 수와 타입을 정의하진 않지만, 대부분의 계층 구조는 4개의 표준 레이어를 가지고 있다.

바로

  1. presentaion
  2. business
  3. persistence
  4. database

레이어이다.

image

어떤 케이스에서는, 비즈니스 레이어와 영속 레이어(임의로 persistence layer를 영속 레이어라고 하겠다. 정확한 표현을 모르겠음)를 하나의 비즈니스 레이어로 합치기도 하는데, 영속 로직(SQL/HSQL)이 비즈 니스 레이어 구성 요소 간에 임베딩 됐을 때다. 그래서 작은 애플리케이션들은 단지 세 개의 레이어를 가지지만, 크고 복잡한 기업 애플리케이션에서는 5개 혹은 더 많은 레이어를 가질 수 있다.

계층 구조 패턴의 각 레이어들은 주어진 역할과 책임이 있다. 예를 들어, 프레젠테이션 레이어에서는 모든 유저 인터페이스와 브라우저 커뮤니케이션 로직을 다뤄야 하며 비즈니스 레이어는 request와 관련 있는 특정 비즈니스 rule을 실행해야 한다. 아키텍처의 각 레이어는 특정 비즈니스 request를 충족시키기 위해 처리되어야 하는 작업에 대한 추상화를 제공한다.(원문에서는 형성한다고 되어 있는데 레이어들이 모여서 이를 이룬다고 생각하면 되겠다.) 예를 들어, 프레젠테이션 레이어는 고객 데이터를 어떻게 가져오는지 알 필요가 없고, 정보를 특정 포맷에 맞게 스크린에 출력하는 작업만 하면 된다. 비슷하게, 비즈니스 레이어는 고객 데이터가 스크린에 출력되는 것이나 데이터가 어디서 오는 것인지 알 필요가 없고, 영속 레이어에서 데이터를 받고, 비즈니스 로직을 수행(값을 계산하거나 데이터를 취합하는것)하는 작업을 해서 프레젠테이션 레이어로 정보를 전달하기만 하면 된다.

계층 구조의 큰 장점 중 하나는 component 사이의 걱정을 분리시키는 것이다.(앞에서 말한 것처럼 레이어들은 다른 레이어에서 일어나는 작업에 대해 걱정할 필요가 없다. 책임이 분리되어 있는 것이다.) 특정 레이어에 있는 컴포넌트는 오직 그 레이어에 종속된 로직만 수행한다. 예를 들어, 프레젠테이션 레이어에 있는 컴포넌트들은 오직 프레젠테이션 로직만 처리하면 되고, 비즈니스 레이어에 있는 컴포넌트들은 비즈니스 로직만 수행하면 되는 것이다. 이런 컴포넌트 분류는 아키텍처에서 효과적인 역할과 책임 모델을 만드는 것을 쉽게 하고, 잘 정의된 컴포넌트 인터페이스와 제한된 컴포넌트 범위 덕분에 개발, 테스트, 운영, 유지를 쉽게 한다.

핵심 개념

image

위 그림에서 아키텍처에 있는 레이어들이 closed 로 표시되어 있는 것을 볼 수 있다. 이것은 계층 구조 패턴에서 정말 중요한 개념이다. 닫힌 레이어는 request가 레이어에서 다른 레이어로 이동할 때, 바로 빝에 있는 레이어보다 더 밑에 있는 레이어에 가기 위해서는 꼭 바로 밑에 있는 레이어를 통과해야 한다는 의미이다. 예를 들어서, presentation layer에서 들어온 request는 무조건 데이터베이스 레이어에 도착하기 전에 business layer를 통과하고 영속 레이어를 지나가야 한다.

그러면 왜 프레젠테이션 레이어는 영속 레이어나 데이터베이스 레이어로 바로 연결하는 것을 허용하지 않을까? 프레젠테이션 레이어에서 직접 데이터베이스에 접근하는 것은 많은 불필요한 레이어가 데이터베이스 정보를 가져오거나 저장하는 것보다 빠르지 않나? 이것에 대한 답은 레이어의 고립이라는 핵심 개념에 있다.

레이어의 고립 개념은 아키텍처의 한 레이어에서 만들어진 변화는 다른 레이어의 컴포넌트들에 영향을 주지 말아야 한다는 뜻이다. 이러면 변화는 해당 레이어에 속한 컴포넌트들이나, 관련된 레이어에 한정될 것이다. 만약 프레젠테이션 레이어가 영속 레이어에 직접 접근할 수 있게 했다면, 영속 레이어의 SQL에서 만들어진 변화는 비즈니스 레이어와 프레젠 테이션 레이어 모두에 영향을 주면서, 컴포넌트 사이에 굉장히 많은 의존과 함께 결합도를 높일 것이다. 이런 타입의 아키텍쳐는 굉장히 수정하는 작업을 어렵게 만든다.

레이어의 고립 개념은 각 레이어가 독립적이어서, 아키텍처에 있는 다른 레이어들의 내부 동작을 아예 알지 못하거나 조금 하는 것을 의미한다. 이 개념의 중요성을 이해하기 위해, JSP(Java Server Pages)의 프레젠테이션 프레임워크를 JSF(Java Server Faces)로 바꾸는 큰 규모의 리팩토링을 수행한다고 생각해보자. 프레젠테이션 레이어와 비즈니스 레이어 사이의 계약(model)이 변하지 않는다고 가정하면, 비즈니스 레이어는 리팩토링에 영향을 받지 않을 것이고 프레젠테이션에 의해 사용되는 유저 인터페이스 프레임 워크의 타입에 완전히 독립적으로 남을 수 있다. 이게 말이 조금 복잡해서 그렇지, 간단하게 다시 정리하면 프레젠테이션 레이어와 비즈니스 레이어가 서로 주고 받는 무언가가 형식이 변하지 않는다고 가정하면 프레젠테이션 레이어가 아무리 변해도 비즈니스 레이어에는 영향이 없을 것이라는 뜻이다.

닫힌 레이어들이 레이어들의 고립을 용이하게 해서 아키텍처에서 일어나는 변화를 고립시키는 것을 도와주기도 하지만, 특정 레이어는 open되는 것이 더 합리적일 때도 있다. 예를 들어, 만약 공유되는 서비스 레이어를 비즈니스 레이어의 컴포넌트에서 접근되어 지는 서비스 컴포넌트들을 포함하는 아키텍처에 추가하는 것을 원한다고 가정해보자. 이 경우에는 서비스 레이어르 생성하는 것이 좋은 방법인데, 왜냐하면 구조적으로 공유되는 서비스가 비즈니스 레이어에 접근하는 것을 막기 때문이다. 분리된 레이어 없이는 프레젠테이션 레이어가 이런 공유되는 서비스에 접근하는 것을 구조적으로 막을 수 없으며, 이런 접근을 제어하는 것을 어렵게 만든다.

이 예시에서는, 새로운 서비스 레이어는 서비스 레이어에 있는 컴포넌트들이 프레젠테이션 레이어에서 접근이 불가능하다는 것을 명시하기 위해 비즈니스 레이어 밑에 위치할 확률이 높다.

ddddd

출처

https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch01.html