우아한테크코스 6기 백엔드 프리코스 - 로또

MVC 구조

이번 미션에 MVC 패턴을 적용하기 위해 애플리케이션을 아래와 같이 계층적 구조로 설계했다.

mvc-architecture

  • IO - 사용자와 상호작용하는 인터페이스. 입출력을 담당하는 계층이다. View를 출력한다.
  • View - 컨트롤러가 IO 계층에게 전달하는 인스턴스이다.
  • Controller - 입력(InputWrapper)에 대한 결과(View)를 생성한다.
  • Service - 컨트롤러의 요청을 받아 비즈니스 로직을 실행하고 적절한 모델을 반환한다.
  • Model - 비즈니스 로직을 수행하기 위해 필요한 클래스들이다.

각각의 계층은 바로 아래 계층의 메서드에만 접근 가능하다.

계층적 구조의 이점

계층적 구조로 설계한 이유는 다음과 같은 이점이 있기 때문이다.

  • 모듈화 - 각각의 계층은 한 가지 기능만을 담당하기 때문에 모듈화가 쉽고 모듈화를 통해 단위 테스트를 작성할 수 있다. 모듈화되어 결합도가 낮은 코드는 다른 곳에서 재사용하기에 용이하다.
  • 디버깅이 쉽다 - 문제가 발생하면 어떤 계층, 어떤 모듈에서 발생했는지 발견하기 쉽다.
  • 변경이 쉽다 - 특정 계층의 모듈을 업데이트 하더라도 분리된 계층은 영향을 받지 않는다. 수정할 코드의 양이 줄어든다.
  • 추상화 - 서로 다른 계층은 다른 계층의 구체적인 구현에 신경쓰지 않고 외부로 노출된 인터페이스를 통해 간편하게 접근할 수 있다.

Model

모델 계층에는 아래와 같은 클래스들이 있다.

models

  • LotteryTicket - 로또 번호에 대한 비즈니스 로직을 수행
  • BonusNumber - 보너스 번호에 대한 비즈니스 로직 수행
  • PurchaseAmount - 구입 금액에 대한 비즈니스 로직 수행
  • LotteryPortfolio - 여러 장의 로또에 대한 비즈니스 로직 수행
  • RandomLotteryNumberProvider - 미션에서 제공하는 Randoms API를 감싸 비즈니스 로직을 수행
  • DrawResult - 추첨 결과(1등 ~ 5등과 꽝)를 표현하는 enum 클래스

Controller

사용자의 입력에 대한 View를 생성하는 계층이다.

리팩토링 전

사용자의 입력을 받고 서비스 객체를 통해 View를 생성한 뒤 출력까지 하고 있다. 서비스 객체 뿐만 아니라 다양한 모델 객체에 접근하여 계층이 분리되지 않았다.

LottoController-1

LottoController-2

리팩토링 후

사용자의 입력에 대한 View를 생성하는 것으로 역할을 제한했다.
코드의 양이 눈에 띄게 줄었고 오직 Service 객체와 상호작용 할 뿐 구체적인 구현에 대해서는 알지 못한다.

LottoMissionController

Service

서비스 객체는 오직 모델 클래스(core 패키지에 존재)를 사용하여 비즈니스 로직을 실행한다. 외부 라이브러리, 자바의 기본 클래스 등 통제할수 없는 코드를 모두 숨겨 비즈니스 로직을 완전히 통제할 수 있다.
비즈니스 로직이 실행된 결과를 반환한다. 반환된 결과는 컨트롤러에서 View를 생성하는데 사용된다.

LottoService-refactored-1

LottoService-refactored-2

IO

사용자와 상호작용을 위해 입출력을 담당하는 계층이다.

UserInputReader

사용자로부터 받은 입력을 PureNumber 또는 MultiplePureNumber 형태로 반환한다. 필드가 없기 때문에 모두 정적 메서드로 작성했다.
지금까지의 다른 모든 미션에서도 재사용할 수 있는 클래스이다.

UserInputReader

ConsoleUserInterface

프롬프트 메세지 출력, View 출력의 기능을 수행한다. 마찬가지로 필드가 없기 때문에 모두 정적 메서드로 작성했다.

ConsoleUserInterface

테스트 코드의 중요성

비교적 큰 규모의 리팩토링을 여러 번 진행했지만 테스트 코드를 통해 모든 기능이 정상적으로 실행됨을 0.842초만에 알 수 있었다.

테스트 통과

이 맛에 코딩한다☺️

마무리

MVC 패턴을 하나부터 열까지 직접 구현해본 것은 처음이다. MVC 패턴을 왜 사용하는가부터 어떻게 구현해야 목적을 이룰수 있을지를 고민해볼 수 있었다.
다음 미션도 MVC 패턴을 적용하여 이번 미션과 최대한 비슷하게 만들어 코드의 재사용성을 높이는 것이 목표이다.

elapsed-time

reference

Comments