[우테코 6기] 프리코스 3주차 미션 - 5일차
우아한테크코스 6기 백엔드 프리코스 - 로또
MVC 구조
이번 미션에 MVC 패턴을 적용하기 위해 애플리케이션을 아래와 같이 계층적 구조로 설계했다.
- IO - 사용자와 상호작용하는 인터페이스. 입출력을 담당하는 계층이다. View를 출력한다.
- View - 컨트롤러가 IO 계층에게 전달하는 인스턴스이다.
- Controller - 입력(InputWrapper)에 대한 결과(View)를 생성한다.
- Service - 컨트롤러의 요청을 받아 비즈니스 로직을 실행하고 적절한 모델을 반환한다.
- Model - 비즈니스 로직을 수행하기 위해 필요한 클래스들이다.
각각의 계층은 바로 아래 계층의 메서드에만 접근 가능하다.
계층적 구조의 이점
계층적 구조로 설계한 이유는 다음과 같은 이점이 있기 때문이다.
- 모듈화 - 각각의 계층은 한 가지 기능만을 담당하기 때문에 모듈화가 쉽고 모듈화를 통해 단위 테스트를 작성할 수 있다. 모듈화되어 결합도가 낮은 코드는 다른 곳에서 재사용하기에 용이하다.
- 디버깅이 쉽다 - 문제가 발생하면 어떤 계층, 어떤 모듈에서 발생했는지 발견하기 쉽다.
- 변경이 쉽다 - 특정 계층의 모듈을 업데이트 하더라도 분리된 계층은 영향을 받지 않는다. 수정할 코드의 양이 줄어든다.
- 추상화 - 서로 다른 계층은 다른 계층의 구체적인 구현에 신경쓰지 않고 외부로 노출된 인터페이스를 통해 간편하게 접근할 수 있다.
Model
모델 계층에는 아래와 같은 클래스들이 있다.
- LotteryTicket - 로또 번호에 대한 비즈니스 로직을 수행
- BonusNumber - 보너스 번호에 대한 비즈니스 로직 수행
- PurchaseAmount - 구입 금액에 대한 비즈니스 로직 수행
- LotteryPortfolio - 여러 장의 로또에 대한 비즈니스 로직 수행
- RandomLotteryNumberProvider - 미션에서 제공하는
Randoms
API를 감싸 비즈니스 로직을 수행 - DrawResult - 추첨 결과(1등 ~ 5등과 꽝)를 표현하는
enum
클래스
Controller
사용자의 입력에 대한 View를 생성하는 계층이다.
리팩토링 전
사용자의 입력을 받고 서비스 객체를 통해 View를 생성한 뒤 출력까지 하고 있다. 서비스 객체 뿐만 아니라 다양한 모델 객체에 접근하여 계층이 분리되지 않았다.
리팩토링 후
사용자의 입력에 대한 View를 생성하는 것으로 역할을 제한했다.
코드의 양이 눈에 띄게 줄었고 오직 Service 객체와 상호작용 할 뿐 구체적인 구현에 대해서는 알지 못한다.
Service
서비스 객체는 오직 모델 클래스(core
패키지에 존재)를 사용하여 비즈니스 로직을 실행한다. 외부 라이브러리, 자바의 기본 클래스 등 통제할수 없는 코드를 모두 숨겨 비즈니스 로직을 완전히 통제할 수 있다.
비즈니스 로직이 실행된 결과를 반환한다. 반환된 결과는 컨트롤러에서 View를 생성하는데 사용된다.
IO
사용자와 상호작용을 위해 입출력을 담당하는 계층이다.
UserInputReader
사용자로부터 받은 입력을 PureNumber
또는 MultiplePureNumber
형태로 반환한다. 필드가 없기 때문에 모두 정적 메서드로 작성했다.
지금까지의 다른 모든 미션에서도 재사용할 수 있는 클래스이다.
ConsoleUserInterface
프롬프트 메세지 출력, View 출력의 기능을 수행한다. 마찬가지로 필드가 없기 때문에 모두 정적 메서드로 작성했다.
테스트 코드의 중요성
비교적 큰 규모의 리팩토링을 여러 번 진행했지만 테스트 코드를 통해 모든 기능이 정상적으로 실행됨을 0.842초만에 알 수 있었다.
이 맛에 코딩한다☺️
마무리
MVC 패턴을 하나부터 열까지 직접 구현해본 것은 처음이다. MVC 패턴을 왜 사용하는가부터 어떻게 구현해야 목적을 이룰수 있을지를 고민해볼 수 있었다.
다음 미션도 MVC 패턴을 적용하여 이번 미션과 최대한 비슷하게 만들어 코드의 재사용성을 높이는 것이 목표이다.
Comments