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

Yi suho·2023년 12월 10일
1
post-thumbnail

소프트웨어 아키텍처란?

소프트웨어 아키텍처란 소프트웨어 시스템의 전체적인 구조와 구성요소들 간의 상호 작용을 설계하는 것을 말한다.

쉽게 말해 건축물의 뼈대를 잡는 것과 같은 과정이다.
건축물의 구조와 종류는 굉장히 다양한다.
어떤 자재를 사용하고 해당 자재들을 어떻게 조립하는지에 따라 건축물의 특성은 크게 달라진다.

이와 같이 소프트웨어 아키텍처는 시스템의 전체적인 동작을 결정하고 시스템의 품질 성능(성능,확장성,유지보수성,보안 등)에 직접적으로 영향을 미친다.

소프트웨어 아키텍처를 선택할 때는 다양한 요소 (요구 사항,복잡성,기술 스택,경험, 비용 및 시간 등)들을 고려하여 적절한 패턴을 선택해야한다.

그 중 가장 기본적인 아키텍처인 레이어드 아키텍처에 대해서 알아보자.

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

가장 흔한 아키텍처 스타일, 모놀리식 아키텍처 중 하나 이다.
단순하고 대중적이면서 비용도 적게 들어 사실상 표준 아키텍처이다.

레이어드 아키텍처란 소프트웨어 시스템을 관심사 별로 여러개의 계층으로 분리(계층화)한 아키텍처를 뜻한다.

각 계층은 어플리케이션 내에서 특정 역할과 책임이 있다.
그 들은 자신의 역할에만 집중한다. 여기서 중요한 것은 구성 요소간 관심사가 분리 되었다는 점이다.

이들은 추상화된 인터페이스로만 소통한다.
이 때, 소통은 자신에게 인접한 하위 계층에 요청을 보내는 방식으로 진행된다.

여기서 핵심은 단방향 의존성이다. 하위 계층은 상위 계층을 몰라야한다.하위 계층은 인터페이스만 제공하고 요청만 받을 뿐이다.

가장 일반적인 레이어드 아키텍처는 4-tier 아키텍처(Presentation,Business,Persistence,Database)이다.

  • 응집성을 높이고 의존도를 낮추기 위한 규칙
  • 상위 계층이 하위 계층을 호출하는 단방향성 유지
  • 상위 계층이 하위의 여러 계층을 모두 알 필요 없이 바로 밑의 근접 계층만 활용
  • 상위 계층이 하위 계층에 영향을 받지 않게 구성
  • 계층 간의 호출은 인터페이스를 통해 호출
  • 제어 흐름이 상위 계층에서 하위 계층으로 흐르게 되어 하위의 인터페이스가 상위 계층의 기능에 관여하게 됨
  • 이는 DIP는 만족할 수 있지만 (계층의 인터페이스로 인해), OCP는 만족하지 않음
    • DIP (Dependency Inversion Principle)와 OCP (Open/Closed Principle)
      DIP는 상위 계층이 하위 계층의 구체적인 구현보다는 인터페이스에 의존하도록 하는 원칙이다.
      OCP는 소프트웨어 구성 요소가 확장에는 열려 있지만 수정에는 닫혀 있어야 한다는 원칙이다.

각 계층의 특징에 대해 알아보자

Presentation Layer

  • 사용자 혹은 클라이언트 시스템과 직접적으로 연결되는 부분이다.
  • 이 외에 비즈니스 로직등은 해당 계층의 관심사가 아니다.

Business Layer

  • 비즈니스 로직을 구현하는 부분이다. 실제로 시스템이 구현해야 하는 핵심 로직을 담당한다.
  • Presentation Layer로 부터, 사용자의 요청을 전달 받고 해당 요청을 실질적으로 처리하는 부분이다.

Presistence Layer

  • 데이터의 영구 저장과 관리를 담당하는 부분이다.
  • 웹 어플리케이션의 데이터베이스와의 상호작용을 처리하며, 데이터베이스와의 상호작용을 추상화한다.

Database Layer

  • 실제 데이터베이스를 뜻한다.

레이어분리

  • 내부 컴포넌트는 논리적으로 수평한 레이어들로 구성된다.
  • 각 레이어는 어플리케이션에서 프레젠테이션 로직,비즈니스 로직 등의 주어진 역할을 수행한다.
  • 일반적으로 Presentation,Business,Persistence,Database의 4개 표준 레이어로 구성한다.
  • 물론 규모에 따라 병합 하기도 하며, 그 이상의 레이어로 구성하기도 한다.

관심사 분리

모듈화와 인터페이스간의 연결에 대한 이야기로 표현할 수도 있는데, OSI 7계층처럼 각각의 영역이 담당하는 역할과 책임을 기준으로 만든다는 것이다.

  • 중요한 특징은 관심사 분리이다.
  • 예를 들어, 비즈니스 레이어는 데이터를 어떻게 받아야하는지,화면에는 어떻게 보여줄지 전혀 관여하지 않는다.
  • 따라서 기술적인 부분에 집중할 수 있지만, 변화에 반응하는 능력(민첩성)은 떨어진다는 단점이 있다.

도메인 변경의 어려움

  • 도메인 분할 아키텍처와 반대로 기술 역할에 따라 묶는다.(기술 중심)
  • 반대로 이야기 하면 어떤 도메인은 모든 레이어에 분산되게 된다.따라서 이 도메인을 변경하는것은 쉽지 않다.
  • 예를 들어'고객'도메인을 변경하려면 Presentation,Business,Persistence,Database 등을 모두 변경해야 한다.
  • 이런 이유로 레이어드 아키텍처 스타일은 도메인 주도 설계 방식과 잘 맞지 않는다.

하위 레이어가 상위 레이어를 모르게 해야한다. 계층구조(hierarchy)

하위 레이어에서 상위 레이어의 API를 콜하거나 상위 레이어가 가지고 있는 정보에 의존(Dependency)하지 않아야 한다.

즉,하위 레이어는 인터페이스만 제공하여 상위 레이어에서 접근할 수 있게만 하는 것이지 상위 레이어를 알고 있어서는 안된다.

이렇게 레어간의 격리를 잘 해두고,상위 레이어로 부터 하위 레이어로만 '요청'하는 형태로 간다면 추후, 특정 레이어만 교체하는 것이 수월해진다.

레이어 격리

  • 각 레이어는 폐쇄(Closed)또는 개방(Open)상태이다.
  • 폐쇄 레이어란 요청이 상위 레이어 에서 하위 레이어로 이동하므로 중간에 어떤 레이어도 건너뛸 수 없다.
  • 예를들어 Presentation 레이어가 Persistence 레이어에 직접 엑세스를 한다고 한다면 Persistence레이어에서 변경이 발생하는 경우 Business 레이어,Presentation 레이어 둘다 영향을 받게 되고 , 결국 컴포넌트간의 상호 의존도가 높아진다.
  • 따라서 가능한 폐쇄 레이어로 설계하는게 유지 보수에 유리하다.

CLOSED

레이어드 아키텍처에서'닫혀있다'(CLOSED)는 중요한 개념이다.
이는 계층간 요청이 이동할 때 인접한 계층을 통과하는 것을 의미한다.
예를 들어,Presentation 레이어 에서 Persistence 레이어로 요청이 이동하기 위해서는 Business 레이어를 거쳐야한다.

그러면 왜 계층을 뛰어넘어 바로 접근하는 것이 좋지 않은 방법일까?

생각해 보면 Presentation 레이어에서 직접 DB에 접근하는 것이 여러 계층을 거치는 방법보다 훨씬 빠를것이다.
하지만 이는 관심사가 분리되지 않는 형태이다.

왜 관심사를 분리하고, 다른 계층에서 영향을 받지 않는 독립적인 계층을 만들기 위해 노력해야 하는가?

이는 한 계층이 변경이 발생했을 때 , 다른 계틍에 영향을 받지 않게 하기 위해서이다.

예를 들어, 온라인 쇼핑몰이 있는데 처음에는 모바일 앱을 통해 접근하도록 설계 됬는데 나중에 데스크톱 웹 브라우저를 통한 접근으로 확장해야 하는 상황이 발생하였을때 계층이 잘 분리되어 있다면 사용자 인터페이스와 관련된 Presentation 레이어만 수정하면 된다.

온라인 쇼핑몰의 상품관리,주문처리 등의 비즈니스 로직은 변경할 필요가 없으며,이로 인해 전체적인 코드 수정과 테스트에 필요한 시간과 노력이 크게 줄어들게 된다.

반면에, 만약 이러한 계층 분리가 제대로 이루어지지 않았다면 상점의 전체 코드를 검토하고 사용자 인터페이스와 관련된 부분을 찾아 수정해야한다.이는 시간이 많이 소요되고 실수의 여지를 높일 수 있다.

이처럼 관심사를 분리하고 계층을 독립적으로 유지하는 것은 소프트웨어의 유연성과 유지보수성을 높이는 중요한 전략이다.

OPEN

항상 모든 계층이 닫혀있어야 하는 것은 아니다.

특정 요청에만 추가적인 계층이 필요한 경우가 있을 것이다.
예를 들어,DB에 이미지를 넣기 전 이미지 하성을 하는 계층을 추가하고 한다면 이 계층은 해당 기능을 사용하는 요청에서만 필요하다.

이런 경우 해당 기능을 사용하는 요청에 한해서만 이미지 합성 계층을 사용하고, 그렇지 않은 요청의 경우 해당 계층을 우회하도록 한다.

이와 같이 요청이 특정 계층을 우회하고 그 아래의 계층으로 이동 가능하게 하는 것을 '개방한다.'(OPEN)고 말한다.

계층 아키텍처에서는 계층 구조와 요청 흐름을 문서화하는 것이 아주 중요하다.
어떤 계층이 열려있고 닫혀 있는지 그 이유까지 문서화 하거나 적절하게 전달해야한다.
(그렇지 않으면 유지 관리, 테스트,배포 등에서 많은 어려움을 겪게 된다.)

싱크홀 안티 패턴(architecture sinkhole)

이는 요청이 싱크홀 처럼 뚝 떨어지는 것을 의미한다.
다시 말해 하위 레이어를 거치긴 하지만, 막상 그 레이어에서는 추가적인 작업 없이 그저 전달만 하는 경우를 뜻한다.

예를 들어,Presentation 레이어에서 데이터베이스의 정보를 가져오려고 하는데, 중간의 두 레이어에서는 아무것도 하지 않고 through pass하는 경우이다.

그래서 중간의 두 레이어 에서는 최소 function 두번이라는 불필요한 오버헤드가 발생하게 되는 것이다.

이런 경우, 레이어를 개방하여 상위 레이어에서 직접 요청을 하는 방식으로 수정할 수 있다.

물론 이는 트레이드 오프의 영역이기 때문에 적절한 방식을 선택하는 것이 좋다.

선택을 할때 일반적으로 80-20 규칙을 따른다.
이는 요청을 20%는 단순 통과 처리하고,80%는 비즈니스 로직을 수행한다는 규칙이다.

이 비율이 역전되고 단순 통과 처리되는 요청이 많아지면, 해당 계층을 개방하는 것을 고려할 수 있다.

  • 아키텍처 싱크홀 안티 패턴을 조심해야한다.
  • 요청이 한 레이어에서 다른 레이어로 이동할 때 각 레이어가 아무 비즈니스 로직도 처리하지 않고 그냥 통과하는 것을 말한다.
  • 이런 흐름은 불필요한 객체 초기화 및 처리를 빈번하게 유발하고 쓸데없는 메모리를 소모하며 성능에도 부정적인 영향을 준다.
  • 물론 싱크홀 안티패턴이 없을 순 없다. 전체 요청의 20%가 싱크홀인 정도면 그런대로 괜찮은 수준이다.

토폴로지 구성

레이어드 아키텍처를 사용할 때, 하나의 토폴로지(묶음)로 구현/배포를 하는 것은 아니다.
예를 들어 데이터베이스 레이어만 분리하여 2개의 토폴로지로도 가능하며 Presentation 레이어도 분리해서 3개의 토폴로지로도 가능하다.
중요한 것은 "역할과 책임"이라는 기준에 의해 레이어로 나누어져 있고, 각각은 추상화된 인터페이스로 접근하게 만드는 것이다.


레이어드 아키텍처를 사용하는 이유

  • 작고 단순한 앱이나 웹사이트에 알맞는 아키텍처이다.특히 처음 구축을 할 때,출발점으로 괜찮은 아키텍처 선택이다.
  • 그리 복잡하지 않으며 어쩌면 비용도 가장 저렴한 아키텍처 스타일이므로 소규모 애플리케이션을 간편하게 개발할 수 있다.
  • 물론 규모가 커질수록 유지 보수성,민첩성,시험성,배포성 같은 특성이 점점 나빠진다.

장점

  • 각 계층이 관심사별로 분리되어 있으므로, 코드의 재사용성과 유지보수성이 향상된다.
  • 변화에 유연하게 대처
    • 각 계층이 독립적으로 개발,확장,변경이 가능하다.
      또한, 각 계틍에서 기능이 확장되거나 변경이 발생할 경우 해당 계층의 코드만 변경이 된다.
      즉, 변화에 유연하게 대처한다.
  • 테스트 용이성
    • 각 계층이 독립적으로 테스트 가능하므로, 단위 테스트나 통합 테스트가 용이하게 수행된다.

단점

  • 오버헤드
    • 계층간 통신을 통해 동작하기 때문에, 데이터의 전달 및 변환 과정에서 일부 오버헤드가 발생한다.이는 계층이 많아 질수록 더 증가한다.
  • 복잡성
    • 계층간 통신을 위한 인터페이스와 로직을 추가해야하므로 복잡성이 증가한다. 특히,대규모 프로젝트에서는 계층 간의 관리와 유지보수가 복잡해질 가능성이 크다.

1개의 댓글

comment-user-thumbnail
2024년 6월 14일

잘 정리된 내용 감사합니다!

답글 달기