온보딩 problem5 리팩토링

MINJU·2022년 12월 11일
0
post-thumbnail

문제5

지난 PR 셀프 리뷰

init() 메소드 말고는 나름 괜찮게한듯!
문제가 단순해서 더 그런 것 같다.

기능 정의

[ 기능 ]
- [ ] money를 입력받기
- [ ] 각 단위별 몇 개의 동전이 필요한지 가져오기
- [ ] 결과 출력하기

[ 예외 ] 
- [ ] money가 1 이상 1,000,000이하가 아닌 경우
- [ ] money가 숫자가 아닌 경우

구현

관리해야하는 숫자인 money(=change) 가 int이므로!
4번 문제 리팩토링에서 다짐했던대로 service 패키지를 도입했다.

change와 관련된 서비스 로직을 모두 ChangeService에 놓고, controller에서 이를 호출해서 사용하도록 구현하였는데, 아래는 처음 구현했던 Service 로직이다.

    public Change getChange(String input){
        while(true){
            try{
                int change = getValidateChange(input);
                return new Change(change);
            } catch (IllegalArgumentException e){
                System.out.println(e.getMessage());
            }
        }
    }

controller에서 inputView로 받아온 String input을 넣고, 이를 Change로 변환해서 return하는 로직인데, 이렇게 구현하니까


요렇게! 에러 메세지가 무한 출력되는 일이 발생했다.

좀만 생각해보면 넘 당연한 일인게, 사용자한테 입력은 밖에서 받고 있으면서 그걸 while문을 돌리면 .. 당연히 변화없이 에러 메세지만 출력되지 😂..


service 로직은 model만 알고 있고, view는 몰라야하므로, 재입력 받는 로직을 controller로 옮겼다!

    public void run() {
        Change change = getChange();
        List<Integer> result = changeService.getResult(change);
        outputView.printResult(result);
    }
    
    private Change getChange(){
        while(true) {
            try{
                outputView.printInputGuide();
                String userInput = inputView.getUserInput();
                return changeService.getChange(userInput);
            } catch(IllegalArgumentException e){
                System.out.println(e.getMessage());
            }
        }
    }

getChange() 메소드를 controller에도 만들어놓은 것이다!

근데 이렇게 하니까, 결국 serivce 로직이 controller에게 model 그 자체를 넘겨준다는 점에서 큰 의미가 없다는?? 생각이 들었다.

지난 주 참고한 모호한 MVC 아키텍쳐보다 조금 더 명확한 아키텍처를 찾아보자하고 검색한 결과 아래와 같은 아키텍처를 찾게 되었다.

여기에서 힌트를 얻어 아래와 같이 코드를 변경하였다.

controller에서

private Change getChange(){
        while(true) {
            try{
                String userInput = inputView.getUserInput();
                int validateChange = changeService.getValidateChange(userInput);
                return new Change(validateChange);
            } catch(IllegalArgumentException e){
                System.out.println(e.getMessage());
            }
        }
    }

service에게 int validateChange를 받아서 새로운 Change 객체를 만들어서 run()로직에 돌려주는 것이다!

이러면 service에서 사용되는 로직은 아래와 같아지는데

    public int getValidateChange(String change){
       int changeInt = changeStringToInt(change);
       Validator.validateRange(changeInt);
       return changeInt;
   }

이렇게 되면 Model 자체를 사용하는 것이 아니라, 그에 맞는 int를 돌려주기 때문에 위에 첨부한 아키텍처와 나름 비슷한?? 역할을 하는 것 같다는 생각이 들었다~~



마무리

MVC 패턴은 여전히 어렵다😂 Spring Boot 공부할 땐 별 생각없이 사용했던 구조가, 자바 프로젝트에서 내가 정의해서 사용하려니 넘 어려운 것 같다.

여기에도 명확한 정답이 있을까 궁금하다. 선택의 기준으로서 변경의 용이함을 적용하려고했는데 ~~나는 그냥 다 편해보인다 🙄 .. ~~

여튼 계속해서 고민하는 과정이 필요했으니까!

남은 것도 화이팅아아아아!

0개의 댓글