본문 바로가기

SW core/SW Design14

DDD - 개념적 윤곽 - 출처: 도메인 주도 설계 - 에릭 에반스 - 개념적 윤곽(Conceptual contour) 코드를 개발하다보면 유연하게 조합할 수 있도록 작은 크기로 기능을 나누기도 하며, 복잡성을 캡슐화하기 위해 기능을 더 큰 단위로 통합 하기도 한다. 이런 방법들은 지나치게 단순해서 일반 원칙으로 적용하기에는 부적절하다. 하지마 이런 방법들은 문제를 해결하기 위한 동기를 부여한다. 모델 혹은 설계를 구성하는 요소가 모놀리식 구조이면 기능이 중복되어 클라이언트는 인터페이스로부터 유용한 정보를 일부만 파악가능하다. 반대로 클래스와 메소드를 잘게 나누면 작은 객체들의 협력 방식을 이해하고 있어야 하기 때문에 클라이언트 객체가 무의미하게 복잡해진다. 도메인에는 잠재적인 일관성이 존재한다. 특정 모델을 발견하면 나중에 .. 2022. 10. 31.
DDD - Assertion - 출처: 도메인 주도 설계 - 에릭 에반스 - 개요 복잡한 계산을 하는 부분은 앞서 살펴본 side effect free function 으로 분리하면 문제의 난이도를 낮출 수 있다. 하지만 여전히 부수효과가 있는 명령(command)는 Entity 에 남아있으며 개발자는 이런 명령의 영향력을 이해해야 한다. 단순한 명령의 경우 코드를 조사하는것만으로도 결과를 예측할 수 있다. 하지만 앱의 규모가 커지면 작은 부분을 조합하여 큰 부분을 구성하는 설계가 등장하기 마련이고, 이럴 경우 사용자가 하나의 명령을 호출하면 다른 명령을 호출하게 된다. 이렇게 되면 각 호출되는 명령을 이해해야 해서 캡슐화가 깨지게 된다. 내부를 조사하지 않고 설계 요소의 의미와 연산 실행결과를 이해하는 방법이 필요하다. 이를 "단.. 2022. 10. 22.
DDD - Side effect free function - 출처: 도메인 주도 설계 - 에릭 에반스 - 연산과 함수 연산은 명령(command, modification)과 질의(query)로 나눌 수 있다. 명령(command, modification): 변수값을 변경해서 시스템의 상태를 변경 질의(query): 변수안에 저장된 데이터에 접근하고, 저장된 데이터를 기반으로 계산을 수행 함수는 부수효과를 일으키지 않고 결과를 반환하는 연산이다. 여러번 호출 해도 무방하며 매번 동일한 값을 반환한다. - 명령과 질의의 분리 명령과 질의는 서로 엄격하게 다른 연산으로 분리해야 한다. 변경을 발생시키는 메서드는 도메인 데이터를 반환하지 않고 단순하게 유지해야 한다. 또는 명령과 질의를 분리하는 대신 연산의 결과를 표현하는 새로운 VO(Value-Object)를 생성.. 2022. 10. 22.
DDD - Inteface - 출처: 도메인 주도 설계 - 에릭 에반스 - Intention Revealing Interface (의도를 드러내는 인터페이스) Interface는 Client 개발자가 객체를 효과적으로 사용하기 위해 알아야할 정보를 추상화하고 있다. 그래서 Interface가 제대로 작성되어 있지 않으면 Client 개발자는 사용하려고 하는 개체에 대한 세부사항을 아주 세밀하게 알고 있어야 한다. Client 개발자의 머릿속이 이런 구현 세부사항들로 넘처나게 되면 해결해야 할 비즈니스 문제를 집중해서 해결할 수 없다. 객체의 캡슐화 가치가 떨어지게되는것이다. 클래스나 연산이름을 지을때에는 수행 방법이 아닌 결과와 목적만을 표현해야 한다. TDD 를 잠깐이라도 접해본적이 있다면 구현하지도 객체에 대해 Test cod.. 2022. 10. 1.
DDD - Specification - 출처: 도메인 주도 설계 - 에릭 에반스 - Specification 간단한 규칙을 검사하는 코드를 작성할때 Boolean을 반환하는 anInvoice.isOverdue() 와 같은 형태로 작성하는 경우가 많다. 규칙이 단순하다면 이정도로 충분하지만 어플리케이션의 규칙이 항상 간단한것만은 아니다. 송장(Invoice)의 지불유예기간에 대한 정책은 고객의 계정상태나 제품군에 따라 달라질 수 있다. 이런 규칙들이 늘어나다보면 송장이라는 모델은 송장 자체를 표현하기 보다 송장에 대한 규칙만 늘어놓는 코드로 전락하고 송장의 본질적인 특성이 무엇인지 파악할 수 없게 된다. 다시말해서 원래 모델링했던 Entity, VO 책임에 맞지 않은 규칙의 다양성과 조합이 본질적인 모델의 의미를 압도하게 된다. 이런 규칙들.. 2022. 9. 25.
DDD - 불명확한 개념 - 출처: 도메인 주도 설계 - 에릭 에반스 - 불명확한 개념의 모델링 객체지향 패러다임을 적용하는 경우 어떠한 객체를 찾는데 집중하게 된다. 객체지향 관련 책을 보다보면 명사와 동사에 기반하여 객체를 찾으라고 하지만 "발생" 처럼 명사나 동사로 표현하기 힘든 모델도 존재하며 객체 모델로서 중요한 요소가 될 수 있다. - 명시적인 제약조건 제약조건은 중요한 범주의 모델 개념을 형성한다. 보통 이런 개념은 암시적으로 존재하지만 이를 명시적으로 표현해주면 설계를 개선할 수 있다. 간단한 제약조건의 경우 객체의 메서드에 포함되는것이 자연스러운 경우가 있다. 어떤 "Bucket" 객체에 내용물을 저장할 대 제한된 용량을 초과할 수 없다는 불변식을 만족한다고 가정해보자. 이를 아래와 같이 코드로 표현할 수 있다... 2022. 9. 19.
DDD - Repository - 출처: 도메인 주도 설계 - 에릭 에반스 - Repository 하나의 객체에서 다른 객체를 탐색하려면 연관관계(association)을 이용하면 된다. 하지만 객체의 생명주기 중간에도 Entity나 Value를 탐색할 수 있는 진입점이 필요하다. 어떤 객체의 참조를 얻기 위한 방법에는 아래와 같은 방법들이 있다. 생성 연산으로 객체를 생성 연관관계를 이용한 탐색 영속화 계층으로 부터 검색 DB 검색은 어디서든 이용가능하며 곧바로 어떤 객체에도 접근 가능하게 해준다. 프로그램내에서 모든 객체가 서로 상호연결이 되어야 하는것은 아니다. 탐색 혹은 검색에 의존하느냐는 설계 결정 사항이다. Customer 객체가 모든 Order에 대한 컬렉션을 가지고 있는 방식이 될수도 있으며 Customer ID를 이용.. 2022. 9. 18.
DDD - Factory - 출처: 도메인 주도 설계 - 에릭 에반스 - Factory 어떤 객체나 Aggregate를 생성하는 일이 복잡해지거나 혹은 내부 구조가 너무 많이 드러나는 경우 Factory를 통해 캡슐화를 제공할 수 있다. 우리는 자동차를 운전할 때 어떻게 조립 되었느냐는 신경쓰지 않는다. 두 가지 행위는 같은 시간에 일어나지 않으며, 이런 기능이 동일한 매커니즘에 결합되어 있는것은 의미가 없기 때문이다. 이를 객체 생성관점에 빗대어 생각해보면 복잡한 객체를 생성하는 일과 생성된 객체가 하는 일은 관련성이 적다고 생각할 수 있다. 프로그래밍 언어의 기본적인 내용을 학습할 때 main과 같은 함수에서 곧바로 객체를 생성한다. 이런식으로 client가 객체를 생성해서 사용하면 되는데 왜 굳이 Factory를 통해 캡슐.. 2022. 9. 12.
DDD - 도메인 객체의 lifecycle과 Aggregate - 출처: 도메인 주도 설계 - 에릭 에반스 - 도메인 객체의 생명주기 일반적으로 객체를 사용하는 과정을 생각해보자. 생성자로 객체를 생성한 뒤 연산에서 사용하며 직접 해제하거나 참조관계를 끊으면 GC와 같은 수집기로 보내져서 소멸하는 과정을 거치게 된다. 도메인 객체는 이런 기본적인 생명주기 말고도 특별히 더 고려해야하는 점들이 있다. 우선 생명주기 동안 무결성을 유지해야 하며 생명주기를 관리해주어서 모델이 난해해지는것을 방지한다. 이 말을 지금 당장은 자세하게 이해하지 못해도 상관없다. 뒤이어 설명할 aggregate 항목을 보면 완전히 이해할 수 있을것이다. DDD에서는 이를 해결하기 위해 Aggregate(집합체), Factory, Repository 3 가지 패턴을 제시한다. Aggregate:.. 2022. 9. 10.
DDD - Module (package) - 출처: 도메인 주도 설계 - 에릭 에반스 - Module (package) 인간이 한번에 받아들일 수 있는 인지력은 한계가 있기 마련이다. 만약 legacy 시스템을 운영해야 하는 업무를 수행한다고 가정해보자. legacy가 방대하다면 해당 시스템을 한번에 이해하기란 쉽지 않을것이다. 그럼 어떻게 해당 시스템을 분석할것인가? 가장 기본적인 접근법은 특정 단위로 나누어서 분석하고 그들간의 관계를 파악하는것이다. module은 왜 필요한가? 위에서 언급한대로 인간의 인지적인 과부하를 줄이기 위한 단위가 필요한데 이것이 바로 module 또는 package 라고할 수 있다. module을 분석하는 관점에는 2가지가 있다. 하나는 module과 module간의 관계를 파악하는 관점이고, 다른 하나는 해당 m.. 2022. 8. 7.