ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백엔드] MVC 패턴
    스프링 2023. 11. 6. 19:36

     

    0)Application

    package lotto;
    
    import lotto.Controller.GameController;
    
    public class Application {
        public static void main(String[] args) {
            GameController gameController = new GameController();
            gameController.run();
        }
    }

    컨트롤러를 호출해 프로그램을 시작한다

     

    1) Controller

    public class GameController {
    
        public void run(){
            int purchaseAmount = this.readPurchaseAmount();
            List<Lotto> lottoTickets = LottoTicket.generateLottoTickets(purchaseAmount);
            output.printLotto(lottoTickets);
            List<Integer> winningNumbers = this.readWinningNumbers();
            int bonusNumber = this.readBonusNumber();
            Map<String, Integer> result = Result.calculateResults(lottoTickets, winningNumbers, bonusNumber);
            double prifitRate = Result.resultsToProfitRate(result);
            output.printResults(result, prifitRate);
        }

     

    Contoller은 필요에따라 model과 view를 호출하며 프로그램의 전체적인 흐름을 담당한다.

     

    view를 호출해 사용자 입력을 받고

    model을 활용해 비즈니스 로직을 처리하며

    그에 따른 값을 다시 view를 통해 사용자에게 보여준다.

     

        private int readPurchaseAmount(){
            while (true) {
                try {
                    String purchaseAmountString = input.readPurchaseAmount();
                    int purchaseAmount = Integer.parseInt(purchaseAmountString);
                    if (purchaseAmount % 1000 == 0) {
                        return purchaseAmount;
                    }
                    error.not_valid_purchaseAmount();
                } catch (NumberFormatException e) {
                    error.NAN();
                }
            }
        }

    view를 통해 들어온 값이 올바른지

    유효성 검사는 Contoller에서 진행된다.

     

    2)Model

    public class input {
        public static String readPurchaseAmount() {
            System.out.println("구입금액을 입력해 주세요.");
            return Console.readLine();
        }
        public static String readWinningNumbers() {
            System.out.println("당첨 번호를 입력해 주세요.");
            return Console.readLine();
        }
    }

    input view. 사용자의 입력을 전달한다

    public class output {
        public static void printLotto(List<Lotto> lottoTickets) {
            int purchaseAmount = lottoTickets.size();
            System.out.println(purchaseAmount+"개를 구매했습니다.");
            
            for (Lotto lottoTicket : lottoTickets) {
                List<Integer> numbers = lottoTicket.getNumbers();
                System.out.println(numbers);
            }
        }
    
        public static void printResults(Map<String, Integer> results, double profitRate) {
            System.out.println("당첨 통계");
            System.out.println("---");
            System.out.println("총 수익률은 " + String.format("%.1f", profitRate) + "%입니다.");
        }
    }

    output view. 사용자에게 출력 값을 보여준다

    public class error {
        public static void not_valid_purchaseAmount() {
            System.out.println(errorText.NOT_VALID_PURCHASE_AMOUNT);
        }
        public static void NAN() {
            System.out.println(errorText.NAN);
        }
        public static void duplicate_winningNumber() {
            System.out.println(errorText.DUPLICATE_WINNING_NUMBER);
        }
    }
    
    public class errorText {
        public static final String NOT_VALID_PURCHASE_AMOUNT = "[ERROR] 구입 금액은 1,000원 단위여야 합니다.";
        public static final String NAN = "[ERROR] 유효한 숫자를 입력하세요.";
        public static final String DUPLICATE_WINNING_NUMBER = "[ERROR] 로또 번호에 중복된 숫자가 있습니다.";
    }

    나는 에러 출력도 별도의 view로 구현하였고,

    이때 출력되는 에러 문구는 별도의 상수로 관리하였다.

     

     

     

     

    3) Model

        public void run(){
            int purchaseAmount = this.readPurchaseAmount();
            List<Lotto> lottoTickets = LottoTicket.generateLottoTickets(purchaseAmount);
            output.printLotto(lottoTickets);
            List<Integer> winningNumbers = this.readWinningNumbers();
            int bonusNumber = this.readBonusNumber();
            Map<String, Integer> result = Result.calculateResults(lottoTickets, winningNumbers, bonusNumber);
            double prifitRate = Result.resultsToProfitRate(result);
            output.printResults(result, prifitRate);
        }

     

    Model은 프로그램에 필요한 비즈니스 로직들을 수행다.

    위 컨트롤러 코드를 보면

    LottoTicket의 generateLottoTicket으로 로또를 생성하고,

    Result의 calculateResult로 당첨 결과를 적용하며

    마찬가지로 Result의 resultsToProfitRate로 수익률을 계산한다. (별도의 클래스로 분리했으면 좋았을 것 같다.)

     

    로또 생성에 필요한 '구매금액'은 input view로 받고

    생성된 로또는 output view로 출력

     

    마찬가지로 로또 결과 확인에 필요한 당첨번호 + 보너스 번호는 input으로 받고

    당첨 결과와 수익률은 output view로 출력한다.

     

    public class LottoTicket {
    
        public static List<Lotto> generateLottoTickets(int purchaseAmount) {
            int numberOfTickets = purchaseAmount / 1000;
            List<Lotto> lottoTickets = new ArrayList<>();
    
            for (int i = 0; i < numberOfTickets; i++) {
                Lotto lottoTicket = generateSingleLottoTicket();
                lottoTickets.add(lottoTicket);
            }
    
            return lottoTickets;
        }
    
        public static Lotto generateSingleLottoTicket() {
            List<Integer> numbers = Randoms.pickUniqueNumbersInRange(1, 45, 6);
            Lotto lottoTicket = new Lotto(numbers);
            return lottoTicket;
        }
    
    }

    로또 생성 코드

     

     

     

    '스프링' 카테고리의 다른 글

    어플리케이션 계층 구조  (0) 2023.11.06
    API - 리액트와 스프링 연동  (0) 2023.01.30
    간단한 JPA 활용 예제  (0) 2023.01.30
    제어 역전 & 의존성 주입  (0) 2023.01.23
    기본적인 회원 가입 예제  (0) 2023.01.23
Designed by Tistory.