BACKEND/SPRING

02. 개발에 앞서 알면 좋은 기초 지식 - 레이어드 아키텍처 및 디자인 패턴

우진하다 2023. 7. 22. 17:57

레이어드 아키텍처(Layered Architecture)

레이어드 아키텍처(Layered Architecture)는 소프트웨어 시스템을 여러 개의 레이어(layer)로 분리하여 구축하는 아키텍처 패턴입니다. 각 레이어는 특정한 역할과 책임을 갖고 있으며, 서로 상위 레이어에서 하위 레이어로만 직접적으로 의존합니다. 이러한 분리된 레이어들은 시스템의 구조를 유연하고 관리하기 쉽게 만들어줍니다.

즉, 애플리케이션의 컴포넌트를 유사 관심사 기준으로 레이어로 묶어 수평적으로 구성한 구조이며
어떻게 설계한냐에 따라 용어와 계층의 수가 달라집니다.

일반적인 레이어드 아키텍처

프레젠테이션 레이어(Presentation Layer)
사용자와 시스템 사이의 상호작용을 처리하는 레이어입니다.
사용자 인터페이스(UI)를 담당하며, 클라이언트 요청을 처리하고 응답을 반환합니다.
웹 애플리케이션의 경우, 웹 브라우저와 상호작용하여 데이터를 보여주고 입력을 받아 서비스 계층으로 전달합니다.

비즈니스 또는 서비스 레이어(Business Or Service Layer)
비즈니스 로직과 관련된 처리를 담당하는 레이어입니다.
프레젠테이션 레이어로부터 요청을 받아 비즈니스 로직을 수행하고, 데이터베이스나 외부 서비스와의 상호작용을 처리합니다.
비즈니스 규칙, 데이터 가공, 트랜잭션 관리 등이 이 레이어에서 이루어집니다.

데이터 액세스 레이어(Data Access Layer)
데이터베이스나 외부 시스템과의 상호작용을 처리하는 레이어입니다.
데이터베이스 CRUD(Create, Read, Update, Delete) 연산이 여기서 수행되며, 데이터를 영구적으로 저장하고 검색합니다.
이 레이어는 서비스 레이어와 데이터베이스 간의 인터페이스 역할을 담당합니다.

레이어드 아키텍처 기반 설계 특징.
- 각 레이어는 가장 까운 하위 레이어의 의존성을 주입 받습니다.
- 각 레이어는 관심사에 따라 묶여 있으며, 다른 레이어의 역할을 침범하지 않습니다.
   > 각 컴포넌트의 역할이 명확하기에 코드의 가독성과 기능 구현에 유리
   > 코드의 확장성 용이
- 각 레이어가 독립적으로 작성되면 다른 레이어와의 의존성을 낮춰 단위 테스트에 용이

 

스프링의 레이어드 아키텍처

스프링 부트는 별도의 설정 없이 spring-boot-starter-web의 의존성을 사용할 때는
기본적으로 스프링 MVC 구조를 띠게 되며 아래와 같은 레이어드 아키첵처를 이룹니다.

Spring MVC는 Model-View-Controller의 구조로
View와 Controller는 프레젠테이션 계층에 속하며 
Model은 비즈니스와 데이터 접근 계층 영역으로 구분할 수 있습니다.

프레젠테이션 레이어
스프링 MVC: 스프링은 웹 애플리케이션의 프레젠테이션 레이어를 구현하기 위해 스프링 MVC를 제공합니다.
@Controller, @RestController 어노테이션과 같은 MVC 관련 어노테이션을 사용하여 핸들러를 정의하고, 웹 요청을 처리하는 컨트롤러를 작성할 수 있습니다.
상황에 따라 유저 인터페이스 계층이라고도 합니다.
클리이언트와 접점이 됩니다.
클라이언트로부터 데이터와 함꼐 교청을 받고 처리 결과를 응답으로 전달하는 역할입니다.

비즈니스 / 서비스 레이어
스프링 빈: 스프링은 서비스 레이어를 구현하기 위해 스프링 빈(Bean)을 사용합니다. 
비즈니스 로직을 처리하는 서비스 클래스를 @Service 어노테이션을 통해 빈으로 등록하여 관리할 수 있습니다.
핵심 비즈니스 로직을 구현하는 영역입니다.
트랜잭션 처리나 유호ㅛ성 검사 등 작업도 수행합니다.

데이터 액세스 레이어
스프링 데이터: 스프링은 데이터 액세스 레이어를 구현하기 위해 스프링 데이터를 제공합니다. 
스프링 데이터는 데이터베이스에 대한 CRUD 연산을 단순화하고 JPA, JDBC, MongoDB 등 다양한 데이터베이스와의 상호작용을 지원합니다.
상황에 따라 영속 계층이라고도 합니다.
데이터베이스에 접근해야 하는 작섭을 수행합니다.
Spring Data JPA에서는 DAO역할을 지포지토리가 수행하기 때문에 레포로 대체할 수 있습니다.

스프링에서 JPA를 사용하면 @Entity 를 정의한 클래스가 도메인 객체가 되며, 이곳에서 비즈니스 로직을 설계하면 좋습니다.
다만 서비스 레이어에서 비즈니스 로직을 담당하는 경우도 있으므로 역할과 책임을 잘 구분해서 설계해야 합니다.

디자인 패턴

디자인 패턴은 소프트웨어 개발에서 자주 발생하는 문제를 해결하는데 도움이 되는 일반적인 설계 해결책들의 모음입니다. 디자인 패턴은 반복적으로 발생하는 디자인 이슈들을 해결하고, 유지보수 가능하고 확장성이 좋은 소프트웨어를 개발하기 위해 사용됩니다.

디자인 패턴은 GoF(Gang of Four)라고 불리는 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides의 저서 "Design Patterns: Elements of Reusable Object-Oriented Software"에서 처음 제시되었습니다. 이 책은 디자인 패턴을 소개하고, 디자인 패턴들을 각각의 이름과 설명으로 정의하며, 재사용 가능한 소프트웨어 디자인의 기본 원칙을 설명하는데 큰 역할을 하였습니다.

생성(Creatoinal) 패턴 구조(Structural) 패턴 행위(Behavioral) 패턴
객체 생성에 사용되는 패턴으로,
객체를 수정해도 호출부가 영향을 받지 않게 합니다.
객체를 조합해서 더 큰 구조를 만드는 패턴 객체간의 알고리즘이나 책임 분애에 관련 패턴
객체 하나로는 수행할 수 없는 작업을 여러 객체를 이용해 작업을 분배
결합도 최소화를 고려할 필요가 있음
추상 팩토리 :

구체적인 클래스를 지정하지 않고 상황에 맞는 객체를 생성하기 위한 인터페이스를 제공하는 패턴
어댑터 :

클래스의 인터페이스를 의도하는 인터페이스로 변환하는 패턴
책임 연쇄 :

요청 처리 객체를 집합으로 만들어 결합을 느슨하게 만드는 패턴
빌더: 

객체의 생성과 표현을 분리해 객체를 생성하는 패턴
브리지:

추상화와 구현을 분리해 각각 독립적으로 변행케하는 패턴
커맨드 :

실행될 기능을 캡슐화해서 주어진 여러 기능을 실행하도록 클래스를 설계하는 패턴
팩토리 메서드:

객체 생성을 서브클래스로 분리해서 위임하는 패턴
컴포지트 :

여러 객체로 구성된 복합 객체와 단일 객체를 클라이언트에서 구별 없이 다루는 패턴
인터프리터 :

주어진 언어의 문법을 위한 표현수단을 정의하고 해당 언어로 구성된 문장을 해석하는 패턴
프로토타입 :

원본 객체를 복사해 객체를 생성하는 패턴
데코레이터 :

객체의 결합을 통해 기능을 동적으로 유연하게 확장할 수 있게 하는 패턴
이터레이터 :

내부 구조를 노출하지 않으면서 해당 객체의 집합 원소에 순차적으로 접근하는 방법을 제공하는 패턴
싱글톤 :

한 클래스마다 인스턴스를 하나만 생성해서 인스턴스가 하낭미을 보장하고 어느 곳에서도 접근할 수 있게 제공하는 패턴
퍼사드 :

서브시스템의 인터페이스 집합들에 하나의 통합된 인터페이스를 제공하는 패턴
미디에이터 :

한 집합에 속한 객체들의 상호작용을 캡슐화하는 객체를 정의한 패턴
  플라이웨이트 :

특정 클래스의 인스턴스 한 개를 가지고 여러 개의 가상 인스턴스를 제공할 떄 사용하는 패턴
메멘토:

객체의 상태 정보를 저장하고 필요 따라 상태를 복원하는 패턴
  프락시 :

특정 객체를 직접 참조하지 않고 해당 객체를 대행(프락시)하는 객체를 통해 접근하는 패턴
옵저버 :

객체의 상태 변화를 관찰하는 관찰자들,
즉 옵저버 목록을 객체에 등록해 상태가 변할 떄마다 메서드 등을 통해 객체가 직접 옵저버에게 통지하게 하는 디자인 패턴
    스테이트 :

상태에 따라 객체가 행동을 변경하게 하는 패턴
    스트래티지 :

행동을 클래스로 캡슐화해서 동적으로 행동을 바꿀 수 있게 하는 패턴
    템플릿 메서드 :

일정 작업을 처리하는 부분을 서브클래스로 캡슐화해서 전체 수행 구조는 바꾸지 않으면서 특정 단계만 변경해서 수행하는 패턴
    비지터 :

실제 로직을 가지고 있는 객체가 ㅗ직을 적용할 객체를 방문하며 실행하는 패턴