-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ac7b3eb
commit 086ef8c
Showing
11 changed files
with
288 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
# 30장. 데이터베이스는 세부사항이다 | ||
|
||
- [yumin](./yumin/) | ||
- [yumin](./yumin/) | ||
- [zhoon](./zhoon/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# 30장. 데이터베이스는 세부사항이다 | ||
|
||
## Introduction | ||
|
||
- 아키텍처 관점에서 볼 때 데이터베이스는 엔티티가 아님 | ||
- 즉, 데이터베이스는 세부사항이라서 아키텍처의 구성요소 수준으로 끌어올릴 수 없음 | ||
- 명확히 짚고 가자면, 지금 데이터 모델을 말하는 건 아님 | ||
- 애플리케이션 내부 데이터의 구조는 시스템 아키텍처에서 대단히 중요함 | ||
- **하지만 데이터베이스는 데이터 모델이 아님** | ||
- 데이터베이스는 일개 소프트웨어일 뿐 | ||
- 데이터베이스는 데이터에 접근할 방법을 제공하는 유틸리티 | ||
- 아키텍처 관점 | ||
- 이러한 유틸리티는 저수준의 세부사항 (메커니즘) 일 뿐, 아키텍처와는 관련이 없음 | ||
- 그리고 뛰어난 아키텍처라면 저수준의 메커니즘이 시스템 아키텍처를 오염시키는 일을 용납하지 않음 | ||
|
||
## 관계형 데이터베이스 | ||
|
||
- 에드거 커드는 1970년에 관계형 데이터베이스의 원칙을 정의함 | ||
- 관계형 모델은 계속 성장하여 1980년대 중반이 되자 데이터 저장소의 지배적인 형태가 됨 | ||
- 이 모델은 우아했고, 절제되었으며, 강건했음 | ||
- 관계형 데이터베이스는 데이터를 저장하고 접근하는 데 탁월한 기술이었음 | ||
- 하지만 관계형 데이터베이스의 기술이 어떻든 결국은 그저 기술일 뿐 | ||
- 그리고 이는 관계형 데이터베이스가 세부사항임을 뜻함 | ||
- 관계형 테이블은 특정한 형식의 데이터에 접근하는 경우에는 편리하지만, **데이터를 행 단위로 배치한다는 자체는 아키텍처적으로 볼 때 전혀 중요하지 않음** | ||
- 데이터가 테이블 구조를 가진다는 사실은 오직 아키텍처의 외부 원에 위치한 최하위 수준의 유틸리티 함수만 알아야 함 | ||
- 많은 데이터 접근 프레임워크가 테이블과 행이 객체 형태로 시스템 여기 저기에서 돌아다니게 허용하는데, 아키텍처적으로 잘못된 설계 | ||
|
||
## 데이터베이스 시스템은 왜 이렇게 널리 사용되는가? | ||
|
||
- 어떻게 데이터베이스 시스템이 소프트웨어 시스템과 소프트웨어 기업을 장악할 수 있었을까? | ||
- 한마디로 답하자면, 바로 ‘디스크’ 때문 | ||
- 디스크가 반세기동안 회전식 자기 디스크부터 엄청나게 발전할 동안, 프로그래머는 디스크 기술이 가진 치명적인 한 가지 특성으로 인해 괴롭힘을 당함, 바로 **느리다는 특성** | ||
- 디스크 때문에 피해갈 수 없는 시간 지연이라는 짐을 완화하기 위해, 색인, 캐시, 쿼리 계획 최적화가 필요해짐 | ||
- 그리고 데이터를 표현하는 일종의 표준적인 방식도 필요했는데, 이러한 색인, 캐시, 쿼리 계획에서 작업중인 대상이 어떤 데이터인지 알 수 있어야 했기 때문 | ||
- **간단히 말해서 데이터 접근 및 관리 시스템이 필요** | ||
- 시간이 지나면서 이러한 시스템은 뚜렷이 구분되는 두 가지 유형으로 구분됨 | ||
- 파일 시스템 | ||
- 관계형 데이터베이스 관리 시스템, RDBMS | ||
- 파일 시스템 | ||
- 문서 기반, document | ||
- 문서 자체를 자연스럽고 편리하게 저장하는 방법을 제공 | ||
- 일련의 문서를 이름을 기준으로 저장하거나 조회할 때는 잘 동작하지만, 내용을 기준으로 검색할 때는 그리 크게 도움되지 않음 | ||
- 관계형 데이터베이스 관리 시스템, RDBMS | ||
- 내용 기반 | ||
- 내용을 기반으로 레코드를 자연스럽고 편리하게 찾는 방법을 제공함 | ||
- 레코드가 서로 공유하는 일부 내용에 기반해서 다수의 레코드를 연관 짓는 데 매우 탁월 | ||
- 하지만 안타깝게도 정형화되지 않은 문서를 저장하고 검색하는 데는 대체로 부적합 | ||
- 두 시스템 모두 데이터를 빠르게 조작할 수 있도록 결국에는 관련 있는 데이터를 RAM 으로 가져옴 | ||
|
||
## 디스크가 없다면 어떻게 될까? | ||
|
||
- 디스크는 현재 소멸 중인 부품 | ||
- 디스크는 RAM 으로 대체되고 있음 | ||
- 디스크가 모두 사라진다면, 그래서 모든 데이터가 RAM에 저장된다면 데이터를 어떻게 체계화할 것인가? | ||
- 데이터를 테이블 구조로 만들어 SQL을 이용해 접근할 것인가? | ||
- 파일 구조로 만들어 디렉터리를 통해 접근할 것인가? | ||
- 당연히 아니다 | ||
- 이 데이터들을 연결 리스트, 트리, 해시 테이블, 스택, 큐 혹은 여타 무수히 많은 데이터 구조로 체계화할 것이며, 데이터에 접근할 때는 포인터나 참조를 사용할 것 | ||
- 이것이 프로그래머가 하는 일이기 때문 | ||
- 사실 이미 그렇게 하고 있음 | ||
|
||
## 세부사항 | ||
|
||
- 데이터베이스가 세부사항이라고 말하는 이유는 바로 이러한 현실 때문 | ||
- 데이터베이스는 그저 메커니즘에 불과함 | ||
- 따라서 아키텍처 관점에서 본다면, 데이터가 어떤 형태인지는 절대로 신경 써서는 안 됨 | ||
- 정말로 우리는 디스크 자체가 존재한다는 사실조차도 인식해서는 안 됨 | ||
|
||
## 하지만 성능은? | ||
|
||
- 성능은 당연히 아키텍처적인 관심사 | ||
- 하지만 데이터 저장소의 측면에서 성능은 완전히 캡슐화하여 업무 규칙과는 분리할 수 있는 관심사임 | ||
- 데이터 저장소에서 데이터를 빠르게 넣고 뺄 수 있어야 하는 것은 맞지만, 이는 저수준의 관심사 | ||
- 이 관심사는 저수준의 데이터 접근 메커니즘 단에서 다룰 수 있음 | ||
- 성능은 시스템의 전반적인 아키텍처와는 아무련 관련이 없음 | ||
|
||
## 개인적인 일화 | ||
|
||
- RDBMS 도입과 관련해서 싸움 | ||
- 저자는 반대함 | ||
- 공학적인 부분에서는 저자가 옳았다고 말함 | ||
- 하지만 현실은 다름 | ||
|
||
## 결론 | ||
|
||
- 데이터는 중요 | ||
- 데이터베이스는 세부사항 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
# 31장. 웹은 세부사항이다 | ||
|
||
- [yumin](./yumin/) | ||
- [yumin](./yumin/) | ||
- [zhoon](./zhoon/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# 31장. 웹은 세부사항이다 | ||
|
||
## Introduction | ||
|
||
- 웹은 바꾼 것이 아무것도 없었고, 적어도 웹은 그렇게 해서는 안됐었음 | ||
- 우리 업계는 일련의 반복되는 진동을 겪어왔고, 웹은 그저 이러한 진동의 맨 끝에 있을 뿐 | ||
- **이 진동은 모든 연산 능력을 중앙 서버에 두는 방식과 모든 연산 능력을 단말에 두는 방식 사이에서 끊임없이 움직여 왔음** | ||
|
||
## 끝없이 반복하는 추 | ||
|
||
- 이 진동이 웹으로부터 시작되었다고 보는 일은 옳지 않음 | ||
- 웹이 있기 전에는 클라이언트-서버 아키텍처가 있었음 | ||
- 이 이야기는 계속 될 것이고, 앞으로도 우리는 연산 능력을 어디에 둘지 알 수 없을 것 | ||
- 연산 능력을 중앙에 집중하는 방식과 분산하는 방식 사이에서 우리는 끊임없이 움직임 | ||
- 그리고 저자 생각에 이러한 진동은 한동안 계속될 것 | ||
- 나도 마찬가지 | ||
- 아키텍트로서 우리는 멀리 내다봐야 함 | ||
- 이 진동은 그저 핵심 업무 규칙의 중심에서 밀어내고 싶은 단기적인 문제일 뿐 | ||
|
||
## 요약 | ||
|
||
- GUI 는 세부사항, 웹은 GUI, 따러서 웹은 세부사항 | ||
- 아키텍터라면 이러한 세부사항을 핵심 업무 로직에서 분리된 경계 바깥에 두어야 함 | ||
|
||
## 결론 | ||
|
||
- 이러한 종류의 추상화는 만들기 쉽지 않고, 제대로 만들려면 수차례의 반복 과정을 거쳐야 할 것 | ||
- 하지만 가능함 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
# 32장. 프레임워크는 세부사항이다 | ||
|
||
- [yumin](./yumin/) | ||
- [yumin](./yumin/) | ||
- [zhoon](./zhoon/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# 32장. 프레임워크는 세부사항이다 | ||
|
||
## Introduction | ||
|
||
- 프레임워크는 상당히 인기를 끌고 있음 | ||
- 일반적으로 말하자면 좋은 현상 | ||
- 무료인 데다 강력하며 유용한 프레임워크가 많음 | ||
- **하지만 아무리 해도 프레임워크는 아키텍처가 될 수 없음** | ||
|
||
## 프레임워크 제작자 | ||
|
||
- 프레임워크 제작자는 우리를 알지 못하며, 우리가 풀어야 할 문제도 알지 못함 | ||
- 프레임워크 제작자는 본인의 문제, 혹은 동료와 친구들의 문제를 해결하기 위해 만들 뿐이며, 이 문제가 많이 겹칠 수록 인기를 끌 것 | ||
- 겹치는 영역이 크면 클수록 프레임워크는 실제로 더 유용해짐 | ||
|
||
## 혼인 관계의 비대칭성 | ||
|
||
- 우리와 프레임워크 제작자 사이의 관계는 놀라울 정도로 비대칭적 | ||
- 우리는 프레임워크를 위해 대단히 큰 헌신을 해야 하지만, 프레임워크 제작자는 우리를 위해 아무런 헌신도 하지 않음 | ||
- 프레임워크 제작자는 프레임워크에 대해 장기간에 걸친 막대한 헌신을 요청하지만, 어떠한 경우에도 그에 상응하는 헌신을 해주지는 않음 | ||
- 이 혼인 관계는 일방적 | ||
- 모든 위험과 부담은 오롯이 당신이 감수할 뿐, 제작자가 감수하는 건 아무 것도 없음 | ||
|
||
## 위험 요인 | ||
|
||
- 프레임워크의 아키텍처는 그다지 깔끔하지 않은 경우가 많음 | ||
- 프레임워크는 의존성 규칙을 위반하는 경향이 있음 | ||
- 프레임워크는 애플리케이션 추기 기능을 만드는 데는 도움이 될 것 | ||
- 하지만 제품이 성숙해지면서 프레임워크가 제공하는 기능과 틀을 벗어나게 될 것 | ||
- 프레임워크는 우리에게 도움이 되지 않는 방향으로 진화할 수도 있음 | ||
- 도움이 되지 않는 신규 버전으로 업그레이드하느라 다른 일을 못할 수도 있음 | ||
- 심지어 사용 중이던 기능이 사라지거나 반영하기 힘든 형태로 변경될 수도 있음 | ||
- 새롭고 더 나은 프레임워크가 등장해서 갈아타고 싶을 수도 있음 | ||
|
||
## 해결책 | ||
|
||
> 프레임워크와 결혼하지 말라! | ||
- 프레임워크를 사용할 수는 있지만, 결합해서는 안 됨 | ||
- 프록시를 만들고, 업무 규칙에 플러그인할 수 있는 컴포넌트에 이들 프록시를 위치시켜라 | ||
- 프레임워크가 핵심 코드 안으로 들어오지 못하게 하라 | ||
- 스프링의 경우 | ||
- 업무 객체는 절대로 스프링에 대해 알아서는 안됨 | ||
- 업무 객체보다는 메인 컴포넌트에서 스프링을 사용해서 의존성을 주입하는 편이 나음 | ||
- 메인은 아키텍처 내에서 가장 지저분한, 최저 수준의 컴포넌트이기 때문에 스프링을 알아도 상관 없음 | ||
|
||
## 이제 선언합니다 | ||
|
||
- 정말로 결혼해야만 하는 프레임워크도 존재 | ||
- C++ <-> STL | ||
- 자바 <-> 표준 라이브러리 | ||
- 이러한 관계는 정상, 하지만 선택적이어야 함 | ||
- 프레임워크와 결혼은 결코 가볍게 시작할 수 있는 관계가 아님 | ||
|
||
## 결론 | ||
|
||
- 프레임워크와의 첫 만남부터 바로 결혼하려 들지 말라 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# 33장. 사례 연구: 비디오 판매 | ||
|
||
- [zhoon](./zhoon/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# 33장. 사례 연구: 비디오 판매 | ||
|
||
## Introduction | ||
|
||
- 이 챕터는 따로 요약을 하지 않겠다. | ||
- 책을 다시 살펴보자. | ||
|
||
## 제품 | ||
|
||
## 유스케이스 분석 | ||
|
||
## 컴포넌트 아키텍처 | ||
|
||
## 의존성 관리 | ||
|
||
## 결론 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# 34장. 빠져 있는 장 | ||
|
||
- [zhoon](./zhoon/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# 34장. 빠져 있는 장 | ||
|
||
## Introduction | ||
|
||
- 설계나 코드 조직화와 관련된 몇 가지 접근법을 살펴보자 | ||
|
||
## 계층 기반 패키지 | ||
|
||
- 가장 단순한 첫 번째 설계 방식은 전통적인 수평 계층형 아키텍처 | ||
- 기술적인 관점에서 해당 코드가 하는 일에 기반해 그 코드를 분할함 | ||
- 흔히 우리는 이 방식을 ‘계층 기반 패키지’라고 부름 | ||
- 이 아키텍처는 엄청난 복잡함을 겪지 않고도 무언가를 작동시켜 주는 아주 빠른 방법 | ||
- 소프트웨어가 커지고 복잡해지기 시작하면, 머지 않아 큰 그릇 세 개만으로는 모든 코드를 담기엔 부족하다는 사실을 깨닫고, 더 잘게 모듈화해야 할지를 고민하게 될 것 | ||
- 계층형 아키텍처는 업무 도메인에 대해 아무것도 말해주지 않는다는 문제도 있음 | ||
|
||
## 기능 기반 패키지 | ||
|
||
- 서로 연관된 기능, 도메인 개념, 또는 Aggregate Root 에 기반하여 수직의 얇은 조각으로 코드를 나누는 방식 | ||
- 저자가 본 전형적인 구현에서는 모든 타입이 하나의 자바 패키지에 속하며, 패키지 이름은 그 안에 담긴 개념을 반영해 지음 | ||
- 저자는 소프트웨어 개발팀이 수평적 계층화(계층 기반 패키지)의 문제를 깨닫고, 수직적 계층화(기능 기반 패키지)로 전환하는 걸 자주 목격함 | ||
- 저자가 보기에 두 접근법은 모두 차선책 | ||
|
||
## 포트와 어댑터 | ||
|
||
- “포트와 어댑터 ports and adapters” 혹은 “육각형 아키텍처 hexagonal architecture”, “경계, 컨트롤러, 엔티티 BCE” 등의 방식으로 접근하는 이유는 업무/도메인에 초점을 둔 코드가 프레임워크가 데이터베이스 같은 기술적인 세부 구현과 독립적이며 분리된 아키텍처를 만들기 위해서임 | ||
- 그런 코드 베이스는 내부(도메인)와 외부(인프라)로 구성됨을 흔히 볼 수 있음 | ||
- 내부 영역 | ||
- 도메인 개념을 모두 포함 | ||
- 외부 영역 | ||
- 외부 세계와의 상호작용을 포함함 | ||
- 주요 규칙 | ||
- 외부가 내부에 의존하며, 절대 그 반대로는 안된다는 점 | ||
- 도메인 주도 설계에서는 내부에 존재하는 모든 것의 이름은 반드시 유비쿼터스 도메인 언어 관점에서 기술하라고 조언함 | ||
|
||
## 컴포넌트 기반 패키지 | ||
|
||
- 코드를 조직화하는 방법에 대해 또 다른 선택지 | ||
- 지금까지 우리가 본 모든 것들을 혼합한 것 | ||
- 큰 단위의 단일 컴포넌트와 관련된 모든 책임을 하나의 자바 패키지로 묶는 데 주안점을 둠 | ||
- 이 접근법은 서비스 중심적인 시각으로 소프트웨어 시스템을 바라보며, 마이크로서비스 아키텍처가 가진 시각과도 동일함 | ||
- 사용자 인터페이스를 큰 단위의 컴포넌트로부터 분리해서 유지함 | ||
- 본질적으로 이 접근법에서는 ‘업무 로직’과 영속성 관련 코드를 하나로 묶는데, 이 묶음을 저자는 ‘컴포넌트’라고 부름 | ||
- 컴포넌트에 대한 엉클 밥의 정의 | ||
- 컴포넌트는 배포 단위다. 컴포넌트는 시스템의 구성 요소로, 배포할 수 있는 가장 작은 단위다. 자바의 경우 jar 파일이 컴포넌트다. | ||
- 컴포넌트에 대한 저자의 정의 | ||
- 컴포넌트는 멋지고 깔끔한 인터페이스로 감싸진 연관된 기능들의 묶음으로, 애플리케이션과 같은 실행 환경 내부에 존재한다. | ||
- 이 방법론에서 소프트웨어 시스템은 하나 이상의 컨테이너로 구성되며, 각 컨테이너는 하나 이상의 컴포넌트를 포함함 | ||
- 또한 각 컴포넌트는 하나 이상의 클래스 (또는 코드) 로 구현됨 | ||
- 이때 각 컴포넌트가 개별 jar 파일로 분리될지 여부는 직교적인 관심사 orthogonal concern | ||
- 컴퍼넌트 기반 패키지 접근법의 주된 이점 | ||
- 도메인과 관련된 무언가를 코딩할 때 오직 한 곳, 컴포넌트만 둘러보면 된다는 점 | ||
- 이 컴포넌트 내부에서 관심사의 분리는 여전히 유효하며, 따라서 업무 로직은 데이터 영속성과 분리되어 있음 | ||
- 하지만 이는 컴포넌트 구현과 관련된 세부사항으로, 사용자는 알 필요가 없음 | ||
- 이는 마이크로서비스나 서비스 지향 아키텍처를 적용했을 때 얻는 이점과도 유사함 | ||
|
||
## 구현 세부사항엔 항상 문제가 있다 | ||
|
||
## 조직화 vs. 캡슐화 | ||
|
||
- 계층 기반 패키지, 기능 기반 패키지, 포트와 어댑터, 컴포넌트 기반 패키지 각각의 접근법에서 다이어그램이 인상적으로 변함 | ||
|
||
## 다른 결합 분리 모드 | ||
|
||
- 프로그래밍 언어가 제공하는 방법 외에도 소스 코드 의존성을 분리하는 방법이 존재할 수 있음 | ||
- 다른 선택지로는 소스 코드 수준에서 의존성을 분리하는 방법도 있음 | ||
- 정확하게는 서로 다른 소스 코드 트리로 분리하는 방법 | ||
- 소스 코드 트리로 분리하는 방법은 빌드 도구를 사용해서 모듈이나 프로젝트가 서로 분리되도록 구성해야 함 | ||
- 이는 너무 이상적인 해결책 | ||
- 포트와 어댑터 접근법을 적용할 때는 이보다 더 간단한 방법을 사용하기도 함 | ||
- 단순히 소스 코드 트리를 두 개만 만드는 것 | ||
- 도메인 코드 (내부) | ||
- 인프라 코드 (외부) | ||
- 이 방법은 잠재적으로 절충해야 할 부분이 있음을 알고 있어야만 함 | ||
- 저자는 이를 “포트와 어댑터에 대한 페리페리크 안티 패턴” 이라 부름 | ||
|
||
## 결론: 빠져 있는 조언 | ||
|
||
- 이 장은 최적의 설계를 꾀했더라도, 구현 전략에 얽힌 복잡함을 고려하지 않았으면 설계가 순식간에 망가질 수 있다는 사실을 강조하는 데 그 목적이 있음 | ||
- 설계를 어떻게 해야만 원하는 코드 구조로 매핑할 수 있을지, 그 코드를 어떻게 조직화할지, 런타임과 컴파일타임에 어떤 결합 분리 모드를 적용할지를 고민하라 | ||
- 가능하다면 선택사항을 열어두되, 실용주의적으로 행하라 | ||
- 그리고 팀의 규모, 기술 수준, 해결책의 복잡성을 일정과 예산이라는 제약과 동시에 고려하라 | ||
- 또한 선택된 아키텍처 스타일을 강제하는 데 컴파일러의 도움을 받을 수 있을지를 고민하며, 데이터 모델과 같은 다른 영역에 결합되지 않도록 주의하라 | ||
- 구현 세부사항에는 항상 문제가 있는 법이다 |