[우아한테크코스 4기] 최종 코딩테스트 리팩토링
최종 코딩테스트를 마치고, 마저 기능 개발 - 리팩토링을 하는 과정을 기록하고자 합니다.
크루 관리 - 리팩토링
프론트엔드 - 백엔드 크루원을 추가하는 함수의 중복
아래 함수는 controller
에서 crew원들을 추가하는 로직을 담당하는 함수이다. frontend, backend를 구분하여 함수를 두 개 작성하였는데, 이 경우
- 수정 사항을 두 함수에게 반영해야한다.
triggerAddFrontendCrew(input) {
const frontendCrewList = this.$crewModel.getFrontendCrewList();
const newCrew = this.makeNewCrew(input, frontendCrewList);
if (newCrew) {
this.mutateModelWithNewFrontendCrew(newCrew);
this.renderViewWithFrontendCrew();
}
}
triggerAddBackendCrew(input) {
const backendCrewList = this.$crewModel.getBackendCrewList();
const newCrew = this.makeNewCrew(input, backendCrewList);
if (newCrew) {
this.mutateModelWithNewBackendCrew(newCrew);
this.renderViewWithBackendCrew();
}
}
이를 하나의 함수로도 동작하게 리팩토링해보자.
1. Crew 모델에서의 중복 제거
❌ 변경 전
getFrontendCrewList() {
return this.getDataByKey(CREW_KEYS.FRONTEND);
}
getBackendCrewList() {
return this.getDataByKey(CREW_KEYS.BACKEND);
}
✅ 변경 후
getCrewListByCourse(course) {
// course : Proptypes.oneOf([CREW_KEYS.FRONTEND,CREW_KEYS.BACKEND])
return this.getDataByKey(course);
}
변경 전 코드는 함수 이름으로 어떤 크루의 리스트를 가져오는 지 알 수 있어 좋다. 코드가 짧으니 굳이 변경하지 않아도 될 것 같다는 생각이든다.
... 수정중
팀 매칭
이 부분은 코스와 미션을 선택하고 뷰를 띄우는 부분까지 기능 개발을 완료하였었습니다.
랜덤으로 팀을 만들어내는 함수를 작성하는데 시간이 걸리기도 하였고, 소감문을 작성하는데 계획해 둔 시간이 있어 코딩테스트 당시 전부 기능 개발을 하지 못해 다시 기능 개발에 들어가 보았습니다.
팀 매칭 - 기능 구현
코딩테스트에선 팀매칭 기능 구현을 하지 못했다. 크게 팀매칭의 두 가지 기능이 있는데, 이를 구현해보았습니다.
1. 팀을 랜덤하게 매칭한다.
// team 인원 수가 입력되면 실행되는 핸들러 함수이다.
onSubmitTeamMemberCountForm(e) {
e.preventDefault();
const crewList = this.$crewModel.getAllCrewList();
const { count } = this.$inputsModel.getTeamMemberCountInput();
try {
if (isValidCount(Number(count))) {
// 올바른 count가 입력되면
// 새로운 팀을 만든다.
const team = this.$teamModel.makeTeam(crewList, Number(count));
// 새로운 팀으로 모델을 변형한다.
this.mutateModelWithNewTeam(team);
// 업데이트 된 모델로 뷰를 업데이트한다.
this.renderViewWithNewTeam();
}
} catch (error) {
alert(error);
}
}
mutateModelWithNewTeam(team) {
const { course, mission } = this.$inputsModel.getCourseAndMissionInput();
this.$teamModel.setTeam(course, mission, team);
}
renderViewWithNewTeam() {
const { course, mission } = this.$inputsModel.getCourseAndMissionInput();
const team = this.$teamModel.getTeam(course, mission);
this.renderViewMatchedTeam(course, mission, team);
}
2. 매칭되어 있는 경우, 재매칭 버튼을 통해 재매칭 한다.
onClickRematchButton(e) {
// console.log(e.target);
// const {target: {}}
const { course, mission } = this.$inputsModel.getCourseAndMissionInput();
// 네이밍 어떻게 하면 좋을까
// 모델을 변형한다.
this.mutateModelByRematch();
// 업데이트된 모델을 바탕으로 뷰를 업데이트한다.
this.renderViewNotMatchedTeam(course, mission);
}
mutateModelByRematch() {
const { course, mission } = this.$inputsModel.getCourseAndMissionInput();
this.$teamModel.clearTeam(course, mission);
}
renderViewNotMatchedTeam(course, mission) {
const crewList = this.$crewModel.getAllCrewList();
this.$view.renderNotMatchedTeam(course, mission, [...crewList]);
this.bindNotMatchedTeamHandler();
}
정리
팀 매칭 기능 구현을 완료하는데, 20분도 채 걸리지 않아 시간분배가 잘못되었음을 깨닫게 되었습니다.
-
명확히 모델을 정의하고 넘어가는 것이 필요하다고 생각하게 되었습니다.( 개발 이후에 모델을 변경하고자 하니, 의외로 수정해야하는 부분이 많아 시간이 더 걸리게 되었습니다.)
-
시간이 촉박하다보니, 하드 코딩을 하게 되었고 이 부분에서 문제가 발생하여 오히려 시간이 더 걸리게 되었습니다.
팀 매칭 - 리팩토링
1. Team 모델에서의 하드코딩을 지양하자
당시에는 빠르게 기능을 개발해야할 것 같아, 하드코딩을 수행하였습니다. 다음은 Team
모델의 defaultValue
를 만들어내는 함수입니다.
generateDefaultValue() {
return {
[`${COURSE_SELECT_MAP.프론트엔드}-${MISSION_SELECT_MAP.결제}`]: null,
[`${COURSE_SELECT_MAP.프론트엔드}-${MISSION_SELECT_MAP.베이스볼}`]: null,
[`${COURSE_SELECT_MAP.프론트엔드}-${MISSION_SELECT_MAP.레이싱카}`]: null,
[`${COURSE_SELECT_MAP.프론트엔드}-${MISSION_SELECT_MAP.로또}`]: null,
[`${COURSE_SELECT_MAP.프론트엔드}-${MISSION_SELECT_MAP.장바구니}`]: null,
[`${COURSE_SELECT_MAP.프론트엔드}-${MISSION_SELECT_MAP.지하철노선도}`]: null,
[`${COURSE_SELECT_MAP.프론트엔드}-${MISSION_SELECT_MAP.퍼포먼스}`]: null,
[`${COURSE_SELECT_MAP.백엔드}-${MISSION_SELECT_MAP.결제}`]: null,
[`${COURSE_SELECT_MAP.백엔드}-${MISSION_SELECT_MAP.베이스볼}`]: null,
[`${COURSE_SELECT_MAP.백엔드}-${MISSION_SELECT_MAP.레이싱카}`]: null,
[`${COURSE_SELECT_MAP.백엔드}-${MISSION_SELECT_MAP.로또}`]: null,
[`${COURSE_SELECT_MAP.백엔드}-${MISSION_SELECT_MAP.장바구니}`]: null,
[`${COURSE_SELECT_MAP.백엔드}-${MISSION_SELECT_MAP.지하철노선도}`]: null,
[`${COURSE_SELECT_MAP.백엔드}-${MISSION_SELECT_MAP.퍼포먼스}`]: null,
};
}
위와 같이 기본 값을 하드코딩 하게되니 다음과 같은 문제가 발생하였습니다.
1. 생성되지 않은 키가 존재 할 수 있습니다. 개발자가 모든 키를 직접 입력하다보니, 빠지는 키가 생길 수 있습니다.(예기치 못한 에러가 발생할 수 있습니다)
2. COURSE_SELECT_MAP, MISSION_SELECT_MAP에 변경을 가하게 되면, 위 함수도 같이 수정해야합니다. (유지보수 비용이 너무 커지게됩니다)
위와 같은 문제들을 방지하고자 다음과 같이 코드를 수정해보았습니다. Object.keys
메소드를 활용하여, 좀 더 선언적으로 코드를 변경해보았습니다. (COURSE_SELECT_MAP
, MISSION_SELECT_MAP
객체에 따라 기본값이 생성되므로)
generateDefaultValue() {
const result = {};
Object.keys(COURSE_SELECT_MAP).forEach((courseKey) => {
Object.keys(MISSION_SELECT_MAP).forEach((missionKey) => {
result[`${courseKey}-${missionKey}`] = null;
});
});
return { ...result };
}
다음과 같은 이점을 얻을 수 있었습니다.
1. 가독성이 올라간다. (객체의 키값으로 기본값의 키를 생성하는구나)
2. COURSE_SELECT_MAP, MISSION_SELECT_MAP 의 값을 변경하여도, 코드를 수정하지 않아도됩니다.
Author And Source
이 문제에 관하여([우아한테크코스 4기] 최종 코딩테스트 리팩토링), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@rat8397/우아한테크코스-4기-최종-코딩테스트-리팩토링저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)