https://www.youtube.com/watch?v=NNFJREcalc0
응용 소프트웨어란
무엇일까 ?
application software -> 사용자가 사용하게 되는 프로그램을 응용 소프트웨어
우린 응용 소프트웨어 개발을 하는데 어떻게 하면 소프트웨어다움
으로 개발을 해야할까 ?
아키텍쳐는
어떤소프트웨어를 개발하는데 어떤 소프트
를 사용해서 어떤 방식 으로 시스템을 만드는 가 에 대해서 다양한 조건들이 있을것이다.
이러한 조건들이 아키텍쳐라고 한다.
이러한 아키텍쳐는 필연적으로 고려를 하면서 작성해야한다.
설계도면없이 배를 만들고 건물을 만들순 없으니깐 말이다.
그중에서 DDD 에 대해서 알아봤다.
DDD 가 뭘까 ??
무슨 말의 약자일까 ??
Domain Driven Design 말이다.
번역을하자면 도메인 주도 설계이다.
여기서 도메인
이 무엇일까 ?
도메인은 사용자가 사용하는것 .
사용자가 사용하게 될때 유사한 업무의 집합
기술을 어떻게 사용하는지 보단 , 어떤 일을 수행하는지에 초점을 두고있다.
유저가 이용하는 방향에 집중하는 개발
여기서 사용자라고 함은 코드가 될수도 있고 , 하나의 버튼이 될수도 있고 ,
소프트웨어 전체 등
그 소프트웨어와 관련된 모든 것이라고 할수있다.
요리사가
응용 소프트웨어
에서 요리 이미지를 볼 수 있다고 한다면 ,
그 요리 이미지는 하나의 도메인이고 ,
개발자가 조건문 하나를 가지고 고민하고있다면 그 조건문도 하나의 도메인이 될 수있다.
즉 도메인은 무엇을 기준으로 잡느냐에 따라서 다르다.
내가 조금더 넓게 잡을수도 있고 ,좁게 잡을 수도 있다.
다시 조금 소프트웨어스럽게 얘기하면
우리가 무엇인가에 해결하고자 하는 문제의 영역 ( 비지니스 )
그래서 DDD 는 비지니스 Domain별로 나누어 설계하는 방식
이다.
중국요리사
/
/
요리사
\
\
한국요리사
위와 같이 도메인
이라는 요리사 밑에 하위 도메인 중국요리사
도메인,
한국요리사
도메인이 존재한다.
client가 요청을 보내게 되면 presentation 에 들어가게 된다.
이게 어떻게 보면 Controller
역할을 한다고 생각하면 되는데
Controller
역할을 하게 되는 presentaion
을 거쳐서
Application Layer
에 호출을 하게 되고 ,
Application
에서는 Domain
과 Entity
를 어떻게 활용할지를 정하게 된다.
Domain
은 하나의 아이템이라고 생각하면 된다.
하나의 데이터의 객체라고 보며 되며
이러한 객체를 어떻게 활용할지를 정하게 된다.
예를 들어 우리가 TypeORM
을 사용하게 되면
거기에 Repository
를 통해서 데이터를 CRUD
비지니스 로직을 작성하게 된다.
서비스가 커지면서 검의 종류가 많아 질 수 있다.
위와 같이 요리사 가 있다고하면 한국 요리사 중국요리사 파생이 된다.
이것처럼 도메인 모델의 복잡도가 점차 증가하고 복잡도를 관리하기 위해 도메인 묶음 이자 집합체인 애그리거트
가 등장하게 된다.
한국 요리사 , 중국요리사가 를 묶고 있는 요리사가 애그리거트가 된다.
이러한 애그리거트에는 특징이 존재한다.
하나의 애그리거트
에 포함된 객체들은 도메인 규칙과 요구사항에 따라 함께 취급된다.하나의 애그리거트
에 포함된 객체들은 동일하거나 유사한 라이프사이클(함께 생성되거나 , 함께 제거되거나 , 함께변경등..) 을 가져야한다.하나의 애그리거트
에 포함된 객체는 다른 애그리거트에 포함되지 않아야 한다.애그리거트
는 자기 자신을 관리할 수 있지만 다른 애그리거트를 직접 관리하지는 않는다.애그리거트에 속한 객체가 일관된 상태를 유지하려면 애그리거트 전체를 관리할 주체가 필요하게 된다.
VO 는 뭘까?? ValueObject 의 약자 이다.
값 객체는 속성들의 집합으로, 자체로서는 별다른 의미가 없고 다른 객체와의 관계에서 의미를 가지는 객체입니다.
Value Object
는 도메인에 입력된 타입값을 나타낸다.VO
는 도메인에서 상속을 받아 사용하게 된다. VO
에는 도메인 로직이 들어간다.VO 내부에 선언된 속성(필드) 의 모든 값들이 VO 객체마다 값이 같아야 , 똑같은 객체라고 판별한다.
data class Money(val amount: BigDecimal, val currency: String) {
fun add(other: Money): Money {
require(currency == other.currency) { "Currencies must match!" }
return Money(amount + other.amount, currency)
}
}
class Order(val orderId: UUID) {
private val _lineItems: MutableList<LineItem> = mutableListOf()
val lineItems: List<LineItem> = _lineItems
fun addProduct(product: Product, quantity: Int) {
_lineItems.add(LineItem(product, quantity))
}
fun totalAmount(): Money {
return _lineItems.sumOf { it.totalPrice() }
}
// Nested Value Object
data class LineItem(val product: Product, val quantity: Int) {
fun totalPrice(): Money = product.price.multiply(BigDecimal(quantity))
}
}
class Product(val productId: UUID, val price: Money, val name: String)
VO 는 Getter 와 Setter 를 가질수 있고 , VO 는 테이블 내에 있는 속성 외에 추가적인 속성을 가질 수 있으며 , 여러 테이블 (A , B , C ) 에 대한 공통 속성을 모아서 만든 BaseVO 클래스를 상속 받아서 사용할 수도 있습니다.