-
What's Wrong with Layers? (계층형 아키텍처의 문제점)📖 개발 공부 2023. 8. 23. 00:30
계층형 아키텍처
계층형 아키텍처는 견고한 아키텍처 패턴이다.
계층을 잘 이해한다면 web과 persistance 계층에 독립적으로 도메인 로직을 작성할 수 있다. 도메인 로직에 영향을 주지 않고 웹 계층이나 영속성 계층의 기술을 변경할 수 있다.
계층형 아키텍처의 문제점
하지만 현재에 이르러서는 계층형 아키텍처 때문에 문제가 생기는 곳이 많아졌다.
계층화된 아키텍처에는 나쁜 습관이 들어 시간이 지남에 따라 소프트웨어를 변경하기가 점점 더 어려워지는 열린 측면들이 있다.
어떤 이유들이 있는지 알아보자.
1. It promotes Database-Driven Design
기존 계층 구조의 기초는 데이터베이스이다.
웹 계층은 도메인 계층에 따라 달라지며, 도메인 계층은 지속성 계층과 데이터베이스에 종속된다. 모든 것이 persistance layer 위에서 구축이 된다.
우리는 주로 상태(state)가 아니라 행동(behavior)을 모델링하려고 한다. 상태(state)는 모든 애플리케이션의 중요한 부분이지만 행동은 상태를 변경하여 비즈니스를 주도하는 것이다.
그렇다면 도메인 논리가 아닌 데이터베이스를 아키텍처의 기초로 만드는 이유는 무엇일까?
대부분의 경우 데이터베이스 구조가 어떻게 생겼는지 생각하고 그 위에 도메인 논리를 구현하는 것으로 넘어간다.
데이터베이스 중심 아키텍처의 원동력은 객체 관계형 매핑(ORM) 프레임워크의 사용이다. ORM 프레임워크를 계층화된 아키텍처와 결합하면 비즈니스 규칙과 지속성 측면을 쉽게 혼합할 수 있다. 이로 인해 비즈니스 규칙을 영속성 관점과 섞고 싶은 강한 유혹을 받게 된다.
위의 사진 같은 상황이 되면 강한 결합으로 인해 서비스에서 영속성 모델을 비즈니스 모델처럼 사용하게 되고, 이로 인해 영속성 계층에 관련된 작업(트랜잭션 등)을 해야만 한다.
결국엔 영속성 코드에 도메인 코드가 녹아들기 때문에 둘 중 하나만 바꾸는 것이 어려워진다.
2. It’s prone to Shortcuts
계층형 아키텍처의 유일한 규칙은 같은 계층의 컴포넌트나 아래의 계층만 접근이 가능하다. 그 외에는 팀마다 정한 규칙이 있을 수도 있고 개발 도구로 강제할 수 있다.
만약 상위 컴포넌트로 접근이 필요한다면 trade-off로 해당 컴포넌트만 계층 아래로 내려버리면 단순하게 처리된다. 그렇지만 편해지자는 마음에, 바쁜 일정 속에서 지름길을 계속 허용하게 된다면 하위 계층은 점점 비대해질 수밖에 없다.
이에 대한 perfect한 후보는 특정 계층에 속해보이지 않는 helper/utility component이다. 그래서 아키텍처에 대한 shortcut을 쓰고싶지 않은 경우에는 추가적인 아키텍처를 강제하지 않는 이상 계층형 아키텍처는 최선의 선택이 아니다.3. It Grows Hard To Test
계층을 건너뛰는 경우를 본 적이 있을 것이다. Entity 의 단일 필드만 조작하기 때문에 웹 계층에서 직접 Persistence 계층에 액세스하고 이를 위해 Domain 계층을 귀찮게 할 필요가 없다.
하지만 2가지 단점을 얘기할 수 있다.
- 단 하나의 필드를 조작하는 것에 불과하더라도 도메인 로직을 웹 계층에 구현하게 된다.
- 앞으로 유스케이스가 확장된다면, 우리는 책임을 혼합하고 애플리케이션 전체에 필수적인 도메인 논리를 퍼뜨리면서 웹 계층에 더 많은 도메인 논리를 추가할 가능성이 높다.
- 웹 계층 테스트에서 도메인 계층뿐만 아니라 영속성 계층의 의존성을 끊기 위한 모킹(mocking)해야 한다.
- 이것은 단위 테스트에 복잡성을 추가한다.
4. It Hides the Use Cases
우리는 일반적으로 새 코드를 만드는 것보다 기존 코드를 변경하는 데 많은 시간을 보낸다.
계층의 경계가 사라지고 여기저기 도메인 로직이 흩어졌기 때문에, 새로운 기능을 추가해도 적당한 위치를 찾기가 힘들고 기존의 코드를 유지보수하는 일이 어려워진다.
계층 구조는 도메인 서비스의 "너비"에 대한 규칙을 부과하지도 않다. 시간이 지남에 따라 다음 그림과 같이 여러 사용 사례를 지원하는 매우 광범위한 서비스로 이어지는 경우가 많다.
비대해진 서비스는 다양한 영속성 계층을 의존하게 되고, 많은 웹 계층의 컴포넌트가 이 서비스를 의존하는 진흙 덩어리가 되어버린다.
5. It Makes Parallel Work Difficult
"Adding manpower to a late software project makes it later"
– The Mythical Man-Month: Essays on Software Engineering by Frederick P. Brooks, Jr., Addison-Wesley, 1995.계층형 아키텍처에서는 추가적인 개발자가 투입된다고 일정에 도움이 되지 않는다. 개발자 3명이 각각 웹, 도메인, 영속성을 맡아 개발할 수 있을까? 전혀 그럴 수 없다.
데이터베이스 주도 설계는 영속성 로직이 도메인 로직과 뒤섞여서 각 측면으로 개발을 할 수 없다. 또한 넓은 서비스가 존재한다면 병합 충돌(merge conflict) 문제로 서로 다른 기능을 동시에 작업할 수 없다.
하지만 개발자가 먼저 인터페이스를 정의하면 각 개발자가 실제 구현을 기다릴 필요없이 이러한 인터페이스에 대해 작업할 수 있다.
물론 이것은 가능하지만 앞서 논의한 바와 같이 지속성 논리가 도메인 논리와 너무 혼합되어 각 측면에서 개별적으로 작업할 수 없는 데이터베이스 중심 설계를 수행하지 않는 경우에만 가능하다.
6. How Does This Help Me Build Maintainable Software?
올바른 구축과 추가적인 규칙을 적용하면 계층형 아키텍처는 유지보수가 쉽고 변화에 유연해진다.
하지만 계층형 아키텍처는 잘못된 방향으로 흘러가기 쉬운 구조다. 유리처럼 한번 균열이 생기기 시작하면 균열이 계속 사방으로 퍼지게 된다. 어떤 아키텍처에 상관없이 계층형 아키텍처의 함정을 염두에 두면 지름길에 빠지지 않고 유지보수하기 좋은 솔루션에 도움이 된다.
반응형'📖 개발 공부' 카테고리의 다른 글
[개발일지] MongoSocketException 이슈 해결기 (0) 2023.08.30 [Cloud Design Patterns] Asynchronous Request-Reply pattern 비동기 요청/응답 패턴 (feat. HTTP 폴링, 웹소켓) (0) 2023.08.29 Redis vs Memcached (1) 2023.08.18 Cache / Caching 전략 / Cache Expiration, Eviction (0) 2023.08.14 [HTTP] HTTP 메서드 (0) 2023.08.09