해결된 질문
작성
·
82
·
수정됨
0
의문이 드는게 어디냐면 calc에서
Money.won(
(long) Math.ceil( money.doubleValue )
)
을 통해서 Money를 만들어내잖아요.
일단 설명의 용이성을 위해 static won이나 메소드 doblueValue 생략하신건 문제 없습니다만..
1. money.doubleValue는 환률과 무관한 컨텍스트로 토해지는 값인거 같은데
2. 그 값을 바탕으로 won을 통한 Money를 만들어도 되는거냐
싶은 생각이 너무 들어요 ^^;
아예 값과 참조에 집중하려면 Money.value(long)같은걸로 했어야 하지 않았나 싶은...
실제 이어지는 ceil의 메소드화에서는 아예 won의 도움없이 Money를 숫자기반으로 만들기도 했구요.
답변 3
2
조금 더 구체적으로 질문해 주시면 좋겠습니다. 🙂
강의에서는 환율에 대한 요구사항이나 다른 통화를 처리해야 한다는 국제화에 대한 제약사항을 언급하지 않은 상태에서 한국에 대한 원화를 처리하는 값 객체로 구현한 상태인데요
질문에서 궁금한 부분에 대해 답변을 주시면 제 의견을 말씀드릴게요.
환율에 대한 요구사항이 없는 상황에서(currency라는 속성도 없구요) 환율과 무관한 won이라는 static 메서드를 사용하는게 어떤 문제가 있을까요?
Money.doubleValue를 이용해서 won을 통해 Money를 만들었을 때의 구체적인 문제가 무엇이라고 생가하시나요?
Money.value(long)라는 메서드를 사용하는게 값과 참조에 더 집중하게 만든다고 생각하시는 이유가 무엇일까요?
ceil 메서드에서 won 메서드 대신 new Money를 사용한 것은 일관성 측면에서 제가 놓친것 같지만, 일관성을 제외하고 new Money를 직접 호출했을 때의 문제점이 어떤 것일까요?
아마 질문 안에 담지 않으신 Hika Maeng님이 여러가지 가정이 있으실것 같은데요.
제가 질문하신 내용에서 이런 부분을 정확하게 이해하지 못한 상태라 답변을 드리기 어렵습니다.
이 부분에 대해 답변 주시면 해당 문제점에 대한 제 생각을 말씀드릴 수 있을것 같아요. 🙂
이 부분은 오해하신게 맞습니다.
Money의 생성자를 보시면 가시성이 default이기 때문에 패키지 외부에서 직접 new Money를 호출하실 수 없기 때문입니다.
(정확하게는 private으로 하는게 맞겠지만 제가 JPA 강의를 할 때 사용하는 예제를 그대로 가져오다 보니 default인 상태네요. 수정 못한게 많네요. ㅠㅠ)
Money(BigDecimal amount) {
this.amount = amount;
}
예제 코드가 작아서 같은 패키지에 넣었지만 제가 강의했던 다른 코스를 들으셨기 때문에 Money 클래스를 별도의 패키지에 위치시켜 놓는 걸 아실 수 있으실 겁니다(들으셨던 DDD나 JPA 강의 예제를 참고하시면 될것 같습니다).
결국 외부에서 Money를 생성하는 방법은 정적 메서드 wons를 호출하는 방법밖에 없기 때문에 오히려 wons라는 메서드는 다른 통화의 금액을 생성할 수 없다는 클래스 본연의 제약사항을 명확하게 표현하고 있습니다.
차라리 wons와 dollars 메서드가 같이 있다면 말씀하신게 맞지만 wons 하나만 있고 패키지 외부에서 직접 생성자에 접근할 수 없는 상황에서 이렇게 예상하시는게 오히려 부자연스럽게 느껴집니다.
강의 어디에서도 통화나 환율에 대한 요구사항이 없음에도, 그리고 값 객체라는 강의 본연의 주제와는 무관한 주제인 통화에 대한 선입견을 가지고 존재하지 않는 허수아비를 때리고 계십니다.
차후에 정말 통화가 필요해서 currency 속성을 추가하고 dollars 메서드를 추가한다고 해도 기존 클라이언트를 수정할 필요가 없기 때문에 현재 코드는 문제가 없습니다.
마찬가지로 외부에서 직접 new를 호출하지 않기 때문에 내부에서 static 메서드를 사용하거나 new를 사용하는 부분을 사용하더라도 캡슐화 관점에서 큰 이슈는 없습니다.
앞 질문에서 말씀드린 것처럼 일관성 측면은 제가 놓쳤다고 말씀드렸지만 외부에 영향을 주지 않고 쉽게 수정이 가능하게 캡슐화됐기 때문에 이 부분이 큰 이슈는 아니라고 생각합니다.
마지막 질문 하나만 답해주시면 될것 같아요.
Money.value(long)라는 메서드를 사용하는게 값과 참조에 더 집중하게 만든다고 생각하시는 이유가 무엇일까요?
허수아비를 만들 필요가 없잖아요 ^^
저는 여전히 클래스명 자체가
Won 이 되던가 Money클래스의 모든 어휘에서 통화 컨텍스트가 빠져야한다고 생각해요.
Money.of 등 value든
아니면 클래스 자체가
Won이든
이건 제가 허수아비를 때리는 지 알려면 너무 많은 연대기를 알아야하잖아요.
아 그간 역사에서 Money는 통화개념을 쓰지 않으니 won을 보고 통화를 떠올리지마 라고 ^^
0
Money.of( long or double)
은 기본형을 Money로 감싼 거지만
Money.won( long or double)
은 원화 기준으로 Money의 밑값을 받아 생성한거죠.
근데 Money.won(
기존 Money를 단순 long or double로 만들어서
)
원 기반의 밑값으로 삼았다는 거죠.
괄호안의 Money는 환률 중립적인 doubleValue로 처리되었는데
아하, 어떤 부분이 이슈가 됐는지 이해가 되었어요. 🙂
강의를 들어보시면 환율에 대해 언급한 부분이 전혀 없습니다.
현재의 Money는 원화만 처리하기 위해 만들어진 클래스입니다.
toString() 메서드를 보시면 아래처럼 명확하게 원화로만 출력하고 있어요.
public String toString() {
return amount.toString() + "원";
}
doubleValue() 메서드는 환율과 무관하게 double 타입으로 타입 캐스팅하기 위해 사용한 것입니다.
Math.ceil이 double 타입을 요청하기 때문에 이 메서드를 사용한 것인데 longValue() 메서드를 사용해서 자동으로 타입 캐스팅 되는 경우와 동일하다고 보시면 됩니다.
아마도 Money가 여러 환율을 처리한다고 가정하셔서 이 부분을 혼동하신 것 같은데 현재의 Money 클래스는 원화만 처리하는 클래스로 구현되어 있습니다.
나머지 제가 드린 질문 세 가지에 대해서도 답글 달아주시면 답변 드리도록 할게요. 🙂
0
안녕하세요, 인프런 AI 인턴입니다. Hika Maeng님, 질문 주셔서 감사합니다.
Money 클래스를 사용하는 과정에서 개념적 의문을 가지신 부분에 대해 설명드리겠습니다. 특히, Money.won((long) Math.ceil(money.doubleValue()))
사용에 대한 걱정이 있으신 것 같습니다. 각 절차와 그 의미를 설명드리겠습니다.
money.doubleValue()
는 Money
클래스에서 금액을 double
값으로 변환하여 사용하는 함수로 이해할 수 있습니다. 이는 객체 내부에서 값을 수리적으로 처리하기 위해 변환하는 과정에서 발생합니다.
doubleValue
함수의 사용은, 환율이나 통화 컨텍스트와 상관없이 금액을 연산하기 위한 임시적인 변환일 뿐, 환율 적용의 문제는 아닙니다. 다만, 이 과정에서 통화 개념이 명시적으로 나타나다 보니 혼동이 있을 수 있습니다.
Money.won(...)
을 통해 새로운 Money
객체를 생성하는 것은 외부에서 환율이나 다른 영향 없이 내부 연산 단위를 기준으로 새로운 금액을 생성하는 과정입니다. 이런 방식은 금액의 불변성을 유지하고, 다양한 연산 후에도 일관성을 제공하는 데 목적이 있습니다.
Math.ceil()
은 double
값을 필요한 경우 올림하여 정수화하는 과정입니다. 이를 통해서 소숫점 아래의 금액을 올림하여 처리할 경우의 금액을 정확하게 계산할 수 있습니다.
Money.value(long)
과 같은 직접적인 정수 기반 메서드는 특정 로직에서 중간 변환 없이 빠르게 객체를 생성하는 방법이 될 수 있습니다.
디자인 관점: Money
클래스를 쓸 때는 코드 유지보수와 변경의 여지를 줄이기 위해, 변환 과정을 관리하는 helper 메서드를 적절히 활용하는 것이 좋습니다.
해당 부분과 관련된 강의 해설 링크나 관련 질문을 참고하여 도움이 되실 수 있을 것 같습니다:
이 답변이 Hika Maeng님께 도움이 되길 바라며, 추가 질문이 있으시다면 언제든지 말씀해 주세요. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 곧 지식공유자님께서도 추가적인 해설을 제공하실 것입니다. 감사합니다.
환율에 대한 요구사항이 없는 상황에서(currency라는 속성도 없구요) 환율과 무관한 won이라는 static 메서드를 사용하는게 어떤 문제가 있을까요?
우선 이건 won이라는 단어가 문제인거 같아요. 모든 메소드명이나 변수명은 커뮤니케이션을 하니까 아주 손쉽게 new Money(Currency.WON, long) 을 떠올리게 합니다. 그에 비해 이 Money는 won만 처리한다는 의도나 표현은 어디에도 없으니 제가 오해했다고 하기엔...
두번째는 처리가 된 거 같구요.
ceil 메서드에서 won 메서드 대신 new Money를 사용한 것은 일관성 측면에서 제가 놓친것 같지만, 일관성을 제외하고 new Money를 직접 호출했을 때의 문제점이 어떤 것일까요?
이것에 대한 직접적인 답은 아닌데 저는 한번 생성 메소드를 만들면 그걸 클래스 내부에서도 사용해야 한다는 주의입니다. DRY를 위반하니까요.
그래서 그 이후에 리팩토링된 코드 조차 메소드 내부에서 new Money를 하면 안되고 Money.won을 써야한다고 생각해요. 안그러면 생성에 대한 지식이 여러군데로 퍼져버리니까요.