반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 스프링 스케쥴러
- 가장 큰 수
- 알고리즘
- H-index
- 전화번호 목록
- 스택/큐
- 모던 자바 인 액션
- kubenetes
- 정렬
- @Getter
- @EnableScheduling
- 코딩 테스트
- 해시
- K번째수
- 쿠버네티스
- 영속 자료구조
- 프로그래머스
- 루씬 인 액션
- @configuration
- 롬복 어노테이션
- Java
- 검색 기능 확장
- 고차원 함수
- 크론 표현식
- 다리를 지나는 트럭
- @Setter
- 기능개발
- @Data
- 완주하지 못한 선수
- 커링
Archives
- Today
- Total
Today I Learned
[도메인 주도 설계] 10. 유연한 설계 (1) 본문
728x90
- 레거시 코드로 인한 중압감에 시달리지 않고 변경을 수용하기 위해 유연한 설계가 필요하다.
- 과도한 추상 계층과 간접 계층은 오히려 유연성에 방해가 된다.
- 유연하게 설계를 수정하기 위해서는 설계가 모델을 드러내어 쉽게 이해할 수 있어야 한다.
- INTENTION-REVEALING INTERFACE(의도를 드러내는 인터페이스)
- 컴포넌트를 사용하기 위해 컴포넌트의 구현 세부사항을 고려해야한다면 캡슐화의 가치는 사라진다.
- 인터페이스를 구성하는 각 요소의 이름을 토대로 설계 의도를 드러내야 한다.
- 따라서 결과와 목적만을 표현하도록 클래스와 연산의 이름을 부여해야 한다.
- 방법이 아닌 의도를 표현하는 인터페이스 뒤로 모든 까다로운 메커니즘을 캡슐화해야 한다.
- 예제 - 리팩터링 : 페인트 혼합 애플리케이션
- 메서드의 이름에서 의도를 드러내어 클래스의 용도에 대한 실마리를 제공할 수 있다.
- 테스트로 표현된 예제가 있다면 더 쉽게 실마리를 찾을 수 있다.
- SIDE-EFFECT-FREE FUNCTION(부수효과가 없는 함수)
- 연산은 질의를 통해 정보를 얻거나, 명령을 통해 상태를 변경하는 것을 의미한다.
- 부수효과란 연산에 영향을 미치는 시스템 상태의 변경을 뜻한다.
- 다수의 규칙에 따라 상호작용하거나 여러가지 계산을 조합하면 결과를 예측하기가 어려워지고 부수효과가 발생하기 쉽다.
- 함수는 부수효과를 일으키지 않으면서 결과를 반환하는 연산으로써 연산을 사용하는데 따르는 위험을 낮춘다.
- 부수효과를 낮추는 방법
- 명령과 질의를 엄격하게 분리된 연산으로 유지한다. 모든 질의와 계산을 부수효과를 발생시키지 않는 메서드에서 수행한다.
- 명령과 질의를 분리하는 대신 연산의 결과를 표현하는 불변객체인 VALUE OBJECT를 생성해서 반환한다. 기존 상태를 변경하는 대신 VALUE OBJECT를 이끌어내거나 전체 책임을 VALUE OBJECT로 옮기는 식으로 부수효과를 제거할 수 있다.
- 예제 - 페인트 혼합 애플리케이션 다시 리팩터링하기
- 지식탐구 과정에서 색상 혼합(color mixing)과 페인트(paint)는 다르다는 것을 알게되었다.
- pigment Color(안료 색소)로 색성과 관련된 데이터를 분리했다. pigment Color는 VALUE OBJECT이므로 불변 객체이다.
- 따라서 pigment Color를 혼합하는 경우 상태를 변경하는 대신 새로운 색상을 표현하는 pigment Color 객체가 생성된다.또한 mixIn() 메서드 안에서 처리되고 있는 색상과 관련된 행위도 분리되어야 한다.
public class Paint { public void mixIN(paint other) { volume = volume + other.getVolume(); double ratio = other.getVolume() / volume; pigmentColor = pigmentColor.mixedWith(other.pigmentColor(), ratio); } }
- 지식탐구 과정에서 색상 혼합(color mixing)과 페인트(paint)는 다르다는 것을 알게되었다.
- ASSERTION(단언)
- 단언은 임의의 연산이 종료된 후에 만족해야 하는 객체의 상태에 관해 개발자가 명시하는 것이다.
- 불변식을 비롯해 사전조건과 사후조건을 명확하게 명시하면 객체나 연산을 사용한 결과를 이해할 수 있다.
- "사후조건"은 연산의 부수효과를 의미하며 호출되는 연산에서 보장하는 결과를 기술한다.
- "사전조건"은 계약에 명시된 단서와 조항과 유사하며 사후조건이 유효하기 위해 충족되어야하는 조건들이다.
- 연산의 사후조건과 클래스 및 AGGREGATE의 불변식을 명시한다.
- 프로그램 코드에 직접 ASSERTION을 명시할 수 없다면 자동화된 단위 테스트를 작성해서 내용을 표현한다.
- 예제 - 다시 페인트 혼합 애플리케이션으로
- 앞선 예제에서 Paint 클래스의 mixin(paint) 메시지를 수신하는 객체의 용량은 인자로 전달된 객체의 용량만큼 증가한다.
- 그에 맞춰 인자의 용량도 감소시켜야한다. 하지만 인자를 변경하는 것은 매우 위험한 종류의 부수효과에 해당한다.
- 인자를 변경하는 것은 좋은 방법은 아니지만 쉽고 직관적이다. 다음과 같은 불변식으로 작성할 수 있다.
"페인트를 혼합하면 전체 용량은 변하지 않는다" - 그런데 프로그램의 목적이 추가된 순수한 페인트의 목록에 관한 보고서를 생성하는 것이라면 어떨까?
- 논리적으로 일관성있는 페인트 용량 모델을 구축하는 대신 애플리케이션의 요구사항에 맞춰 새로운 모델을 찾을 필요가 있다.
- Paint의 부여된 두가지 책임을 분리할 수 있다.
- 명령은 mixIn() 하나 밖에 없으며, mixIn()은 단지 객체를 컬렉션에 추가할 뿐이다.
- 테스트 메서드는 다음과 같다.
public void testMixingVolume { pigmentColor yellow = new PigmentColor(0, 50, 0); pigmentColor blue = new PigmentColor(0, 0, 50); StockPaint paint1 = new StockPaint(1.0, yellow); StockPaint paint2 = new StockPaint(1.5, blue); MixedPaint mix = new MixedPaint(); mix.mixIn(paint1); mix.mixIn(paint2); assertEquals(2.5, mix.getVolume(), 0.01); }
- SIDE-EFFECT FREE FUNCTION과 ASSERTION의 예측 가능성을 INTENTION-REVEALING INTERFACE의 의사전달력과 결합하면 더 안전한 캡슐화와 추상화가 가능해진다.
728x90
'도메인 주도 설계' 카테고리의 다른 글
[도메인 주도 설계] 10. 유연한 설계 (3) (0) | 2022.02.25 |
---|---|
[도메인 주도 설계] 10. 유연한 설계 (2) (0) | 2022.02.17 |
[도메인 주도 설계] 09. 암시적인 개념을 명확하게 (2) (0) | 2022.01.26 |
[도메인 주도 설계] 09. 암시적인 개념을 명확하게 (1) (0) | 2022.01.20 |
[도메인 주도 설계] 08. 도약 (0) | 2022.01.11 |
Comments