
드디어 마지막 시험! D-day
코로나 여파로 인해 오프라인 테스트 대신 ZOOM을 이용한 온라인 테스트로 대체되었다. 너무 아쉬웠다! 마지막일 수도 있는 우테코 현장을 구경할 수 없다니!!! 자바지기 박재성님을 실제로 뵙지 못하다니… 꼭 붙고 싶다는 욕망이 커진다!!!
1시 시험 시작이지만 12시 부터 ZOOM에서 셋팅! 너무나 폐인스러운 모습에 조금 민망하긴 했다….
1시가 되자마자 요구사항이 도착했다.
처음에는 내 눈을 의심했다. ‘오잉? 3차 과제가 또 왔네??’ 하고 자세히 살펴보는데… 최단거리
최소시간
을 구하는 기능이었다. 최단거리
최소시간
을 한 번은 만들어보고싶었던 프로젝트였는데 이렇게 만나니 반가우면서 겁이 났다.
기능 구현 시작!
먼저 천천히 내가 만들어야할 기능이 무엇이 있을까 적어봤다. 지난 3차 과제때는 MVC패턴으로 갔다면 이번에는 책임주도개발을 하고싶다는 생각에 각 객체에 책임을 나눠주기 시작했다. (프리코스 끝나고 바로 오브젝트
라는 책을 읽고 많이 반성하게 되었다. 그래서 이번 마지막 미션은 최대한 오브젝트
책에서 나온 중요한 규칙을 지키려 노력해봤다.)
최단거리
와 최소시간
을 만났을 때는 먼저 다익스트라 알고리즘이 생각났다. 설마… 다익스트라 알고리즘까지 구현해야하나 생각이 들었을 찰나 밑에 보니 힌트가 있었다.
이 라이브러리는 처음 보기 때문에 매우 당황했다. 빠르게 구글링으로 api를 쭈욱 살피고 바로 test코드를 돌리면서 라이브러리에 익숙해지려고 노력했다. (이를 학습 테스트
라고 칭한다.)
5 시간이라는 시간제한 때문에 바로 틀을 짜기 시작했다.
얼른 적고 코드를 작성해봐야하기 때문에 무언가 프리코스때 보다 자세히 못 쓴 거 같아 많이 아쉽다. 이번 과제에서 가장 신경써야 했던 부분은 “최단 거리 시 걸리는 시간” 또는 “최소 시간 시 총 거리” 를 구하는 것이었다.
최단 거리 기준
최소 시간 기준
위 처럼 같은 출발역과 도착역이지만 선택한 기능에 따라 따로 계산을 해줘야 한다는 것이다. (이런!! [INFO} 오타를 지금 발견했다… 흑 ㅠ) 최대한 중복을 피하기 위해 Weight라는 enum을 만들어 기능들을 구현했다.
public enum Weight {
TIME("분", Path::getTime),
DISTANCE("km", Path::getDistance);
private final String name;
private final Function<Path, Integer> function;
Weight(String name, Function<Path, Integer> function) {
this.name = name;
this.function = function;
}
public static int getWeight(Path path, Weight weight) {
return Arrays.stream(values())
.filter(value -> value == weight)
.findFirst()
.orElseThrow(() -> new IllegalStateException("잘못 입력이 되었습니다."))
.function.apply(path);
}
}
public enum FunctionView {
DISTANCE("1", "최단 거리", StationManager::byDistance),
TIME("2", "최소 시간", StationManager::byTime),
BACK("B", "돌아가기", stationManager -> {});
private static final String VIEW_FORM = "%s. %s \n";
private final String key;
private final String name;
private final Consumer<StationManager> consumer;
FunctionView(String key, String name, Consumer<StationManager> consumer) {
this.key = key;
this.name = name;
this.consumer = consumer;
}
public static String getViewNames() {
StringBuilder stringBuilder = new StringBuilder();
Arrays.stream(values())
.forEach(value -> stringBuilder.append(String.format(VIEW_FORM, value.key, value.name)));
return stringBuilder.toString();
}
public static FunctionView getFunction(String key) {
return Arrays.stream(values())
.filter(value -> value.key.equals(key))
.findFirst()
.orElseThrow(() -> new IllegalStateException(SubwayErrorMessage.NOT_EXIST_FUNC.getMessage()));
}
public void execute(StationManager stationManager) {
consumer.accept(stationManager);
}
}
마지막 과제 후기
원래는 ‘천천히 모든 상황의 테스트 코드를 작성하며 완성도 있는 코드를 제출하자!’ 가 나의 목표였다. 하지만… 너무나 시간이 촉박했다. 기능을 다 구현하고 흐름 코드 구현을 해야하는데 시간을 보니 1 시간밖에 안남았었다. 그래도 1차~3차 프리코스를 통해 많은 훈련과 패턴이 있어 30 분 안에 구현할 수 있었던 것 같다.
나름 내가 배운 많은 부분들을 이번 과제에 표현했던 것 같아 만족스럽다. 이번 우테코 프리코스를 통해 많은 것을 배웠다. 간절한 마음으로 부족한 부분을 채우려 많은 노력을 했다. 이번 코스를 통해 총 4 권의 프로그래밍 서적을 완독했다… 자바 객체지향 디자인패턴
, 모던자바 인 액션
, 이펙티브 자바
, 오브젝트
들이다. 이 4 권 모두 정말 과제를 제출하는 데에 있어서 많은 도움이 되었고 내 프로그래밍 습관도 새롭게 변화된 것 같다. 또한 이 배움을 우테코 과제 안에 녹이다보니 학습 효과는 배로 되는 것 같았다. 프리코스를 통해 많은 것을 배웠기 때문일까? 우테코를 합격해 거기 속에서 많은 것을 배우고 싶은 욕심이 커졌다.
프로그래밍을 접하게 된 지 거의 1 년이 다 되어 간다. 매일 혼자 공부를 하며 나만의 틀에 갖히는 건 아닐까 고민이 많았던 때에 프리코스에서 다른 분들의 코드를 살펴보며 더 넓은 세상을 맛 보게 되었고 내가 나아가야 할 길에 대한 힌트를 받은 느낌이었다. 이러한 경험을 준 우테코 프리코스에게 너무나 감사하다! Gracias a WUA!!!
결과
이런 배움의 기회가 주어진 것에 감사하다. 지금의 열정 잃지 않고 계속해서 배움을 통해 성장하는 2021년이 되자!