오후 3시에 새로운 2주차 프리코스 과제를 받게 되었습니다.
1주차에서 저의 코드가 처참하다는 것을 알고 더욱 멋진 코드를 작성하기 위해 칼을 갈아 공부할 준비로 돌아왔습니다.
오늘은 지피지기를 하기 위해 다른 분들의 코드리뷰를 보고 배울 점을 파악하고 필요한 부분을 정리해서 빠르게 학습 해보려고 합니다.
저는 안타깝게도 디스코드에 코드 리뷰를 요청하였지만 아무 코드 리뷰를 받지 못하였습니다.
모든 코드를 Application.java
에 전부 넣어 파일 하나만 달랑 만들었기 때문일 것 같습니다.
Pull Request
의 README
를 굉장히 멋지게 작성해주신 분에 계셨는데 그 분의 구조를 파악하고 여러 과정을 학습하여 프로젝트에 넣고 배운 내용을 PR에 모두 꽉꽉 채을 계획을 세웠습니다.
코딩을 들어가기에 앞서 2가지의 주요 키워드를 가지고 공부를 먼저 해보았습니다.
우선 다른 분들은 모두 MVC 패턴으로 폴더 구조화를 하였으며, Controller
Model
View
가 나뉘어져 각자의 역할을 각자가 알아서 하도록 설계한 것을 볼 수 있었습니다.
저는 단순히 기능 구현에 초점을 맞추다 보니 Application.java
에 함수로 분리한 것이 전부였으며, 이외의 클래스는 ComparisionResult
라는 ball
과 strike
개수를 담고 있는 클래스 하나만 만들었습니다.
이후 프로젝트에서 MVC패턴을 꼭 도입하여 좀 더 구조화 된 모습으로 진행하려고 합니다!
저의 프로젝트에서는 Application.java
에 List
를 사용하여 구분되지 않도록 기능 구현에만 급급한 코드를 작성했습니다.
이는 추후 유지보수에 굉장히 비효율 적일 것이라는 것을 일급 컬렉션을 보고 알게 되었습니다.
일급 컬렉션은 리스트만을 매개변수로 가지며 private
으로 외부에 노출 시키지 않고 직접적인 접근이 불가능 하기에 변경 또는 조회에 민감하며 이 리스트에 대한 동작들은 함수화 하여 사용할 수 있도록 함으로써 일급 컬렉션 만의 역할을 할 수 있도록 하는 것이 매력적이였습니다.
이 또한 다음 프로젝트에서 꼭 도입하여 수정이 있더라도 편리하게 고칠 수 있도록 진행 해보려고 합니다.
1주차 프로젝트를 정말 대학교 과제하듯이 결과만 잘 나오는 것과 요구조건 충실에만 집중하다 보니 많은 것을 놓쳤고 아직도 제가 Java
에 대해서 많은 것을 알지 못한다는 것을 깨우치게 되어습니다.
특히 다른 사람들의 코드 리뷰를 보며 정말 멋지고 좋은 코드, 재사용 가능성이 높은 그런 코드를 작성해서 저 또한 코드 리뷰를 많이 해주고 받아보고 싶다고 생각하였습니다.
오늘 하루는 앞으로 모든 주차에 적용할 MVC 패턴
에 대해서 확실히 깊에 공부할 것입니다.
모델-뷰-컨트롤러(Model-View-Controller, MVC) 패턴은 어플리케이션을 세 개의 영역으로 분할하고 각 구성요소에게 고유한 역할을 부여하는 개발 방식입니다.
MVC 패턴을 도입하면 도메인(비지니스 로직) 영역과 UI 영역이 분리되어 서로에게 영향을 주지 않고 유지보수가 가능합니다.
보통 혼자 개발 할 때에는 분리 없이 작업을 하다보니 하나의 클래스의 함수를 로직을 바꾸게 되면 연관된 모든 것을 바꿔야 하는 불상사가 생기기 일수 였는데 MVC 패턴을 도입하면 해당 사항을 최소화 하여 사용자의 입출력 (View) 부분에 수정 사항이 생기면 DB와 상호작용 할 모델 (Model) 쪽은 상관 없는 일이니 딱 View 만 수정해주면 될 것 같습니다.
이러한 이점은 수정에 필요한 시간 비용을 줄여주어 생산성을 향상에 큰 효과를 가져올 것입니다.
Model
데이터(Data) 가공을 책임지는 컴포넌트(Component) 입니다.
모델은 어플리케이션의 정보 및 데이터를 나타내며, 다음과 같은 규칙을 가지고 있습니다.
View
사용자에게 보여지는 부분, 즉 유저 인터페이스(User interface)를 의미합니다.
MVC 패턴에서 여러 개의 뷰가 존재할 수 있으며, 모델에게 질의하여 데이터를 전달 받습니다.
뷰는 받은 데이터를 화면에 표시해주는 역할을 가지고 있습니다.
모델에게 전달받은 데이터를 별도로 저장하지 않아야 합니다.
사용자가 화면에 표시된 내용을 변경하게 되면 모델에게 전달하여 모델을 변경해야 합니다.
뷰는 다음과 같은 규칙을 가지고 있습니다.
Controller
모델과 뷰 사이를 이어주는 브릿지(bridge) 역할을 의미합니다.
모델이나 뷰는 서로의 존재를 모르고 있습니다.
변경 사항을 외부로 알리고 수신하는 방법만 있습니다.
컨트롤러는 이를 중재하기 위한 컴포넌트입니다.
모델과 뷰에 대해 알고 있으며 모델이나 뷰로부터 변경 내용을 통지 받으면 이를 각 구성 요소에게 통지합니다.
사용자가 어플리케이션을 조작하여 발생하는 변경 이벤트들을 처리하는 역할을 수행합니다.
컨트롤러는 다음과 같은 규칙을 가지고 있습니다.
유지보수
처음 설계부터 탄탄하게 진행한 시스템이라도 유지 보수를 시작하게 되면 기능간의 결합도가 증가하여 하나의 수정이 다른 비지니스 로직에 영향을 미쳐 의도치 않은 버그를 유발할 수 있을 것입니다.
디자인 패턴은 이러한 개발 과정에서 마주하는 문제들은 해결하기 위한 방법들 입니다.
선배 개발자 분들께서 이런 문제점을 해결하기 위해 UI 시스템을 위한 책임을 기준으로 3개의 핵심 컴포넌트 모델, 뷰, 컨트롤러로 나누었습니다.
각 컴포넌트가 자신의 수행 결과를 다른 컴포넌트에게 전달하는 프로그래밍 방식으로 결합도를 낮췄습니다.
시스템 유지보수 시에도 특정 컴포넌트만 수정하면 되기 때문에 보다 쉬운 시스템 변경이 가능합니다.
단순히 함수화, 싱글톤 같은 Java 디자인 패턴만 적용 하는 것이 아닌 이러한 구조를 만듦으로써 많은 이점이 있음을 이론적으로 알게 되었고 실전 코딩을 하며 수정사항이 생길 때 MVC 패턴에 대한 장점을 제대로 알아 볼 수 있을 것입니다.
바로 2주차 과정 코딩에 들어가고 싶지만 남들 만큼, 남들 보다 더 좋은 코드를 작성하고 싶은 욕심 때문에 잠시 참고 일급 컬렉션에 대해서도 확실히 짚고 넘어간 후 시작하려고 합니다.
일급컬렉션이란 단어를 구글에 검색하면 많은 자료가 우테코와 관련하여 학습한 것으로 나옵니다.
왜 일급컬렉션을 사용하고 얻어가는 장점이 무엇인지 알아볼 것입니다.
일급컬렉션이란 원시값을 포장하여 접근을 최소한으로 막고 Collection
을 내부적으로 사용하여 자료를 다루도록 하는 것입니다.
List<String>
을 사용할 때 이 자료형을 그냥 막 사용하지 않고 Class
를 새로 만들고 private
필드로 자료를 두고 public
인 함수를 사용하여 자료를 넣고 다루도록 하는 것입니다.
이를 통해 아래와 같은 여러 이점을 가져올 수 있습니다.
비지니스에 종속적인 자료구조
요소의 개수를 제한시키는 등의 기능을 가집니다.
불변성 보장
자료가 내부적으로 private
로 보관되기 때문에 임의로 추가, 삭제, 변경이 불가능 합니다.
상태와 행위를 한 곳에서 처리
클래스 안에서의 함수들로만 자료를 관리하기 때문에 함수만 잘 만들면 다른 곳에서 의심할 여지 없이 자료를 잘 사용할 수 있습니다.
이름있는 자료구조
실제 프로젝트에서 단순히 List<String> myList = new ArrayList<String>();
보다는 Users myList = new Users();
쪽이 변수명을 막 지어도 파악하기 쉬울 것입니다. (물론 변수명을 막 지을 일을 없을 거에요...)
과제가 출시되었을 당시 기능 구현쪽을 보며 난이도가 크게 어렵지 않은 것 같은 느낌을 받았고 2주차까지 적응할 시간을 주는 것 같았습니다.
그리하여 초반은 공부하는 쪽으로 시간을 쏟고 나머지 시간에 코딩을 할 수 있었지만 3주차 부터는 그동안 공부한 것을 바탕으로 더 심도있는 프로젝트를 만들 것이라 예상이 됩니다.
이제 이론은 어느정도 공부한 것 같고 오늘 부터 본격적으로 코딩을 시작하였습니다.
처음 시작으로는 구현할 기능 목록을 정리하였습니다.
4주차까지 사용할 템플릿을 미리 구성하자 생각했고 기본 구조는 1주차의 다른분의 PR에서 아이디어를 얻어왔습니다.
길 수도 있지만 구현할 기능 목록을 포함하여 제가 알리고 싶은 모든 필요한 부분을 모두 넣겠다는 마음이었습니다.
본격적으로 MVC 패턴
을 프로젝트에 직접 써볼 수 있는 시간이 되었고 Application.java
파일 하나에 모든 것을 넣는 비효율적 방식에서 벗어날 수 있었습니다.
이후 사용자의 입력을 받아 domain
에서 validate
함수를 실행하여 검증을 거치고 예외 사항 체크를 하는 등 작업까지 완료하여 내일 결과를 계산하여 출력하는 것을 하면 될 것 같습니다.
기능 구현은 요구조건에 맞도록 간단히 작성하였는데 이후 테스트를 계속 통과하지 못하는 문제가 발생하였습니다.
시도할 횟수와 자동차 이름을 사용자에게 받아 domain
에 넣어두고 사용하는 도중 CarGroup
일급 컬렉션의 자료구조를 Map
으로 만드는 바람에 테스트 코드를 계속 통과하지 못하였습니다.
처음에는 이 문제가 제가 기능 구현을 제대로 하지 못하였다 생각하여 고치던 도중 결과를 자세히 보고 테스트 코드의 conatin
과 could not find
부분을 보고 알 수 있었습니다.
자료구조가 Map
이고 Key
기준으로 정렬했을 때 랜덤하게 나오는 반면 테스트 코드를 입력 순서대로 결과가 나오도록 요구하였습니다.
따라서 List
자료구조를 사용함으로써 해결할 수 있었습니다.
여기서 MVC패턴
의 큰 장점을 느낄수 있었는데요, controller
부분에서 domain
일급컬렉션 객체가 만들어둔 함수를 신뢰하여 사용하기만 하니 자료구조를 Map
에서 List
로 바꿀 때 관련 함수 정의 부분을 수정만 해줌으로써 CarGroup
클래스 파일 하나만 고치니 바로 테스트 코드를 통과할 수 있었습니다.
과거 개발 방식에서는 하나의 자료형을 바꾸면 관련되어 사용되는 모든 곳의 여러 파일을 하나하나 들어가여 수정해주는 번거로움이 있었는데 여기서 MVC패턴을 통한 모듈화의 장점을 잘 느낄수 있었습니다.
주어진 테스트 코드를 통과함으로써 코딩이 끝났고 패키지 구조 작성 까지로 마무리 하였습니다.
마지막으로 문제 해결 과정을 작성하여 Pull Request
의 README
작성을 마무리 하였습니다.
1주차 Pull Request
에서는 아무 글을 적지 않고 문서화에 정말 신경을 하나도 안쓴 것에 비해 이번 주차에는 기능 목록 뿐만 아니라 패키지 구조와 문제 해결 과정까지 담은 README
를 그대로 Pull Request
에 넣음으로써 코드 리뷰를 받기위한 노력을 하였습니다.
이후 제출 전에 다른 분들의 코드를 미리 염탐해보았습니다.
사용자의 음수 입력에 대한 검증 과정 하나를 빠뜨린 것을 알게 되었고 깁급히 제 코드에서 추가를 하였습니다.
Github
에 Pull Request
로 제출하는 특성상 다른 사람의 코드를 볼 수 있는데 악용하지 않고 사용한다면 자신의 부족한 부분을 확인할 수 있고 성장시킬 수 있기 때문에 굉장히 좋은 것 같습니다.
우테코의 서로 성장하는 취지를 제가 잘 받아들였다 생각됩니다.
코드 리뷰를 하기 위해 1주차와 같이 디스코드에 게시글을 작성하였지만 아무도 코드리뷰를 해주지 않았습니다...
이번엔 MVC패턴
도 적용하고 Pull Request
에 README
또한 굉장히 잘 작성하였음에도 아무도 제 코드를 봐주지 않았어요.
하지만 다른 사람들의 코드 리뷰들을 보며 학습할 수 있고 이번 주차에 공부한 것이 많기 때문에 뿌듯했습니다.
이 기세를 모아 3주차에는 더욱 발전된 코드를 작성하고 코드리뷰를 받기 위한 다른 방안을 생각해 보겠습니다.