반영 1
일단 시간이 부족해서 못했던 players 객체화, recommand의 util화를 했고, 그러면서 getWeekMenus도 util에 있기보다는 Players 로 이동시켰다. 그러면 getPlayer를 쓰지 않을 수 있었다.
반영 2
get 문제들을 해결하기 위해 Players, RecommendCategories에 각 get이 필요했던 메소드들을 분리해줬다.
https://github.com/woowacourse-precourse/java-menu/pull/214
랜덤 메소드를 관할하는 클래스는 한 번만 생성해놓으면 되는데, 그럼 보통 getInstance를 떠올리기 쉽다. 이렇게 컨트롤러의 생성자의 인자로 넘겨줘서 클래스 필드로 선언하는 것의 장점은 뭘까?
시작 메시지등의 경우 print 메소드 분리 깔끔하다.
validate 전의 인자를 raw라는 네이밍으로, 그 바깥에서는 scan이라는 네이밍 아이디어!
추상화를 통한 제어를 하면 우테코에서 제공하는 메소드 이외의 경우도 테스트 할 수 있다는 장점이 있고,
우테코에서 제공한 테스트를 이용하면 shuffle 등의 메소드 자체에 대해 추상화 없이 테스트 할 수 있다는 장점이 있다.
다만, 해당 테스트 코드가 돌아가는 방식을 이해하고 run main이 아니더라도 사용할 수 있는지를 확인해야할 것 같다.run main에서만 사용 가능하다면 제약이 있고, run main으로 연결하는 방법을 생각해봐야할 것 같다.
https://velog.io/@dlguswl936/우테코-제공-NsTest-메소드-들여다보기
random을 관리하는 클래스를 만들어도 좋겠다. 비록 이 기능 하나만 있더라도 의미가 있어보인다.
controller내에 read 함수를 만드는 게 아니라 retryUtil을 따로 만들어서 거기의 static 메소드로 만들고,
import 문을 넣어놓음으로써 별도 추가 없이 바로 read 메소드 불러오기!
이렇게 하면 genarateCoaches() 속에서
형식에 대한 검증 결과를 read로 retry 처리를 한 번 한뒤,
Coaches에 대한 길이 검증 결과를 반환한다.
그 결과인 genarateCoaches()를 read로 감싸면 검증 결과에 대해 retry를 다시 해주는 구조!
각 검증이 일어나는 과정마다 메소드로 분리해서 감싸주면 될 것 같다!
예를 들어, 코치 입력 시 조건들이 아래와 같을 때,
공백 불가/ ','로 구분/ 특수문자말고 한영만/ 5명까지 입력 가능/ 이름은 2~4자
거치는 순서대로 검증 책임은 이렇게 나눠진다.
InputView (→InputValidator)
단, InputView에 정규식이나 비교 메소드를 넣지 않고,
InputValidator를 만들어 InputView에서 쓰일 수 있는 메소드들을 static 메소드로 분리한다.
Coaches
coach
어차피 ,로 입력받은 걸 List로 반환해주는 건 동일한 기능이기 때문에!
대놓고 new 객체를 dto를 받아서 만드는 게 아니라,
dto 내에 dto->객체의 to객체메소드를 만들어서,
그 안에 객체의 from 메소드를 가져와서 객체로 변환한다!
이렇게 하면 생성자를 privat으로 감출 수 있기도 하다!
메뉴 추천 로직을 따라가보자, 다음엔 나도 만들어볼 수 있게!
recommendCategories.recommendMenus(coaches, menuShuffle)
: 일단 coaches랑 shuffle(MenuGenerator)들고 추천카테고리들 돌러 들어감
coaches.recommendMenus(recommendCategory, menushuffle)
: 추천 카데고리들 중 하나씩 갖고 coaches 돌러 들어감, 셔플은 계속 갖고감.
coach.recommendMenu(menuCategory, menushuffle)
: 코치들 중 한명씩 갖고 코치에 hate, 이미recommend과 함께 처리해야하므로 들어감
menucategory.recommendMenu(gateMenuNames, recommendMenuNames, menushuffle)
: 자기가 가진 hate, 이미recommend 갖고 카테고리enum으로 추천 받으러 들어감. 셔플은 끝에서 해야하는 기능이므로 갖고 들어감.
menushuffle.getMenuFromShuffle(그카테고리의 음식리스트)
.filter(!hateMenuNames, recommendMenuNames)
.findFirst.isPresent(recommenMenuNames::add);
: 그 카테고리의 음식 리스트를 셔플돌려서 하나 갖고, 필터로 hate, recommend 거르고, 나오면 갖고온 코치 recommend에 추가, 아니면 다시 돌아가는 건 어딨지?
우선 전략패턴에 대한 설명은 해당 포스팅을 발췌했다.
에 대한 의견이 좀 있는데, 일단 현재는 이렇게 정리하려고 한다.
public static RecommendMenuNames fromTest(List<String> recommendMenu) {
return new RecommendMenuNames(recommendMenu);
우선, 공식문서에서의 join
다음으로, 해당 포스팅에서 String.join과 비슷한 기능들에 대한 설명을 가져와서 이해했다.
코드로 돌아가보자면,
메시지를 끼워넣는 또 다른 방식!
printf와 똑같아보이는데 이건 출력되지 않는다는 점이 차이인 것 같다. 왜 여기는 이걸로 썼을까?