Both sides previous revisionPrevious revisionNext revision | Previous revision |
domain-driven_design:part_4_strategic_design:15_distillation [2024/07/18 14:02] – [15 디스틸레이션] Diagram 내에 선언적 형식을 10장과 연결 ledyx | domain-driven_design:part_4_strategic_design:15_distillation [2024/07/29 11:27] (current) – [ABSTRACT CORE] 링크 오류 수정 ledyx |
---|
= 15 디스틸레이션 = | = 15 디스틸레이션 = |
| |
폭넓은 일련의 모델을 구분하고 도메인 모델의 정수를 추출하는 방법 | 폭넓은 일련의 모델을 구분하고 도메인 모델의 정수인 **CORE DOMAIN**을 추출하는 방법 |
| |
{{tag>Domain-Driven_Design Modeling Design}} | {{tag>Domain-Driven_Design Modeling Design}} |
| |
| |
coreDomain --"벗어날 대상으로 인식"--> genericSubdomain | coreDomain --"벗어날 대상으로 인식<br>(덜 중요한 도메인 분리)"--> genericSubdomain |
coreDomain --"방향을 제시하는 데 활용"--> domainVisionStatement | coreDomain --"방향을 제시하는 데 활용"--> domainVisionStatement |
coreDomain --"내용물을 표시하는 데 활용"--> highlightedCore | coreDomain --"내용물을 표시하는 데 활용"--> highlightedCore |
coreDomain --"벗어날 대상으로 인식"--> cohesiveMechanism | coreDomain --"벗어날 대상으로 인식<br>(계산 메커니즘 분리)"--> cohesiveMechanism |
coreDomain --"재패키지화의 대상으로 간주"--> segregatedCore | coreDomain --"재패키지화의 대상으로 간주"--> segregatedCore |
| |
== COHESIVE MECHANISM == | == COHESIVE MECHANISM == |
| |
=== GENERIC SUBDOMAIN과 COHESIVE MECHANISM === | __계산 메커니즘__을 간결하게 만드는 모델을 찾아라. |
| 응집력 있는 부분을 찾아내면 나머지 메커니즘을 이해하기가 좀더 쉬워질 것이다. |
| |
| <note important> |
| 개념적으로 COHESIVE MACHANISM을 **별도의 경량 프레임워크로 분할**하라. |
| 특히 형식주의[(formalism, 목표 달성을 위한 실질적인 내용보다 의식이나 절차 선례 관습등에 집착하는 성향을 형식주의라고 한다. 실질적인 목적보다 표면적인 현상에 행정력을 낭비하여 행정 목적에 어긋나는 것이라고 할 수 있다. 출처 : [[https://namu.wiki/w/%ED%98%95%EC%8B%9D%EC%A3%BC%EC%9D%98|나무위키]])]나 잘 문서화된 알고리즘 카테고리를 주의 깊게 살펴라. |
| |
| |
| [[domain-driven_design:part_3_refactoring_toward_deeper_insight:10_supple_design#intention-revealing_interfaces|INTENTION-REVEALING INTERFACE]]로 프레임워크의 기능을 노출하라. |
| 이제 도메인의 다른 요소들은 해법의 복잡성("어떻게")을 프레임워크에 위임해서 **문제("무엇")을 표현하는 데 집중할 수 있다.** |
| </note> |
| |
| 새로 만들어지는 것이 __**계산에만 집중**__하게 하고 표현력 있는 모델과 섞이지 않게 한다. |
| 그러면 책임의 분리가 일어나고 CORE DOMAIN이나 GENERIC SUBDOMAIN의 모델이 사실이나 규칙, 또는 문제를 **정형화**하게 된다. |
| 그리고 COHESIVE MECHANISM은 모델에 구체화돼 있는 대로 **규칙을 결정하거나 계산을 완료한다.** |
| |
| 예시 : 그래프 알고리즘, [[https://wiki.ledyx.xyz/domain-driven_design/part_3_refactoring_toward_deeper_insight/09_making_implicit_concepts_explicit?s[]=specification#specification|SPECIFICATION]] |
| |
| |
| === GENERIC SUBDOMAIN Versus COHESIVE MECHANISM === |
| |
| 공통점으로는 CORE DOMAIN의 부담을 더는 데 목적이 있다. |
| 차이점은 각자 맡고 있는 책임의 본질에 있다. |
| |
| * GENERIC SUBDOMAIN : 팀이 도메인을 어떻게 바라보는지와 관련된 일부 측면을 나타내는 표현력 있는 모델이 토대를 둔다. \\ 단지 CORE DOMAIN에 비교하여 덜 중심적이고, 덜 중요하고, 덜 특화되었다는 점을 제외하면 전혀 다르지 않다. |
| * COHESIVE MECHANISM : **도메인을 나타내지 않는다.** 표현력 있는 모델에서 제기하는 일부 성가신 **계산** 문제를 해결해줄 뿐이다. |
| |
| <note important> |
| 모델이 제안하면, COHESIVE MECHANISM은 **처리**한다. |
| </note> |
| |
=== MECHANISM이 CORE DOMAIN의 일부인 경우 === | === MECHANISM이 CORE DOMAIN의 일부인 경우 === |
| |
| 예외적으로 MECHANISM 자체가 기업 소유이고 |
| 소프트웨어 가치의 **핵심 부분**을 차지하는 경우, |
| 간혹 **대단히 특화된 알고리즘을 보유**한 경우 |
| 비용 편익 분석 기반으로 분리를 할지 말지 결정될 것이다. |
| |
| |
== 선언적 형식의 디스틸레이션 == | == 선언적 형식의 디스틸레이션 == |
| |
| <note> |
| 디스틸레이션의 가치는 |
| 현재 여러분이 무슨 일을 하고 있는지 볼 수 있다는 것이다. |
| 즉, 관련성 없는 세부사항 탓에 혼란을 겪지 않고도 **본질**에 직접적으로 도달하는 것이다. |
| </note> |
| |
| [[part_3_refactoring_toward_deeper_insight:10_supple_design#a_declarative_style_of_design|선언적 형식]]을 취하게 되면 더 정수에 가까운 상태가 된다. |
| |
| |
== SEGREGATED CORE == | == SEGREGATED CORE == |
| |
| CORE DOMAIN을 구조적으로 구별하는 데 직접적인 접근법 |
| |
| GENERIC SUBDOMAIN을 추출하는 식으로 |
| 도메인에서 일부 CORE를 불분명하게 만드는 세부사항을 제거해 CORE를 눈에 띄게 만들 수 있지만 |
| 모든 하위 도메인을 식별하고 분명하게 하는 작업은 쉽지 않고, 이 중 일부는 그럴 만한 가치가 없는 듯 하다. |
| |
| <note important> |
| 보조적인 역할(잘못 정의된 것을 비롯해)로부터 |
| CORE 개념을 분리되게끔 모델을 리팩터링하고 |
| CORE와 다른 코드와의 결합은 줄이면서 |
| CORE의 응집력은 강화하라. |
| 모든 일반적이거나 보조적인 역할을 하는 구성요소를 다른 객체로 추출해서 __다른 패키지에 배치__하라. |
| 심지어 이러한 과정이 매우 긴밀하게 결합돼 있는 요소를 분리하는 식으로 모델을 리팩터링하는 것을 의미하더라도 말이다. |
| </note> |
| |
| AOP와 비슷한 의미인듯. |
| |
| |
| SEGREGATED CORE로 리팩터링하는 단계는 대체로 아래와 같다. |
| |
| - CORE 하위 도메인을 식별한다(디스틸레이션 문서에서 도출해야 할 수도 있음). |
| - 새로운 MODULE로 관련 클래스를 옮긴다. 이 때 MODULE의 이름은 관련 개념에 따라 짓는다. |
| - __개념을 직접적으로 표현하지 않는__ 서버 데이터와 기능으로 코드를 리팩터링한다. \\ 제거된 측면을 (아마도 새로 만들어진) __다른 패키지에 있는 클래스에 배치__한다. 그러한 측면은 개념상 관련 작업과 함께 둬야 하지만 완벽하게 하려고 __너무 많은 시간을 들여서는 안 된다.__ \\ CORE 하위 도메인의 불순물을 제거하고 그곳에서 다른 패키지를 참조하는 바를 명시적이 그 자체로도 이해할 수 있는 상태로 만드는 데 집중한다. |
| - 새로 생긴 SEGREGATED CORE MODULE의 관계와 __상호작용을 더욱 단순하고 전달력 있게 만들고__, 다른 MODULE과의 관계가 최소화되고 분명해지게끔 리팩터링한다. (이 것은 계속 진행되는 리팩터링의 목표가 된다.) |
| - SEGREGATED CORE가 완전해질 때까지 또 다른 CORE 하위 도메인을 대상으로 위 단계를 반복한다. |
| |
| |
=== SEGREGATED CORE를 만드는 데 드는 비용 === | === SEGREGATED CORE를 만드는 데 드는 비용 === |
| |
| * 특정 MODULE의 CORE DOMAIN의 응집도를 이끌어내기 위해 Cohesion이 희생될 수도 있는데, 엔터프라이즈 소프트웨어의 가장 큰 부가가치는 모델의 기업별 측면에서 나오기 때문에, 이를 CORE DOMAIN으로 이끌어내면 오히려 이득이다. |
| * CORE를 분리하려면 해야 할 일이 많기 때문에 개발자가 많은 시간을 보낸다. |
| |
| <note important> |
| SEGREGATED CORE를 노출시켜야 할 때는 |
| 규모가 큰 BOUNDED CONTEXT가 시스템에 결정적인 역할을 하지만 |
| 많은 양의 보조적인 기능 탓에 **모델의 근본적인 부분이 가려지는 경우다.** |
| </note> |
| |
| |
=== 발전하는 팀의 의사결정 === | === 발전하는 팀의 의사결정 === |
| |
| 의사소통은 모든 사람이 CORE라는 하나의 시각을 함께 유지할 수 있을 만큼 효과적으로 이뤄져야 한다. |
| |
| |
== ABSTRACT CORE == | == ABSTRACT CORE == |
| |
| <note important> |
| 모델의 가장 근본적인 개념을 식별해서 |
| 그것을 별도의 클래스나 추상 클래스, 또는 인터페이스로 추출하라. |
| 이 추상 모델이 중요 컴포넌트 간에 발생하는 **상호작용**을 대부분 표현할 수 있게끔 설계하라. |
| 특화되고 세부적인 구현 클래스는 |
| 하위 도메인을 기준으로 정의된 자체적인 MODULE에 남겨둔 상태에서 |
| 이 추상적이면서 전체적인 모델을 자체적인 MODULE에 배치하라. |
| </note> |
| |
| |
| ABSTRACT CORE를 모델링하려면 |
| 핵심 개념과 해당 개념이 시스템의 주요 **상호작용**에서 수행하는 역할을 심층적으로 이해해야 한다. |
| 다시 말해, 이것은 [[domain-driven_design:part_3_refactoring_toward_deeper_insight:13_refactoring_toward_deeper_insight|더 심층적인 통찰력을 향한 리팩터링]]의 한 사례에 해당한다. |
| 그리고 __대개 여기에는 상당한 양의 재설계가 필요하다.__ |
| |
| |
== 심층 모델의 디스틸레이션 == | == 심층 모델의 디스틸레이션 == |
| |
| <flow> |
| flowchart |
| |
| subgraph subCoreDomain["CORE DOMAIN의 정제 → Project 전체"] |
| deepModel["Deep Model의 정제 → 한 도메인"] |
| end |
| |
| </flow> |
| |
| |
== 리팩터링의대상 선택 == | == 리팩터링의대상 선택 == |
| |
| CORE DOMAIN 분리에 집중. |
| |
| - 고통 주도적(pain-driven) 리팩터링에서는 \\ 문제의 근원에 CORE DOMAIN이나, CORE와 지원 요소와의 관계가 관련돼 있는지 살핀다. \\ 만약 그렇다면, 이를 악물고 그 부분을 가장 먼저 고쳐야 한다. |
| - 마음껏 리팩터링할 수 있는 상황이라면 \\ 제일 먼저 CORE DOMAIN을 더 잘 분해하고, CORE의 격리를 개선하며, 보조적인 하위 도메인이 GENERIC하게 만드는 데 집중한다. |
| |