study/우아한테크코스

우아한테크코스 7기 프리코스 3주 차 회고

듀2 2024. 11. 4. 17:38

벌써 프리코스 3주 차도 마무리를 하고 있다.

로또 역시도 TDD 스터디를 하면서 한 번 구현해 보았던 프로그램이지만, 다시 구현하려니 새롭게 다가왔다.

그리고 프리코스 1주 차, 2주 차를 겪으면서 배운 것이라던가, 새로 확립한 구현 규칙들을 적용하고 프로그래밍에 임하는 느낌이 색달랐다.

 

웬만하면 매일 매일의 회고, 고민의 순간들을 적어두려고 노력 중이지만 생각보다 쉽지 않다.

 

일급 컬렉션의 활용

2주 차의 자동차 경주를 구현하며 자동차 객체를 관리하는 Cars 클래스를 만들고, 제대로 활용하지 못했던 것 같은 느낌을 지울 수 없었다.

특히 List 인터페이스가 주는 장점을 일급 컬렉션으로 관리하면 사용하지 못한다는 느낌을 받았는데, 내가 활용하지 못하고 있는 것이었다.

모른다는 걸 몰랐다가 알게 되었다. 메타 인지의 순간!😎

그래서 일급 컬렉션에 대해 더 찾아보고 공부했는데, 컬렉션을 관리할 때 Iterable 인터페이스를 구현하면 컬렉션 인터페이스의 장점들을 모두 활용할 수 있었다.

 

정적 팩토리 메소드 사용

TDD 스터디를 할 때부터 정적 팩토리 메서드를 도대체 왜 사용하는 것인지 이해할 수 없었다.

Java 기초부터 객체의 생성은 new 라고만 배워왔는데, 정적 팩토리 메서드를 사용하는 것의 이점이 무엇일까 답을 얻지 못하여 계속 사용하지 못하고 있었다.

그런데 2주 차 자동차 경주 때 코드 리뷰를 진행하며, 정적 팩토리 메소드를 사용하여 구현한 코드를 보게 됐는데, 코드

가 술술 읽혔다.

그리고 그 분께서 내게 남겨준 코드 리뷰에서 'Car 객체의 생성 부분은 Cars 안에서 수행하는 것은 어떨까요?'라는 내용이 있었다.

정말 많이 배웠다!

 

곰곰이 생각해보니 정적 팩토리 메서드를 사용하면 객체 생성을 객체 내부에서 수행하고, 사용과 분리할 수 있겠구나 생각이 들었다.

계속 컨트롤러에서 객체를 생성하고 있다는 느낌을 지울 수 없었는데, 장점을 체득하니 정적 팩토리 메서드를 사용해보고 싶다고 생각했다.

추가로, https://tecoble.techcourse.co.kr/post/2020-05-26-static-factory-method/ 테코블 블로그 역시 도움이 많이 되었다.

 

전략 패턴

디자인 패턴에 대해서도 공부하고 싶어서 헤드퍼스트 디자인 패턴이라는 책을 읽어 보았는데, '전략 패턴'이 가장 처음에 나오는 패턴이었다.

정처기 공부할 때는 디자인 패턴이 너무 안 외워져서 진짜 싫었었는데..ㅎ

읽다 보니 2주 차 자동차 경주에서도, 3주 차 로또에서도 랜덤 숫자를 생성하는 경우에 NumberGenerator 인터페이스를 생성하고, 여러 방면으로 활용할 수 있겠다는 생각을 했다.

그렇지만 아직 스스로 디자인 패턴에 대한 이해도나 활용도가 낮다고 생각되어 추후 리팩토링 할 기회가 주어진다면 활용해 보도록 기록만 남겨 두어야겠다.

헤드퍼스트 디자인 패턴 책을 더 읽어보고 활용할 수 있도록 공부해야지!

 

DTO의 사용

DTO 역시도 정적 팩토리 메서드와 동일하게 스터디 때부터 도대체 왜 사용하는 거지?라는 의문을 가지고 있었다.

Data Transfer Object, 말 그대로 데이터를 운반하기만 하는 객체이다.

이 역시도 코드 리뷰를 하면서 답을 찾을 수 있었다. 이래서 코드 리뷰를 하는 건가?🤔

MVC 패턴은 모델과 뷰는 서로를 모르고, 컨트롤러가 중간에서 서로에게 데이터를 전달해 주는 패턴이다.

DTO는 뷰에서 모델의 비즈니스 로직을 모르도록 데이터만 전달하는 객체인 것이다.

하지만 나는 DTO를 활용하게 된다면 컨트롤러가 하는 일이 너무 많아지고, DTO를 사용하지 않더라도 뷰에서 필요한 출력 정보를 모델에서 캡슐화를 어기지 않고 전달만 잘해준다면 괜찮다고 생각했다.

그래서 이번 주차에도 DTO를 사용하지 않고 구현했다.

DTO 사용도 정적 팩토리 메서드처럼 필요성이 느껴질 때 사용하게 되지 않을까?

 

유효성 검증

유효성 검증은 프리코스가 시작될 때부터 계속 고민해 왔던 부분이다.

입력값에 대한 유효성 검증과 객체의 유효성 검증 부분이 겹칠 때 어떻게 검증할지 나름의 규칙을 세웠다.

뷰를 프론트엔드 개발 영역으로 생각하고, 뷰에서도 정규 표현식을 사용해 일부 유효성 검증을 진행한다.

모델에서 진행하는 유효성 검증은 백엔드 개발 영역으로 보고, 모델에서도 필요한 유효성 검증을 진행한다.

2주 차까지 고민했던 부분들을 토대로 나만의 검증 규칙을 세우니 더 빠르게 구현할 수 있었다.

1주 차, 2주 차까지는 유효성 검증 클래스를 별도로 두어 관리했는데, 이렇게 규칙을 세웠더니 뷰는 뷰 객체에서, 모델은 각 모델의 객체에서 유효성 검증을 담당하는 것이 더 맞겠다는 판단이 들어 객체 내부에서 유효성 검증을 진행하게 됐다.

 

static method의 사용 줄이기

뷰와 관련된 클래스인 InputReader, OutputWriter, InputView, OutputView 클래스는 무분별한 객체 생성으로 인한 메모리를 줄이기 위해 private으로 객체 생성을 막고 static method를 사용했었는데, 프리코스 커뮤니티에 static method를 사용할 때 알고 있어야 할 점들에 대한 글이 올라왔다.

글을 읽고 나는 왜 static method를 사용했는가 생각해 보았는데, 어차피 private으로 객체 생성을 막아 두었으니 무분별한 객체 생성은 없을 것이고, 오히려 static 영역을 사용하는 것이 메모리에 더 안 좋지 않을까?라는 생각을 하게 됐다.

그래서 확장 가능성을 열어 모두 객체로 만들고, 객체의 장점인 상속을 활용하여 InputReader, OutputWriter의 method를 protect로 제한, InputView, OutputView가 각각 InputReader, OutputWriter를 상속하여 부모 클래스의 메서드를 사용할 수 있도록 활용해 보았다.

이렇게 하나씩 더 객체 지향의 장점을 사용해 보면서 더더욱 객체 지향 개발자가 된 듯한 느낌을 받는다.🤩

제주도에서 만난 객체..?

 

Enum의 사용

3주 차 미션의 요구 사항 중 Enum을 적용하라는 내용이 있었다.

지금까지 나는 범용으로 사용하는 에러 메시지나, 숫자 제한 등을 static으로 관리하고 있었는데, Enum을 활용하라는 말에 범용 메시지가 아닌 다른 곳에서 Enum을 활용할 수 있는지 생각해 봤다.

Enum은 미리 정의된 상수들의 집합인데, 단순한 집합이 아니라 상수들과 관련된 상태나 행위를 관리할 수 있고, 상수 데이터들 사이에 어떠한 관계가 있을 때 유의미하다.
이번 주차에서는 당첨 통계와 관련된 값들을 Enum으로 관리하면 좋겠다고 생각했다.
Enum을 적용하면서 당첨 결과를 관리할 때 EnumMap을 활용하는 것에 대해서도 공부했다.
이렇게 활용해 보니 Enum을 왜 사용하는지 더 체득할 수 있었다.

 

단위 테스트

입력값과 역할이 명확한 모델에 대한 단위 테스트는 어느 정도 감을 잡았다고 생각한다.
특히 피드백으로 주신 학습테스트를 통해 JUnit 학습하기.pdf 파일이 단위 테스트에 대한 감을 잡는데 도움이 많이 되었다! 우테코 최고최고👍🏻
단위 테스트를 구현할 때 그리 오랜 시간이 걸리지 않는다.
역할을 세세하게 자르지 않은 모델에 대한 테스트가 어렵다고 느껴진다. 말 그대로 '단위' 테스트가 아니기 때문이겠지!
TDD를 더 연습해야겠다는 생각을 했다.
하지만 이번 프리코스의 목표를 잊지 말자!
먼저 기본적인 기능을 구현한 돌아가는 쓰레기를 만들고, 리팩토링과 테스트는 그 이후다!
조급해하지 말자.

 

함수형 인터페이스

사용자가 올바르지 않은 입력값을 입력했을 때, 예외 처리하고 예외 문구를 출력한 뒤 그 부분부터 재입력을 받도록 구현해야 했다.
처음에는 try ~ catch 구문으로 재입력받아야 하는 모든 메서드를 감싸고 재귀 함수를 호출했는데, 중복이 너무 꼴보기 싫었다!!
그래서 좀 구글링을 해보니 자바도 함수형 인터페이스를 지원하니, 이를 활용하면 된다고 한다.
https://inma.tistory.com/151 블로그를 참고했다.
람다가 처음에는 참 가독성이 좋지 않다고 생각했는데.. 스트림처럼 점점 익숙해지고 있는 것 같다!

 

3주 차도 완료!! 1주밖에 안 남았다니 말도 안돼🥲

 

최대한 객체 지향적으로 생각하려고 하고, 모델에게 메시지를 던지려고 하고, 모델과 뷰가 서로를 모르게 하려는 데에 집중했다.
여전히 부족한 점이 많겠지만, 프리코스를 통해 알아 가는 것도 많고 성장하고 있다는 것을 조금은 느끼고 있다.
특히 의문을 가지고 있었던 부분들에 대해 구현을 통해서 혹은 코드리뷰를 통해서 직접 체득하여 해결하는 방식이 참 좋다.

꼭 코드리뷰에 참여하지 않더라도, 한 가지 문제에 대해 여러 사람의 코드를 볼 수 있다는 것이 좋은 것 같다.
다음 주는 어떤 미션이 나올까?
마지막 프리코스 미션인 만큼 더 고민하고, 생각하고, 공부해야지!👏🏻

 

3주 차 프리코스 코드 레포지토리:

https://github.com/ljhee92/java-lotto-7/tree/ljhee92

728x90