Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

생성자 코드에 validation코드도 넣을 수 없을까? #22

Open
qhals321 opened this issue Apr 17, 2021 · 7 comments
Open

생성자 코드에 validation코드도 넣을 수 없을까? #22

qhals321 opened this issue Apr 17, 2021 · 7 comments

Comments

@qhals321
Copy link
Contributor

조엔 글을 읽으면서 저도 이 부분에 대해 다른 분들의 의견이 궁금하더라고요~!!!
"생성자 코드에 validation코드도 넣을 수 없을까?"

제 생각부터 이야기하면 예고르 형님의 말투를 따라하면 "넣어야 합니다!!"
엘레강트 오브젝트 책에는 "객체를 인스턴스화하는 동안에는 객체를 만드는 일 이외에는 어떤 일도 수행하지 않습니다."라는 글이 있습니다!
객체는 생성할 수 있을 때만 생성해야한다고 생각합니다. 만일, 잘못된 값으로 만들어달라고 부탁하면 바로 "이 재료로는 못 만들어줘!" 라는 메시지를 클라이언트에게 표현해야하지 않을까 생각합니다.
만일 잘못된 값으로 넣었는데 사용하는 시점까지 미룬다면 대학교때 팀프로젝트 본인 이름 올려놓고 발표 당일에 "이거 못해!!"라는 의미처럼 느껴지더라고요...
그리고 예외를 발생하는 것을 계속 미룬다면 예외 trace를 살펴볼 때도 많이 힘들 거라고 생각들어요!
즉, 객체 생성자 안에는 validation 코드는 들어가도 된다! 라고 생각드네요.

다른 분들의 의견은 어떤가요???
좋은 의문점 고마워요 조엔!!

@yjksw
Copy link
Contributor

yjksw commented Apr 17, 2021

#11
비슷한 의문점에 씨유가 의견을 남긴 것 첨부합니다!!

@qhals321
Copy link
Contributor Author

qhals321 commented Apr 18, 2021

씨유도 같은 의견이군여! 그런데 또 궁금한 것이 있어요!
엘레강트 오브젝트에서는 숫자인 자리에 String 형태로 받아도 숫자로 변환하지 않고 그대로 String으로 간직하게 되니까 아예 숫자값 유효성 검사가 힘들잖아요?
예를 들어 LottoNumber는 1에서 45 사이에 숫자가 필요하다라고 할 때 인자 값을 StringLottoNumber라는 구현체를 통해 숫자를 String 폼으로 받아오고 lazy하게 변환을 시킨다고 하면 결국 1에서 45 사이에 숫자인지 확인하기 위해선 결국 사용할 때 확인할 수 밖에 없는 구조인데...
이럴땐 validation이 어떻게 가능할까요..? 생성자에서 validation하고 싶다면 String으로 넘어온 값을 int로 변경해서 유효성을 검사할 수 밖에 없는데... 이렇게 유효성을 검사하면 결국 lazy의 의미가 사라지고..?!

@wannte
Copy link
Contributor

wannte commented Apr 18, 2021

@qhals321 저도 늦게남아 읽으면서 저도 이 부분에 대해서 고민이 되네요!
validation자체를 하기위해 parseInt의 과정이 필요한..

로또 미션에서 게임 머니(양수)값을 입력한느 동시에 잘못된 입력이라 표시가 되야한느데, 이를 사용하는 시점에서 에러가 발생하면, 문제가 될것 같네요..

@Livenow14
Copy link
Contributor

Validation만을 위한 인터페이스가 있으면 어떨까요? (인터페이스 주입 -> 검증된 객체 반환 )
Validation을 구현하는 클래스에 따라 행동을 다르게 둔다면, 괜찮을거 같기도하고,

@sihyung92
Copy link
Contributor

sihyung92 commented Apr 18, 2021

저두 무조건 pure한 생성자는 과유불급이라 생각합니다~~

생성자가 복잡해지면 안 된다는 내용엔 100% 동의하지만

할당할 property의 validate만큼은 객체가 정말 일급시민 이라면 수행해야할 의무 아닐까?? 생각해요ㅎㅎ

역할을 다 하라고 요구받았을 때 "실은 내가 할당을 잘 못 받았어..ㅎㅎ" 라고 징징거리는 객체는 우아하지 않네요

@seovalue
Copy link
Contributor

seovalue commented Apr 18, 2021

이펙티브 자바 아이템 49. 매개변수가 유효한지 검사하라 파트에 이러한 내용이 있네요.

메서드와 생성자 대부분은 입력 매개변수의 값이 특정 조건을 만족하길 바라며, 이러한 제약은 반드시 문서화해야하며 메서드 몸체가 시작되기 전에 검사해야한다. 생성자는 "나중에 쓰려고 저장하는 매개변수의 유효성을 검사하라"는 원칙의 특수한 사례로써 생성자 매개변수의 유효성 검사는 클래스 불변식을 어기는 객체가 만들어지지 않게 하는데 꼭 필요하다.

이렇듯 매개변수가 유효한지는 메서드 몸체가 시작되기 전에 검사해야한다고 하는데요, 그 이유로는 다음과 같은 것들을 들었어요.

  1. 오류를 발생한 즉시 잡지 못하면 해당 오류를 감지하기 어려워지고, 감지하더라도 오류의 발생 시점을 찾기 어려워진다.
  2. 잘못된 값이 넘어왔을 때 즉각적이고 깔끔한 방식으로 예외를 던질 수 있다.
  3. 매개변수 검사를 제대로 하지 못한다면 어떠한 객체를 이상한 상태로 만들어 놓았기에 미래의 알 수 없는 시점에서 이 메서드와는 관련없는 오류를 발생할 수 있다. (실패 원자성을 어기는 결과를 낳을 수 있다.)

그리고 또, 이펙티브 자바에서는 이 책(엘옵)의 주장을 메서드 몸체 실행 전에 매개변수 유효성을 검사해야한다는 규칙의 예외로서 인정하고 있는데요, 그 이유는 다음과 같아요.

  1. 유효성 검사 비용이 지나치게 높거나 실용적이지 않을 때
  2. 계산 과정에서 암묵적으로 검사가 수행될 때 (ex. Collections.sort의 경우 객체 리스트를 정렬하는 메서드인데, 리스트 안의 객체들은 모두 상호 비교될 수 있어야하며 정렬 과정에서 이 비교가 이루어지므로 리스트 안의 모든 객체가 상호 비교할 수 있는지 검사해 볼 필요는 그닥 없다.)

아무튼 주절주절했지만 결론은 생성자 내부에서 매개변수에 대한 유효성 검사를 실행하되 그 비용이 너무 크다면 이후에 맡길 수 있지 않을까..? ㅋㅋㅋ

@bperhaps
Copy link
Contributor

재미있는 관점을 하나 소개해 보도록 하지.
빠른 실패 관점으로 봤을땐 어떨까?
요즘 프로그래밍 페러다임이 빠른 실패를 중요하기 여기지. 이를 따라기 위해서는 당연히 생성자 검증이 필요하지 않을까?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants