분류 전체보기 378

도메인의 성장과 Service 계층의 관계

도메인이 빈약했을 때는 Service가 필요했지만, 도메인이 풍부해지면서 Service는 자연스럽게 사라졌다 ! 1,2주 차에는 미션과 요구사항, 도메인이 간단해서 늘 협력메시지 시나리오 흐름과 객체들의 책임과 역할을 모두 설계한 뒤 진행을 했지만 이번 3주차 로또는 요구사항이 많고 초기 설계하는 과정에서 너무 많은 역할과 로직들이 떠올라 유즈케이스와 기능구현목록 분석후 간단한 설계후 진행하였다. 하지만 이러한 원인 때문인지 미션 구현과 리팩토링 과정에서 많이 헤매었고, 특히 리팩토링을 하는 과정이 힘들었다.이러한 과정 속에서 service 계층이 있었다가 최종적으로는 제거가 되었다. 우선 1,2주차에 비해 복잡하고 요구사항이 많아진 만큼 웹 애플리케이션 개발 경험을 떠올리며 Service 계층이 필요..

책임과 무한 리팩토링(정보 전문가 vs 단일책임원칙)

3주차 미션을 진행하며 기존에 알고 있던 설계 원칙들간의 모순(?) 충돌(?)과 트레이트 오프에 대해 고민하며 엄청난 리팩토링을 하게 되었다.대부분의 나의 고민은 '책임'에 대한 시선이었다 !결론적으로 책임을 바라보는 시선을 다르게 가지니 초반에 가진 모순에 대해 해결이 되는것 같다 !하지만 이 또한 나의 편협한 시선일 뿐 이후 코드리뷰나 미션을 진행하며 언제든 바뀔 수 있다고 생각한다.하지만 현재로서 나의 고민과 고민과정에서 어떻게 지금의 책임을 바라보는 시선을 하게 되었는지 흐름을 정리하고 자한다. 🤔 첫 리팩토링 후 만든 LottoResult기본적인 기능 구현을 마친 뒤 리팩토링을 위해 다시금 코드를 하나씩 살펴 보았다. 그 과정에서 WinningStatistics에서 통계가 아닌 '결과'라는..

검증의 책임 톺아보기

2주차 자동차 경주 미션을 진행하면서 코드 리뷰를 통해 "검증의 책임"에 대한 피드백을 받고 여러 의견을 주고 받았다.처음에는 단순히 "검증 로직을 어디에 둘까?"의 문제라고 생각했지만, 파고들수록 훨씬 깊은 설계 철학의 문제였다.2주차의 실수: Validator를 분리했지만...// Controller에서 검증public class RacingController { private final CarNameValidator carNameValidator; private List readAndValidateCarNames() { List carNames = inputView.readCarNames(); carNameValidator.validate(carNa..

불변객체 == Record 가 아니다 🙅

3주차 로또 미션을 진행하며 일급 컬렉션, Value Object, 불변성에 대해 깊이 이해하게 되었다.그 과정에서 "BonusNumber과 같은 VO를 Record로 바꾸면 더 간결하지 않을까?"라는 생각이 들었고, 실제로 시도해봤다.결과는 실패였지만, 이 실패를 통해 얻은 인사이트가 있다."모든 불변 객체라고 record로 바꾸면 안된다 !" Record로 바꾸고 싶은 이유package lotto.domain.winning;import static lotto.exception.ErrorMessage.BONUS_NUMBER_DUPLICATED;import static lotto.exception.ErrorMessage.BONUS_NUMBER_OUT_OF_RANGE;import lotto.domain.L..

도메인 모델과 VO, 일급 컬렉션 톺아보기

3주차 로또 미션을 진행하며 일급 컬렉션, Value Object, 불변성에 대한 개념과 실제 적용 및 관계에 대해 혼동이 와서 다시 한번 정리해 보고자한다. 우선 불변 객체와 VO, 도메인 모델간의 개념에 대해 혼동이 있었다 ! Value Object란?값으로 정의되는 작은 객체로서 동일한 값을 가지면 동일한 객체로 간주되며, 식별자가 없고 불변이다.불변성 (Immutable)public class BonusNumber { private final int value; // final - 변경 불가 public BonusNumber(int value) { this.value = value; } // setter 없음!}값 동등성 (Equality by V..

불변성의 오해와 진실 톺아보기

3주차 로또 미션을 진행하며 일급 컬렉션, Value Object, 불변성에 대한 개념과 실제 적용 및 관계에 대해 혼동을 느꼈다. 그 기본인 불변성에 대해 final이 있으면 뭔가 아 ! 불변성을 얻었다 ! 싶은 생각이 충동적으로 들었다. 하지만 절대 절대 아니며 오히려 이런 잘못된 오해가 모든 혼란을 가져온다 ! 그로 인해 혼란 스러운 점과 실제 생성 방법 예시들을 정리해 보고자 한다 불변성 (Immutability)객체가 생성된 이후 그 상태를 변경할 수 없는 것을 의미// ❌ 가변 객체public class MutableLotto { private List numbers; public void addNumber(int number) { numbers.add(numbe..

ErrorMessage Enum 관리 및 간소화 시도

프리코스 1주차와 2주차 미션을 진행하고 코드리뷰를 통해 3주차에서는 ErrorMessage Enum 을 도입하게 되었다.도입 후 확실한 장점을 느끼게 되어 이에 대해 정리해 보고자 한다. 1,2주차에서는 ErrorMessage를 상수로 해당 클래스 내부에서 선언해서 사용을 했지만 테스트코드에서 메시지 내용까지는 검증하지 않았다. 각 클래스가 아닌 다른 부분에서 검증을 해야하는 경우 상수를 테스트코드 내부로 옮기거나 직접 타이핑을 했어야 했지만 매번 패키지들을 넘나들며 에러 문구를 확인하고 수정했어야 했다.또한 한줄 한줄 매번 복사 붙여넣기 혹은 타이핑 하는 과정에 꽤나 피로감이 많게 느껴졌다 .또한 3주차 미션 요구사항에 아래와 같은 요구 사항이 추가되어 더욱 Enum을 사용해ErrorMessage를..

[우아한테크코스 8기] 프리코스 2주차 회고

ㅇㅇㅇ 시작하며 2주차 역시 상당한 몰입을 경험했다 !요즘 매일 아침 눈 떠서 미션에 대한 고민을 하고 잠들기 전까지 미션에 대한 생각을 하며 눈을 감는다..이번 주 꿈에만 벌써 3번가량 프리코스 미션에 관한 꿈을 꿀 정도로 요즘 나의 머릿속은 프리코스 미션에 대한 생각뿐인것 같다 ㅋㅋㅋ 너무 신기하다..우아한테크코스 운영진분들 덕분에 무료로 너무 좋은 교육 프로그램을 통해 즐기며 폭발적인 성장을 할 수 있는 기회를 주셔서 늘 너무 감사한 마음이 든다. 또한 작년과 달라진 넘이 점점 느껴졌다.조영호 저자님의 객체지향의 사실과 오해, 오브젝트 도서를 접한 이후로 객체로 바라보는 시야가 점차 생긴것이 가장 큰 이유라고 생각된다.그 덕분에 1주 차가 객체지향적 사고의 시작이었다면, 2주 차는 설계와..

테스트 코드로 완성하는 자동차 경주: Callback과 Strategy의 시너지

여러객체의 협력이 핵심이고, Mock이 3개 이상 필요하며, 흐름 제어가 주 책임인 RacingGame은 통합 테스트가 적합하다는 확신은 들었다.하지만 막상 테스트 코드를 작성하려하니 막막했다.어디서부터 시작을 해야할지뭘 검증해야할지이동 전략은 어떻게 제어할지 등등 이론은 잘 정리했지만 막상 실제로 타이핑을 하려고 하니 턱 막혔다. 일단 생각 나는대로 작성해보자 !@Testvoid racingGameTest() { // given List cars = new ArrayList(); cars.add(new Car("pobi")); cars.add(new Car("woni")); cars.add(new Car("jun")); MoveStrategy strategy ..

단위 테스트 vs 통합 테스트: 어떤 테스트를 작성해야 할까?

CarFactory와 RacingGame의 테스트 코드를 작성하면서 계속 고민이 되었다."이 클래스는 테스트를 작성해야 하나?" "작성한다면 단위 테스트? 통합 테스트?" "이거... 테스트해야 하나? 너무 단순한데...?""테스트한다면 어떻게 해야 하지?"이 고민을 시작으로 단위 테스트와 통합 테스트에 대해 깊이 공부하게 되었다. 테스트의 진짜 목적은 무엇인가?처음에는 "테스트는 버그를 찾는 거야. 모든 클래스, 모든 메서드를 테스트하면 버그가 없겠지!"그래서 이런 테스트를 작성하려고 했다.@Testvoid carFactoryTest() { CarFactory factory = new CarFactory(); List cars = factory.createCars(Arrays.asList("..