사다리 생성 미션을 마무리하면서 사용했던 코드들을 정리해 보자.

원시값 포장

이번 미션에서 제일 많이 고민했던 부분이다. Player 클래스의 이름을 갖고 있는 String을 Name으로 포장하였다.
다음 두 코드를 보고 차이를 보자. 생성자에서 포장된 객체를 받는 것이 좋을까 원시 값을 받아서 생성자에서 포장해 주는 것이 좋을까?

public class Player {

    private Name name;    

    public Player(Name name) {
        this.name = name;
    }
}

생성자에서 포장된 객체를 받는 것은 도메인의 코드가 깔끔해 보인다.

public class Player {

    private Name name;    

    public Player(String name) {
        this.name = new Name(name);
    }
}

이는 도메인의 코드가 조금은 지저분해 보일 수 있다. 처음에는 무조건 "포장된 객체가 다른 계층으로 돌아다니는 것이 안전하다"라고 생각해서 포장된 객체를 전달받고, 전달했다. 어떤 방법이 맞는지 생각해 보기 위해 원시값 포장을 왜 하는지 생각해 보자.
원시값 포장은 객체의 책임을 분리하기 위해서 사용한다. Name에 관한 로직을 Name클래스에서 담당하도록 책임을 분리하는 것이다.
이러한 이유로 사용하는데 다른 계층에 원시값으로 돌아다녀도 상관이 없다! 다른 계층으로 돌아다닐 때는 Name의 값이 필요한 것이고 Name에 대한 로직을 사용할 때는 도메인 내에서 사용하기 때문에 원시값으로 돌아다녀도 상관이 없는 것 같다.

로직의 실행 위치

만약 Name을 검증하는 로직이 추가되어 Name의 생성자에서 validate() 메서드를 실행하고, 잘못된 값을 입력하면 예외를 던진다고 해보자. Name은 Player가 생성될 때 의미가 있다. 따라서 잘못된 Name에 대한 예외도 Player가 생성될 때 발생하는 것이 맞다. 따라서 생성자에서 포장을 하는 방식이 더 좋아 보인다.

테스트하기 좋은 코드

테스트의 관점에서 살펴보자.
test1은 포장된 객체를 전달받는 방식, test2는 원시값을 받아 생성자에서 포장하는 방식이다.

@Test
void test1() {
    Player player = new Player(new Name("maco"));
}

test1의 방식은 테스트를 할 때 Name객체를 직접 생성해서 넣어주어야 한다.

@Test
void test2() {
    Player player = new Player("maco");
}

test2의 방식은 이름값만 넣어주면 된다.
그래서 어떤 방법이 더 좋을까? test1은 Player를 테스트하는데 Name까지 알고 있어야 한다. 알아야 하는 정보가 더 많기 때문에 복잡하다고 할 수 있고 아는 다른 개발자들을 힘들게 할 것이다. 따라서 test2의 방식, 원시값을 전달받아 생성자에서 포장해 주는 방법이 나은 것 같다. 항상 이 방법이 맞다고 할 순 없을 것 같다. 상황에 따라 원시값 포장의 의미를 잘 생각하면서 상황에 맞게 사용하자!

'회고 > 우아한테크코스' 카테고리의 다른 글

2023.03.02 일일 회고  (0) 2023.03.03
2023.02.28 일일 회고  (0) 2023.03.01
2023.02.23 일일 회고  (1) 2023.02.24
2023.02.22 일일 회고  (0) 2023.02.23
2023.02.21 일일 회고  (0) 2023.02.22

+ Recent posts