본문 바로가기
Concepts/SW Design

DDD - Inteface

by ocwokocw 2022. 10. 1.

- 출처: 도메인 주도 설계 - 에릭 에반스

- Intention Revealing Interface (의도를 드러내는 인터페이스)

Interface는 Client 개발자가 객체를 효과적으로 사용하기 위해 알아야할 정보를 추상화하고 있다. 그래서 Interface가 제대로 작성되어 있지 않으면 Client 개발자는 사용하려고 하는 개체에 대한 세부사항을 아주 세밀하게 알고 있어야 한다. Client 개발자의 머릿속이 이런 구현 세부사항들로 넘처나게 되면 해결해야 할 비즈니스 문제를 집중해서 해결할 수 없다. 객체의 캡슐화 가치가 떨어지게되는것이다.
 
클래스나 연산이름을 지을때에는 수행 방법이 아닌 결과와 목적만을 표현해야 한다.
 
TDD 를 잠깐이라도 접해본적이 있다면 구현하지도 객체에 대해 Test code를 먼저 작성하고나서 해당 객체를 구현해가는 과정을 거쳐본적이 있을것이다. 객체 구현보다 행위에 대한 Test를 먼저 작성하게 된다.
 
처음에는 당연히 이상하다는 생각을 할 수 있고 나 역시도 그랬다. 이런 과정이 귀찮긴 한번 따라해보면 client 개발자가 사용하기에 깔끔한 코드가 완성될 확률이 높다. 그리고 test code에 대한 품질을 신경쓰다 보면 메서드 이름도 client 개발자가 더 잘 이해할 수 있도록 변경해야겠다는 생각이 든다.

- Paint example

type Paint struct {
	v       float32
	r, y, b int
}

func NewPaint(v float32, r, y, b int) *Paint {
	return &Paint{
		v: v,
		r: r,
		y: y,
		b: b,
	}
}

func (p *Paint) paint(paint *Paint) {
	p.v = p.v + paint.v
	// TODO mix r,y,b component
}

func Test_Paint(t *testing.T) {
	yellow := NewPaint(100.0, 0, 50, 0)
	blue := NewPaint(100.0, 0, 0, 50)

	yellow.paint(blue)

	if 200.0 != yellow.v {
		t.Fatalf("expected: %f, but got: %f", 200.0, yellow.v)
	}
}
 
위의 예제에서 paint 연산의 이름을 보고 무슨 행위를 하는지 이해하기는 힘들것이다. 하지만 다행히도 Test 코드가 있어서 paint를 섞는 행위라고 쉽게 추측할 수 있다.
 
Client가 이해할 수 있도록 연산 이름을 mixIn 으로 변경해보자.
 
func (p *Paint) mixIn(paint *Paint) {
	p.v = p.v + paint.v
	// TODO mix r,y,b component
}

func Test_Paint(t *testing.T) {
	yellow := NewPaint(100.0, 0, 50, 0)
	blue := NewPaint(100.0, 0, 0, 50)

	yellow.mixIn(blue)

	if 200.0 != yellow.v {
		t.Fatalf("expected: %f, but got: %f", 200.0, yellow.v)
	}
}
 
 

'Concepts > SW Design' 카테고리의 다른 글

DDD - Assertion  (0) 2022.10.22
DDD - Side effect free function  (0) 2022.10.22
DDD - Specification  (0) 2022.09.25
DDD - 불명확한 개념  (0) 2022.09.19
DDD - Repository  (0) 2022.09.18

댓글