Toby 스프링3 1부 9장-2
15 Sep 2017 | 스프링 spring 아키텍처 데이터중심 아키텍처 오브젝트 중심 아키텍처9.3 애플리케이션 아키텍처
9.3.1 계층형 아키텍처
아키텍처와 SoC
3계층 아키텍처와 수직 계층
-
데이터 액세스 계층 : 수직적 계층 구조, DAO 계층, 장기적인 데이터 저장을 목적으로 하는 DB 이용이 주된 책임이다. 또 외부 시스템을 호출해서 서비스에 이용하는 기반계층으로 따로 분류하기도 한다.
-
서비스 계층: POJO, 엔터프라이즈 애플리케이션에서 가장 중요한 자산은 도메인의 핵심 비즈니스 로직이 들어 있는 서비스 계층이어야 한다.
-
프리젠테이션 계층: 엔터프라이즈 애플리케이션의 프레젠테이션 계층은 클라이언트의 종류와 상관없이 HTTP 프로토콜을 사용하는 서블릿이 바탕이 된다.
계층형 아키텍처 설계의 원칙
9.3.2 애플리케이션 정보 아키텍처
화면을 중심으로 하는 업무 트랜잭션단위로 코드가 모이기 때문에 최초 개발하기 편하다.
=> 내가 보아온 SI 프로젝트 대부분이 위와 같이 구성 되어 있었다.
다른 개발자의 간섭없이 독립적인 개발이 가능하다.
계층간 결합도가 높고 응집력이 떨어지며, 중복 코드가 발생하기 쉽고 장기적으로 코드 관리하고 발전 시키기 어렵다.
DB/SQL 중심의 로직 구현 방식
비즈니스 로직이 SQL이나 저장 프로시저에 있다
장점
코드 생성기나 툴을 사용하여 자동화하기 유리하다
단점
DB 확장에는 한계가 있으며 고비용이 발생 한다.
테스트가 어렵다
중복제거가 쉽지 않다
변화에 취약 하다
거대한 서비스 계층 방식
비즈니스 로직이 서비스 계층에 있다.
장점
DAO와 SQL은 상대적으로 단순해지고, 그중 일부는 여러 서비스 계층 코드에서 재사용이 가능해 진다.
테스트가 DB 방식보다 수월해 진다.
단점
업무 트랜잭션 단위로 서비스 계층의 만들어질 가능성이 높다
본격적인 객체지향 설계는 어렵다
개발 능력이 떨어지는 경우 자바 코드로 구현한 비즈니스 로직이 복잡한 SQL보다 더 이해하기 힘들 수도 있다.
9.3.3 오브젝트 중심 아키텍처
도메인 모델을 반영하는 오브젝트 구조를 만들어두고 그것을 각 계층 사이에서 정보를 전송하는 데 사용한다.
오브젝트 중심 아키텍터는 객체지향 분석과 모델링의 결과로 나오는 도메인 모델을 오브젝트 모델을 활용한다.
코드는 이해하기 쉽고 로직을 작성하기 쉽다.
프레젠테이션 영역에서도 이미 정의된 도메인 오브젝트 구조만 알고 있다면 아직 DAO가 작성되지 않았어도 뷰를 미리 만들어 볼수도 있다.
코드의 재사용성이 높아지고 DAO는 더 작고 효율적으로 만들질 수 있다.
데이터와 오브젝트
도메인 오브젝트를 사용하는 코드
도메인 오브젝트 사용의 문제점
- 최적화된 SQL을 매번 만들어 사용하는 경우에 비해 성능 면에서 조금은 손해를 감수해야 할 수도 있다. 비즈니스 로직 마다 필요한 정보가 달라질 수 있기 때문에 발생하는 문제이다.
- 오브젝트 관계 문제 : 필요하지 않는 관계된 걕체의 정보까지고 가져올 수 있다. 최적화를 고려해서 DAO를 작성하려면 DAO는 비즈니스 로직에서 각 오브젝트를 어디까지 사용해야 하는지 어느 정도 알고 있어야 한다. 프리젠테이션 계층도 마찬가지이다.
- 오브젝트 관계 문제의 해결 :
- 지연 로딩기법을 이용하면 일단 최소한의 오브젝트 정보만 읽어두고 관계하고 있는 오브젝트가 필요할 경우에만 다이내믹하게 DB에서 다시 읽어들인다.
- 가장 이상 적인 방법은 ORM기술 을 사용하는 것이다.
빈약한 도메인 오브젝트 방식
도메인 오브젝트에는 정보만 담겨 있고, 정보를 활용하는 아무런 기능도 갖고 있지 않다. 비즈니스 로직은 서비스 계층에 존재 한다.
문제점 : 거대 서비스 계층 방식과 유사하다. 데이터 방식보다는 유연하고 간결하지만, 서비스 계층의 메소드에 대부분의 비즈니스 로직이 득어 있기 때문에 로직의 재사용 성이 떨어지고 중복이 발생하기 쉽다.
풍성한 도메인 오브젝트 방식
비즈니스 로직이 특정 도메인 오브젝트와 관계가 깊다면 이 로직을 서비스 계층이 아닌 도메인 오브젝트에 넣어주고, 서비스 계층의 비즈니스 로직에서 재사용 하도록 만든다.
도메인 오브젝트는 직접 데이터 액세스 계층이나 기반 계층 또는 다른 서비스 계층의 오브젝트에 접근 할 수 없기 때문에 서비스 계층이 필요하다. (데이터 계층이나 서비스 계층은 스프링 빈으로 관리되기 때문이다. 해당 객체에 접근하려면 도메인 오브젝트도 스프링 빈으로 등록되어야 한다.)
도메인 오브젝트는 애플리케이션의 코드 또는 기타 프레임워크나 라이브러리, JDBC템플릿 등에 의해 필요할 때마다 새롭게 만들어 진다.
스프링의 빈으로 관리되는 3계층의 오브젝트들은 도메인 오브젝트를 자유롭게 이용할 수 있지만 그 반대는 안된다.
빈약한 도메인 오브젝트를 피하고 도메인 오브젝트가 스스로 처리 가능한 기능과 도메인 비즈니스 로직을 갖도록 만드는 것이 바람직하다.
장점
- 빈약한 도메인 오브젝트 방식보다 서비스 계층의 코드가 간결하다.
- 비즈니스 로직 코드를 이해하기도 쉽다.
도메인 계층 방식
풍성한 도메인 오브젝트 안의 비즈니스 로직은 데이터액세스 계층에 접근 할 수 없으므로 서비스계층의 오브젝트의 부가적인 작업이 필요 하다.
도메인 오브젝트들이 하나의 독립적인 계층을 이뤄서 서비스 계층과 데이터 액세스 계층의 사이에 존재하게 하는 것이다.
- 도메인 계층으로 들어가면 서비스계층의 도움 없이도 비즈니스 로직의 대부분의 작업을 수행 할 수 있다.
- 도메인의 오브젝트가 기존 데이터 액세스 계층이나 기반 계층의 기능을 직접 활용할 수 있다.
스프링이 관리하지 않는 도메인 오브젝트에 DI를 적용하기 위해서는 AOP가 필요하다.
AspectJ AOP를 사용하면 클래스 생성자가 호출되면서 오브젝트가 생성되는 시점에 조인 포인트로 사용할 수 있고 스프링 빈이 아닌 일반 오브젝트도 AOP 부가기능을 적용할 수 있다. 오브젝트의 수정자나 DI용 애노테이션을 참고해서 DI 가능한 대상을 스프링 컨테이너에서 찾아 DI해주는 기능을 추가한다. 도메인 오브젝트에 스프링의 빈 오브젝트를 DI받아 사용 할수 있도록 만든다.
서비스 계층의 역할
- 서비스계층에서는 여러 오브젝트를 조합해서 사용하는 복잡한 작업을 하는 경우 사용 한다.
- 데이터 액세스 계층에서 클라이언트로 정보를 제공할 때 인터페이스 역할을 한다.
- 트랜잭션 경계를 설정하거나 특정 도메인 로직에 포함되지는 않지만 애플리케이션에서 필요로 하는 기반 서비스를 이용해야 하는 작업을 위해서도 필요하다.
도메인 계층의 고려 사항
- 프리젠테이션 영역에서 도메인 객체를 사용하게 되면 문제가 발생할 수 있다.
- 도메인 객체를 모든 계층에서 사용하게 하지만 개발가이드를 특정 메소드 말고는 접근을 막는 것이다. 이때 AspectJ를 활용한다.
- 도메인 객체는 도메인 계층을 벗어나지 못하게 한다. 도메인 계층 밖으로 전달될 때는 별도로 준비된 정보 전달용 오브젝트(DTO)에 도메인 오브젝트의 내용을 복사하여 넘겨 준다.
도메인 계층 방식을 사용 할 때는 매우 복잡하고 변경이 잦은 도메인을 갖을 때 사용 한다.
DTO와 리포트 쿼리
리포트 쿼리 : 여러 테이블에 걸쳐 존재하는 자료를 분석하고 그에 따른 분석/통계 결과를 생성하는 쿼리
DB쿼리 결과를 담을 적절한 도메인 오브젝트가 없을 경우 DTO라고 불리는 단순한 자바 빈이나 맵에 담아 전달 해야 한다.
9.3.4 스프링 애필리케이션을 위한 아키텍처 설계
계층형 아키텍처
처음 학습 할때는 3계층 구조로 프레젠테이션 계층은 SpringMVC를 이용하고 서비스 계층은 POJO로 구현하면서 트랜잭션 AOP를 적용하고, 데이터 액세스 계층은 JDBC를 비롯해서 스프링의 데이터 액세스 전략이 적용된 JPA, 하이버네이트, JDO 등을 활용하는 것이 좋다. 코드가 익숙해지면 다양한 방식으로 계층구조를 통합과 분산을 시도해 보자.
정보 전송 아키텍처
빈약한 도메인 오브젝트 방식으로 시작해 보는게 가장 쉽다. 도메인 오브젝트를 계층 간의 정보 전송을 위해서 사용하고, 이를 각 계층의 코드에서 활용한다.
DAO는 그 기술이 어떤 것이든 상관없이 서비스 계층에서 요청을 받거나 결과를 돌려줄 때 도메인 오브젝트 형태를 유지하게 만든다.
서비스 계층의 비즈니스 로직 또한 도메인 오브젝트를 이용해서 작성한다. 가능하다면 도메인 오브젝트에 단순한 기능이라도 추가하도록 노력해보는 것이 좋다.
프레젠테이션 계층의 MVC아키텍처 에서도 모델은 도메인 오브젝트를 그대로 사용 한다. 뷰에 전달하는 정보도 물론 도메인 오브젝트를 사용하는 모델이고, 사용자가 입력하는 폼의 정보도 도메인 오브젝트로 변환해서 사용한다.
상태 관리와 빈 스코프
스프링은 기본적으로 상태가 유지되지 않는 빈과 오브젝트를 사용하는 것을 권장한다. 웹의 생리에 가장 잘 맞고 개발하기 쉽기 때문이다. 또, 서버를 여러 대로 확장하기가 매우 쉽다. 반면에 웹 클라이언트에 폼 정보를 출력하고 이를 수정하는 등의 작업을 위해서는 HTTP세션을 적극 활용하기도 한다. 대부분의 폼 등록, 수정 작업은 한페이지짜리 폼이라도 여러 번의 HTTP 요청에 걸쳐 일어나기 때문에 작업 중인 폼의 내용을 짧은 동안에라도 서버에 저장해둘 필요가 있다.
스프링에서는 싱글톤 외에도 다른 스코프를 갖는 빈을 간단히 만들 수 있다. 빈의 스코프를 잘 활용하면 스프링이 관리하는 빈이면서 사용자별로 또는 단위 작업별로 독립적으로 생성되고 유지되는 오브젝트를 만들어 상태를 저자하고 이를 DI를 통해 서비스 빈에서 사용하게 만들 수 있다.
서드파티 프레임워크, 라이브러리 적용
스프링이 지원하는 기술이란 ?
- 첫째, 해당 기술을 스프링의 DI 패턴을 따라 사용할 수 있다.
- 둘째, 스프링의 서비스 추상화가 적용됐다.
- 셋째, 스프링이 지지하는 프로그래밍 모델을 적용했다.
- 넷째, 템플릿/콜백이 지원된다.
9.4 정리
- 스프링은 어떤 플랫폼에서도 사용될 수 있지만, 기본적으로 자바 엔터프라이즈 플랫폼(JavaEE)에 최적화되어 있다. HTTP를 통해 접근하는 웹 클라이언트와 백엔드 DB를 사용하는 애플리케이션에 적합하다.
- 스프링 개발의 생산성을 증대시키고 품질을 높이려면 SpringIDE 플러그인이나 STS 같은 적절할 툴의 지원이 필요하다.
- 스프링의 의존 라이브러리가 방대하기 때문에 라이브러리 관리와 의존관계를 관리하는 데 많은 노력을 기울여야 한다. 가능하면 스프링이 의존관계 정보를 제공해주는 Maven이나 Ivy같은 빌드 툴을 사용해 의존 라이브러리를 관리하는 것이 바람직하다.
- 스프링 애플리케이션은 역할에 따라 3계층으로 구분되고, 다시 기술의 추상화에 따라 세분할 수 있다.
- 스프링에 가장 잘 어울리는 아키텍처는 오브젝트 중심의 아키텍처이다.
- 스프링이 직접 지원하지 않는 서드파티 기술도 스프링의 스타일의 접근 방식을 따라서 사용할 수 있도록 준비해둬야 한다.
Comments