{
    "componentChunkName": "component---src-templates-blog-template-js",
    "path": "/wooteco-pre-final/",
    "result": {"data":{"cur":{"id":"b70d3ada-b3a5-59ef-aaa4-1cf0b16eb29d","html":"<p>우테코 프리코스 그리고 최종 코테가 끝난지도 한달이 지났다.<br>\n다시 한 달 전의 기억을 살려서 최종 코딩 테스트 후기를 써보려고 한다.<br>\n지금까지 썼던 회고와는 다르게 일기 느낌으로다가,,</p>\n<h2 id=\"-프리코스가-끝나고-최종-코테까지\" style=\"position:relative;\"><a href=\"#-%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4%EA%B0%80-%EB%81%9D%EB%82%98%EA%B3%A0-%EC%B5%9C%EC%A2%85-%EC%BD%94%ED%85%8C%EA%B9%8C%EC%A7%80\" aria-label=\" 프리코스가 끝나고 최종 코테까지 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>👏 프리코스가 끝나고 최종 코테까지</h2>\n<p>11월 23일.<br>\n4주 동안의 프리코스 과정이 끝났다.</p>\n<p>프리코스가 끝나고 바로 들었던 생각은 ‘떨어져도 괜찮을 것 같다’였다.<br>\n자바를 싫어하고 자바에 대해서 1학년 수준의 기초 밖에 모르는 상태에서 시작했던 프리코스였기 때문에 이미 이 4주 동안의 프리코스 과정만으로도 많은 것들을 배웠다는 생각이 들었다. 게다가 프리코스를 진행하면서 각 주차가 끝나고 다른 사람들의 코드를 봤을 때, 나랑은 완전 차원이 다르게 잘하는 사람이 많구나라고 생각했다. 각 주차가 끝나고 쓰는 소감문도 정말 간단하게 해당 주차에 새롭게 배운 핵심 내용들만 적었던 나로서는 ‘나보다 더 간절한 사람이 붙겠지’라는 생각만 들었다.</p>\n<p>그리고 12월 14일 1차 심사 결과가 나왔다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 36.11111111111111%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAz0lEQVQoz41RB47EIAzk/8/cJPQSQZKFtDnZW3TSbTlL1gwgjwdbrOsK5xzGcUSMkTGlxOi9RykFFOd5/itFa42LlmVhnOcZdHeL855/461gzhlSSnajtYYxht0dx4F935+4HwfzR74VLGWCdQ59P8BYixAif70fBlwuHZTSkFKh63oMUjFX2mDbtpdOxTTNXERC2hgWowbeBzjvobRmHlNisZw/z1TQ3EgghABrHXNaEiE7pgb2xq/X+nVBgrZcW+NF1Fqf+Ti3X280u2+CP/kAH4KPjdGhAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"precourse-result.png\"\n        title=\"precourse-result.png\"\n        src=\"/static/21aeaadb9d05d44459bc57ba1688689e/37523/precourse-result.png\"\n        srcset=\"/static/21aeaadb9d05d44459bc57ba1688689e/e9ff0/precourse-result.png 180w,\n/static/21aeaadb9d05d44459bc57ba1688689e/f21e7/precourse-result.png 360w,\n/static/21aeaadb9d05d44459bc57ba1688689e/37523/precourse-result.png 720w,\n/static/21aeaadb9d05d44459bc57ba1688689e/302a4/precourse-result.png 1080w,\n/static/21aeaadb9d05d44459bc57ba1688689e/07a9c/precourse-result.png 1440w,\n/static/21aeaadb9d05d44459bc57ba1688689e/add4c/precourse-result.png 1452w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>그렇게 큰 기대를 하지 않은 채 메일로 결과를 확인했다.<br>\n‘축하드립니다’라는 문구를 확인하고 얼떨떨해서 메일을 계속 다시 읽다가 정신 차리고 기차 표부터 구했다.<br>\n당장 바로 3일 뒤였기 때문에 아침 일찍 기차로 표를 겨우 구하고 이제 내가 어떻게 붙은 건지 생각해봤다.</p>\n<p>사실 이건 아직도 의문이다.<br>\n비전공자를 우선으로 한다는 말도 조금씩 나왔었고 소감문도 평가 요소에 포함된다는 말도 있는 등 여러 방면에서 나에게 이득이 되는 평가 요소는 많지 않았다. 그래서 내가 어떻게 합격하게 되었는지 정확히 알 수 없었다.<br>\n하지만 조금이나마 추측해보자면, 우테코에서 원하는 방향과 내가 미션을 해결하면서 찾고자 했던 방향이 비슷했던 것 같다.<br>\n구현하기 전에 클래스 구조를 설계하는 과정을 우선시 하고, 미션 요구사항을 중요하게 생각하는 등 이런 생각이 우테코에서 원하는 프리코스 목표와 비슷했지 않을까. 그리고 다른 사람들이 보기에는 나도 다른 사람들처럼 간절해보이지 않았을까. 그렇게 생각한다.</p>\n<hr>\n<h2 id=\"-최종-코딩-테스트-시작\" style=\"position:relative;\"><a href=\"#-%EC%B5%9C%EC%A2%85-%EC%BD%94%EB%94%A9-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%8B%9C%EC%9E%91\" aria-label=\" 최종 코딩 테스트 시작 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>👋 최종 코딩 테스트 시작!</h2>\n<p>12월 17일.<br>\n아침 일찍 KTX를 타고 서울로 갔다.</p>\n<p>도착해서 점심을 먹고 선릉역에 도착해서 선릉 캠퍼스로 가는 길은 떨리기보다는 설렜다.<br>\n보통 이런 시험을 앞두고 많이 긴장하는 타입이지만 왠지 모르게 이 날은 설렜다.<br>\n기대도 안하고 있던 시험이어서 보너스로 기회가 주어졌다는 생각이 커서인지 긴장하는 마음 하나 없이 도착했고, 오히려 유튜브로만 보던 코치님들을 보니 반가운 마음이 들었다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.111111111111114%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACMklEQVQoz0XO20/TUADHcf4X46s+EDFAYgRNiKgv4IPKJYMBW7tetvV+utN1tKeXnbWHdZe26yIPgBfeBA1/m0pWs4Vkv/dPvr+FfDLJ83zy78/NRW97a/Pl8uLGi6WNtdVPW288D3TCZhCYQWjiAHo+sJHseOCkvLe29Hj9+aOFPJ/h+7+3V4PtrXcri09frT5bXVl+v/nadZV2B+LA6HQMjKHvaciRT21RFEuFz293Pqw/4Hxyf3M5ZNhDpkrxAqcAoWU3gm477OEwwqSHcei4fsvxTcsB0KhJEiXJ5YX8YZOfl0OeP9LsdhMPeYCOea3IyMecwoiwxMmg1XZIbAWD03YIm4Kq0rJMTfEsnd9cJix7KBmOhrpV3S0yWrkOqZpeEeEJrzb9yD1LrTBp4Z7RFKBRBYCd49uvKcsciBDp7kB3+0VGpeuQk01GMjjFdLoZIgk6G6FwaJqirrOKSs/wTP/6lrKVgtCwgdPnNLRfEooVuVRr8MAu10ALD5woQ2eZQ2K2UqwwFY6blicP+HtK0/t1/VRFUcOPTTz8KJEnBf/IjMP43InG03g3sztdvsZyNe1wtzDHv39kNLUnma7m9iFOLJKpXlq1E5OMvWg8PUxSm4wsTES5zgpg5+BofvvuekRTu6KBFDtq+MMmjq0w8aLMjcaz7NgmqUUyCxOOZ9i6dnBMzct31yOK3hMNS7FC6A1aYYaicz++6KRX7cEXt5ugsG9jYvsW0DlFZVXA/QeIkHQmMNwRWQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"final-info.png\"\n        title=\"final-info.png\"\n        src=\"/static/914fd4a5094dfbb5519deeeea5c99f2c/37523/final-info.png\"\n        srcset=\"/static/914fd4a5094dfbb5519deeeea5c99f2c/e9ff0/final-info.png 180w,\n/static/914fd4a5094dfbb5519deeeea5c99f2c/f21e7/final-info.png 360w,\n/static/914fd4a5094dfbb5519deeeea5c99f2c/37523/final-info.png 720w,\n/static/914fd4a5094dfbb5519deeeea5c99f2c/302a4/final-info.png 1080w,\n/static/914fd4a5094dfbb5519deeeea5c99f2c/07a9c/final-info.png 1440w,\n/static/914fd4a5094dfbb5519deeeea5c99f2c/3f1d5/final-info.png 2831w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>도착해서 가장 놀랐던 점은 엄청 자유로운 환경이라는 점이었다. 코테 중간에 자유롭게 화장실 이용은 물론이고 준비된 간식들을 가져와서 먹거나 구경하는 것도 가능해서 놀랐다,,<br>\n당연히 노트북 거치대나 마우스, 키보드 사용이 안될 거라 생각하고 안가져갔는데 사용 가능했다,,,</p>\n<p>그리고 13시부터 점심 메뉴 추천이라는 주제의 최종 코딩 테스트가 시작되었다.</p>\n<hr>\n<h2 id=\"-최종-코딩-테스트-미션-소개\" style=\"position:relative;\"><a href=\"#-%EC%B5%9C%EC%A2%85-%EC%BD%94%EB%94%A9-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EB%AF%B8%EC%85%98-%EC%86%8C%EA%B0%9C\" aria-label=\" 최종 코딩 테스트 미션 소개 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🎞 최종 코딩 테스트 미션 소개</h2>\n<p><a href=\"https://github.com/woowacourse-precourse/java-menu\">최종 코딩 테스트 미션 소개</a></p>\n<h3 id=\"-기능-요구-사항\" style=\"position:relative;\"><a href=\"#-%EA%B8%B0%EB%8A%A5-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD\" aria-label=\" 기능 요구 사항 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🚀 기능 요구 사항</h3>\n<p>한 주의 점심 메뉴를 추천해 주는 서비스다.</p>\n<ul>\n<li>코치들은 월, 화, 수, 목, 금요일에 점심 식사를 같이 한다.</li>\n<li>메뉴를 추천하는 과정은 아래와 같이 이뤄진다.\n<ol>\n<li>월요일에 추천할 카테고리를 무작위로 정한다.</li>\n<li>각 코치가 월요일에 먹을 메뉴를 추천한다.</li>\n<li>화, 수, 목, 금요일에 대해 i, ii 과정을 반복한다.</li>\n</ol>\n</li>\n<li>코치의 이름은 최소 2글자, 최대 4글자이다.</li>\n<li>코치는 최소 2명, 최대 5명까지 식사를 함께 한다.</li>\n<li>각 코치는 최소 0개, 최대 2개의 못 먹는 메뉴가 있다. (<code class=\"language-text\">,</code> 로 구분해서 입력한다.)\n<ul>\n<li>먹지 못하는 메뉴가 없으면 빈 값을 입력한다.</li>\n<li>추천을 못하는 경우는 발생하지 않으니 고려하지 않아도 된다.</li>\n</ul>\n</li>\n<li>한 주에 같은 카테고리는 최대 2회까지만 고를 수 있다.</li>\n<li>각 코치에게 한 주에 중복되지 않는 메뉴를 추천해야 한다.\n<ul>\n<li>예시)\n<ul>\n<li>구구: 비빔밥, 김치찌개, 쌈밥, 규동, 우동 → 한식을 3회 먹으므로 불가능</li>\n<li>토미: 비빔밥, 비빔밥, 규동, 우동, 볶음면 → 한 코치가 같은 메뉴를 먹으므로 불가능</li>\n<li>제임스: 비빔밥, 김치찌개, 스시, 가츠동, 짜장면 → 매일 다른 메뉴를 먹으므로 가능</li>\n<li>포코: 비빔밥, 김치찌개, 스시, 가츠동, 짜장면 → 제임스와 메뉴가 같지만, 포코는 매번 다른 메뉴를 먹으므로 가능</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>메뉴 추천을 완료하면 프로그램이 종료된다.</li>\n<li>사용자가 잘못된 값을 입력할 경우 <code class=\"language-text\">IllegalArgumentException</code>를 발생시키고, “[ERROR]“로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시\n받는다.\n<ul>\n<li><code class=\"language-text\">Exception</code>이 아닌 <code class=\"language-text\">IllegalArgumentException</code>, <code class=\"language-text\">IllegalStateException</code> 등과 같은 명확한 유형을 처리한다.</li>\n</ul>\n</li>\n</ul>\n<p>…</p>\n<h3 id=\"실행-결과-예시\" style=\"position:relative;\"><a href=\"#%EC%8B%A4%ED%96%89-%EA%B2%B0%EA%B3%BC-%EC%98%88%EC%8B%9C\" aria-label=\"실행 결과 예시 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>실행 결과 예시</h3>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">점심 메뉴 추천을 시작합니다.\n\n코치의 이름을 입력해 주세요. (, 로 구분)\n토미,제임스,포코\n\n토미(이)가 못 먹는 메뉴를 입력해 주세요.\n우동,스시\n\n제임스(이)가 못 먹는 메뉴를 입력해 주세요.\n뇨끼,월남쌈\n\n포코(이)가 못 먹는 메뉴를 입력해 주세요.\n마파두부,고추잡채\n\n메뉴 추천 결과입니다.\n[ 구분 | 월요일 | 화요일 | 수요일 | 목요일 | 금요일 ]\n[ 카테고리 | 한식 | 한식 | 일식 | 중식 | 아시안 ]\n[ 토미 | 쌈밥 | 김치찌개 | 미소시루 | 짜장면 | 팟타이 ]\n[ 제임스 | 된장찌개 | 비빔밥 | 가츠동 | 토마토 달걀볶음 | 파인애플 볶음밥 ]\n[ 포코 | 된장찌개 | 불고기 | 하이라이스 | 탕수육 | 나시고렝 ]\n\n추천을 완료했습니다.</code></pre></div>\n<hr>\n<h2 id=\"-최종-코딩-테스트-후기\" style=\"position:relative;\"><a href=\"#-%EC%B5%9C%EC%A2%85-%EC%BD%94%EB%94%A9-%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%9B%84%EA%B8%B0\" aria-label=\" 최종 코딩 테스트 후기 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🙏 최종 코딩 테스트 후기</h2>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.111111111111114%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACkElEQVQoz03LSU8TcQCG8X+BBDxpvJhoPBjvmCghSAigoiEG0UhIXDBukURBgiKkYGihpaUM3SgwUCjdV6YLpe10X2bpQjstltKZIgL6TQx48c0vz+0FdC5GU4lyLkHnMIbCKnn8VzGVjaNkcCsd9ZJBdyaGHhSIgwLJUHgljx8Ukoc/0sd7mZNSFuzvxEuZ2F46upc+bTEVsRvWlyRCNSydn5kUCzgy0bRFvbJLhukczlAEQ5Fn/9RRMQMqeYKhcIbC6TPlbCLosvid5sj2ptuq8zstDuOGy6ymsGApk9jfwfazOJ0jKvnk4W4aJEMuwu/AUCThO4NukgEn5rNH3ba4F4l7kYTPHvMgQacZRQy+TT2K6P12Y8BhCrusQA8L12TcFfEkPP8PZxniKGa/i3mjIs7XOe6ITDguF7Cl/DGIM8Jnfx54+7yvp6uv59Gr3m5g00hM65BBOWdcg8wbEqtGbtMt2LSnrBq5VSPXKSE1LFQvzyilXPnseOOt+osXzl+5fOn6taug8WZ9U8ONtubG9pam1rPea2u+f6els6O1q/NuR3vL1MSw36k1qRYsaoVOKVmEphYh7qp8ZlXKB1U1NSxWVd25utq6WhaLBf5bdXU1AGBo4F0+6V2HIa1SAssECjFPo5RkMTeFecCidHqWNzY+Ovhl6MPQpzf971+8ftn7rPfx0ycPu7se3G5qmBgbzJHbeBghwwgRRogQggVtiYCFCNpAORuiqXCZCtH5yGExflTCjsvkCU3+ppN/mDRTiFJJz88SHkUtZu2SXrVgUCnsJmWB9JWzEcD51j/N/ijiDIt5IzIBe2l+ck3O18Ais0rm0MMO/fKWeSXqMeIBhAw7UhEXGTptIYkWcO9fc9uGLFJkgW0AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"final-gift.png\"\n        title=\"final-gift.png\"\n        src=\"/static/ede77837c4c0ab8c6dd4b2748926452b/37523/final-gift.png\"\n        srcset=\"/static/ede77837c4c0ab8c6dd4b2748926452b/e9ff0/final-gift.png 180w,\n/static/ede77837c4c0ab8c6dd4b2748926452b/f21e7/final-gift.png 360w,\n/static/ede77837c4c0ab8c6dd4b2748926452b/37523/final-gift.png 720w,\n/static/ede77837c4c0ab8c6dd4b2748926452b/302a4/final-gift.png 1080w,\n/static/ede77837c4c0ab8c6dd4b2748926452b/07a9c/final-gift.png 1440w,\n/static/ede77837c4c0ab8c6dd4b2748926452b/669cd/final-gift.png 3024w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>우선 최종 코테도 기존 프리코스 미션과 비슷하게 진행되었다.<br>\n크게 추가된 프로그래밍 요구사항은 없었고 오히려 프로그래밍 요구사항에서는 10라인 제한에서 15라인 제한으로 완화되거나 파라미터 개수 제한이 사라지는 등 전체적으로 완화되었다.<br>\n다만, 기능 요구사항은 개인적으로 프리코스 때보다 복잡해졌다는 생각이 들었다.<br>\n필요한 기능이 전체적으로 많아졌고, 특히 클래스 구조를 설계하는데 살짝 꼬였었다. 항상 구조 설계를 먼저하고 그 구조에 맞춰서 기능 요구사항 순서대로 구현을 시작했는데 설계에서 한 번 꼬이니까 당황했고 평소보다 더 시간이 걸렸다.</p>\n<p>구현 자체는 프리코스 미션들 난이도랑 크게 다르지 않았고 지금까지 해왔던 방식 그대로 구현했다.<br>\n하지만 중간에 구조를 살짝 다시 바꾸는 등 시간이 조금 걸렸고, 그래서 전체 5시간 중에서 4시간 반 정도 지났을 때 쯤 전체 구현을 완료했고 기본 테스트를 통과할 수 있었다.</p>\n<p>20분 정도 남아서 부랴부랴 제출 페이지에 제출하고 리팩토링을 시작했다.<br>\n프리코스 마지막 미션에서는 프로그래밍 요구사항 중에 <code class=\"language-text\">메서드 파라미터는 3개로 제한한다</code>라는 요구사항이 있었기 때문에 이번에도 이 요구사항을 지키려고 노력했는데 이 요구사항을 지키지 못한 메서드를 하나 발견했다.<br>\n하지만 이를 고치려면 클래스를 하나 나눠야했었는데, 이 때 쯤 남은 시간이 10분 정도 밖에 안남았고 이번 요구사항 중에는 없었기 때문에 찝찝하지만 넘기기로 했다..</p>\n<p>또한 이번 요구사항 중에는 테스트 관련 요구사항이 없었고, 최종 코테 시작 전에 <code class=\"language-text\">안 돌아가는 프로그램보다 돌아가는 쓰레기가 낫다.</code>라는 말이 있었기 때문에 평소에는 기능 하나를 구현하면 그 기능에 대한 단위 테스트를 만들고 넘어갔지만 이번에는 우선 구현에만 집중했다.<br>\n생각보다 구현에 시간이 오래걸려서 단위 테스트를 하나도 만들지 못하고 제출했는데 이 점이 코딩 테스트가 끝나고도 남은 2주 동안 가장 마음에 걸렸었다,,</p>\n<hr>\n<p>구현은 다 완료했고 돌아가는 쓰레기라도 만들었기 때문에 전체적으로 만족했다.<br>\n하지만 단위 테스트를 하나도 만들지 못한 점과 리팩토링을 제대로 하지 못한 점은 끝나고도 마음에 걸렸다.<br>\n특히 끝나고 나가는 길에 구현이 끝나고도 2시간이나 남았다는 사람의 말을 듣고 엄청 충격이었다,, 이런 괴물들과 같은 선 상에 섰던 것만으로도 만족스럽다는 생각을 하며 2주를 기다렸다.</p>\n<p>12월 28일.\n결과 발표를 기다리다가 너무 긴장될 것 같아서 아무 생각 안하려고 한 시간 전부터 롤이나 했다,,<br>\n신기하게도 발표 1분 전에 게임이 끝나서 로그인 하고 메일을 확인했는데</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.111111111111114%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACN0lEQVQoz22OWVPaUABGb+7NHjALWQBDFiNBIIkF0UIYsQEaFrWIsigKVDvU+tIZ35zpS396h7Zv7Xk4T9+Z+QAkU0RCp4UCK5bJhMMIB0RyHzE5QKoYIWO4BJAIkAAgD7AkABzAWAxjINoaQEqEpMQJVsY8sdwoazUNN844bc2sK1lfVF1JzfMpW1QcSXV4yeD4DMGIGGIhZAGiZQD5/EHteva4WH2fP7wun94my7f188/15sfFeDO/fxndrDu9ye3DZnb71OuPHTcAgIJEEkBKQoyMaDkhGHLW291rpo2G6w3KlctS5SrvXxr5aNd+n9aDtF5S0vkEv4soAVE8hicBolM4o+CMKiiOW27sF0On1KmFd/3Rc/vjMuquovgxPJsfHceVasvz64pqMZxMMCIkeYDobUmwGs5qml7eK9QLfuRVL7vDr5+uXz60po2TYbPeb4VxK+wW3UNN0SVBYzmRpHkAySROSwSXwRlNyRZr9d5J4zxsjXuDx8Xi9fPy9WG+Wc1Ws+FodbPoht3ADcxMThJSHCeA32CITJCJLCdaklZUM55hVoJy6zy+m46eplfryWAyiUeDZrtSCk6r9apbMjRF3Pkbb0EEi1M8yaRSsmPmfM89OqtFF6fDaTxZXS2/3X/pNE5pgojeHbYPfc/M6YoK/oXnRct0S3nPzlm2btTKwbFfGcf9i07Xte1mcb9Z2LM1WUzu/CfGMAwAIEmSZVuGaVAUtf0FIU2SCCEcx3EI/0x/Af8gWm237gMPAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"final-result.png\"\n        title=\"final-result.png\"\n        src=\"/static/420cad732304bdbb8b8612a713957b1f/37523/final-result.png\"\n        srcset=\"/static/420cad732304bdbb8b8612a713957b1f/e9ff0/final-result.png 180w,\n/static/420cad732304bdbb8b8612a713957b1f/f21e7/final-result.png 360w,\n/static/420cad732304bdbb8b8612a713957b1f/37523/final-result.png 720w,\n/static/420cad732304bdbb8b8612a713957b1f/302a4/final-result.png 1080w,\n/static/420cad732304bdbb8b8612a713957b1f/07a9c/final-result.png 1440w,\n/static/420cad732304bdbb8b8612a713957b1f/29114/final-result.png 1920w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>합격이었다..<br>\n정말 2022년 마지막이라고 생각했던 라스트 댄스가 성공해서 너무 기뻤고 믿기지 않았다.<br>\n단위 테스트랑 리팩토링이 부족해서 남들보다 기준치에 약간 밀리지 않을까 걱정했었는데 아마 이번에도 내가 생각했던 방향과 우테코가 원했던 방향이 맞았던 것 아닐까 생각한다.<br>\n기초부터 탄탄히 설계를 잘한 다음에 돌아가는 쓰레기를 만들어 놓으면, 그 다음 과정은 우테코에서 가르치겠다는 그런 뜻이 아닐까</p>\n<hr>\n<p><a href=\"https://github.com/Go-Jaecheol/java-menu/tree/Go-Jaecheol\">구현 코드 확인</a></p>\n<div class=\"table-of-contents\">\n<ul>\n<li>\n<p><a href=\"#-%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4%EA%B0%80-%EB%81%9D%EB%82%98%EA%B3%A0-%EC%B5%9C%EC%A2%85-%EC%BD%94%ED%85%8C%EA%B9%8C%EC%A7%80\">👏 프리코스가 끝나고 최종 코테까지</a></p>\n</li>\n<li>\n<p><a href=\"#-%EC%B5%9C%EC%A2%85-%EC%BD%94%EB%94%A9-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%8B%9C%EC%9E%91\">👋 최종 코딩 테스트 시작!</a></p>\n</li>\n<li>\n<p><a href=\"#-%EC%B5%9C%EC%A2%85-%EC%BD%94%EB%94%A9-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EB%AF%B8%EC%85%98-%EC%86%8C%EA%B0%9C\">🎞 최종 코딩 테스트 미션 소개</a></p>\n<ul>\n<li><a href=\"#-%EA%B8%B0%EB%8A%A5-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD\">🚀 기능 요구 사항</a></li>\n<li><a href=\"#%EC%8B%A4%ED%96%89-%EA%B2%B0%EA%B3%BC-%EC%98%88%EC%8B%9C\">실행 결과 예시</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#-%EC%B5%9C%EC%A2%85-%EC%BD%94%EB%94%A9-%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%9B%84%EA%B8%B0\">🙏 최종 코딩 테스트 후기</a></p>\n</li>\n</ul>\n</div>","excerpt":"우테코 프리코스 그리고 최종 코테가 끝난지도 한달이 지났다. 다시 한 달 전의 기억을 살려서 최종 코딩 테스트 후기를 써보려고 한다. 지금까지 썼던 회고와는 다르게 일기 느낌으로다가,, 👏 프리코스가 끝나고 최종 코테까지 11월 23일. 4주 동안의 프리코스 과정이 끝났다. 프리코스가 끝나고 바로 들었던 생각은 ‘떨어져도 괜찮을 것 같다’였다. 자바를 싫어하고 자바에 대해서 1학년 수준의 기초 밖에 모르는 상태에서 시작했던 프리코스였기 때문에 이미 이 4주 동안의 프리코스 과정만으로도 많은 것들을 배웠다는 생각이 들었다. 게다가 프리코스를 진행하면서 각 주차가 끝나고 다른 사람들의 코드를 봤을 때, 나랑은 완전 차원이 다르게 잘하는 사람이 많구나라고 생각했다. 각 주차가 끝나고 쓰는 소감문도 정말 간단하게 해당 주차에 새롭게 배운 핵심 내용들만 적었던 나로서는 ‘나보다 더 간절한 사람이 붙겠지’라는 생각만 들었다. 그리고 12월 14일 1차 심사 결과가 나왔다.  그렇게 큰 기대를…","frontmatter":{"date":"January 18, 2023","title":"[우아한테크코스] 우테코 최종 코딩 테스트 후기","categories":"우테코","author":"JFe","emoji":"🍽"},"fields":{"slug":"/wooteco-pre-final/"}},"next":{"id":"81630d85-48b2-5713-b505-7a065a91988f","html":"<p>프리코스 끝난지 한달 됐는데 아직 회고 쓰는 사람이 있다..?! 그게 나야<br>\n사실 3주차 회고를 쓰는 중에 프리코스 결과가 발표났다.</p>\n<p>하나도 기대 안하고 있다가 발표 났다는 소식을 듣고 확인했는데, 어떻게 된 건지는 몰라도 됐다,,,<br>\n엄청 당황했지만 바로 힘들게 기차 표 예매하고, 최종 코테 대비하고, 토요일에 최종 코테 치러 서울 갔다 오고 하다 보니 시간이 바쁘게 빠르게 지나갔다,,,</p>\n<p>그리고 솔직히 말하면 프리코스 결과 발표는 하나도 기대 안했지만, 최종 코테는 정말 이게 올해 마지막이라는 마음에 간절해졌었다.<br>\n그러다보니 회고 쓰려고 프리코스 다시 보면 최종 코테에서 못한 것들이 생각나고 집중이 안돼서 회고는 최종 코테 발표날 때까지 넣어두고 다른 일들부터 했다.<br>\n한 달 뒤에 쓰는 회고도 그 때 생각을 다시 떠올리고, 그 때 생각 못했던 것들도 다시 떠올릴 수 있어서 나름 괜찮은 것 같다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 37.77777777777778%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABTUlEQVQoz4VS2W6DMBDkT5I2JCTc4IPLGAhHjjZ5qdT//5OpvISqVav2YWRr18zOzGJJNYAVHdw4w8r28OyEeNoF37DUzPkfrCRrkOYtIlEjEgohVzQgljXSfO75afEn4dfhFi+PKLsLoWjPyPWEZrpDjzdUxysirrDZRz9U/+aCFMp6tmw+5lUPoUakeYckb5HpE/y0pL6sJ0RCU80g1yfIeoSoBsRSI2QVHJ/BMhk24x318Ao93MCKFka1sWuIhOrByw5OwEmBfYgJm8dJ9300W3cCWDufIdMTRNUTwRKBUVA05zmO9kJZunEOx+fYeQyHKKMhWy+F4TB1201geUmO8faO/voG1b9gWZKxz8sFRwg1EEwvYNWn1YCVCHlFSz2EEpZhLrsrqUkyTY8ZWW4RywZSjbT5IC0JJqeV7WK1cek3W289rG3vcffxAWGS/y2LzWOnAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"programming-requirement.png\"\n        title=\"programming-requirement.png\"\n        src=\"/static/ee7df65f98f23100918d6d80650a5690/37523/programming-requirement.png\"\n        srcset=\"/static/ee7df65f98f23100918d6d80650a5690/e9ff0/programming-requirement.png 180w,\n/static/ee7df65f98f23100918d6d80650a5690/f21e7/programming-requirement.png 360w,\n/static/ee7df65f98f23100918d6d80650a5690/37523/programming-requirement.png 720w,\n/static/ee7df65f98f23100918d6d80650a5690/302a4/programming-requirement.png 1080w,\n/static/ee7df65f98f23100918d6d80650a5690/07a9c/programming-requirement.png 1440w,\n/static/ee7df65f98f23100918d6d80650a5690/010dc/programming-requirement.png 1714w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>이번 4주차 미션도 저번 주차 미션보다 <strong>기능 요구 사항</strong>과 <strong>프로그래밍 요구 사항</strong>이 많아졌다.<br>\n특히 함수의 길이가 15라인에서 10라인으로 타이트하게 줄어든 것을 볼 수 있고, 메서드의 파라미터 개수도 3개로 타이트하게 제한했다.</p>\n<p>그리고 이번 4주차 미션의 전체적인 학습 목표는 다음과 같다.</p>\n<ol>\n<li><strong>클래스(객체)를 분리하는 연습</strong></li>\n<li><strong>리팩터링</strong></li>\n</ol>\n<hr>\n<h2 id=\"-4주차-미션-소개\" style=\"position:relative;\"><a href=\"#-4%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%EC%86%8C%EA%B0%9C\" aria-label=\" 4주차 미션 소개 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🎞 4주차 미션 소개</h2>\n<p><a href=\"https://github.com/woowacourse-precourse/java-bridge\">4주차 미션 소개</a></p>\n<h3 id=\"-기능-요구-사항\" style=\"position:relative;\"><a href=\"#-%EA%B8%B0%EB%8A%A5-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD\" aria-label=\" 기능 요구 사항 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🚀 기능 요구 사항</h3>\n<p>위아래 둘 중 하나의 칸만 건널 수 있는 다리를 끝까지 건너가는 게임이다.</p>\n<ul>\n<li>위아래 두 칸으로 이루어진 다리를 건너야 한다.\n<ul>\n<li>다리는 왼쪽에서 오른쪽으로 건너야 한다.</li>\n<li>위아래 둘 중 하나의 칸만 건널 수 있다.</li>\n</ul>\n</li>\n<li>다리의 길이를 숫자로 입력받고 생성한다.\n<ul>\n<li>다리를 생성할 때 위 칸과 아래 칸 중 건널 수 있는 칸은 0과 1 중 무작위 값을 이용해서 정한다.</li>\n<li>위 칸을 건널 수 있는 경우 U, 아래 칸을 건널 수 있는 경우 D값으로 나타낸다.</li>\n<li>무작위 값이 0인 경우 아래 칸, 1인 경우 위 칸이 건널 수 있는 칸이 된다.</li>\n</ul>\n</li>\n<li>다리가 생성되면 플레이어가 이동할 칸을 선택한다.\n<ul>\n<li>이동할 때 위 칸은 대문자 U, 아래 칸은 대문자 D를 입력한다.</li>\n<li>이동한 칸을 건널 수 있다면 O로 표시한다. 건널 수 없다면 X로 표시한다.</li>\n</ul>\n</li>\n<li>다리를 끝까지 건너면 게임이 종료된다.</li>\n<li>다리를 건너다 실패하면 게임을 재시작하거나 종료할 수 있다.\n<ul>\n<li>재시작해도 처음에 만든 다리로 재사용한다.</li>\n<li>게임 결과의 총 시도한 횟수는 첫 시도를 포함해 게임을 종료할 때까지 시도한 횟수를 나타낸다.</li>\n</ul>\n</li>\n<li>사용자가 잘못된 값을 입력할 경우 <code class=\"language-text\">IllegalArgumentException</code>를 발생시키고, “[ERROR]“로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다.\n<ul>\n<li><code class=\"language-text\">Exception</code>이 아닌 <code class=\"language-text\">IllegalArgumentException</code>, <code class=\"language-text\">IllegalStateException</code> 등과 같은 명확한 유형을 처리한다.</li>\n</ul>\n</li>\n</ul>\n<p>…</p>\n<h3 id=\"실행-결과-예시\" style=\"position:relative;\"><a href=\"#%EC%8B%A4%ED%96%89-%EA%B2%B0%EA%B3%BC-%EC%98%88%EC%8B%9C\" aria-label=\"실행 결과 예시 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>실행 결과 예시</h3>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">다리 건너기 게임을 시작합니다.\n\n다리의 길이를 입력해주세요.\n3\n\n이동할 칸을 선택해주세요. (위: U, 아래: D)\nU\n[ O ]\n[   ]\n\n이동할 칸을 선택해주세요. (위: U, 아래: D)\nU\n[ O | X ]\n[   |   ]\n\n게임을 다시 시도할지 여부를 입력해주세요. (재시도: R, 종료: Q)\nR\n이동할 칸을 선택해주세요. (위: U, 아래: D)\nU\n[ O ]\n[   ]\n\n이동할 칸을 선택해주세요. (위: U, 아래: D)\nD\n[ O |   ]\n[   | O ]\n\n이동할 칸을 선택해주세요. (위: U, 아래: D)\nD\n[ O |   |   ]\n[   | O | O ]\n\n최종 게임 결과\n[ O |   |   ]\n[   | O | O ]\n\n게임 성공 여부: 성공\n총 시도한 횟수: 2</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">다리 건너기 게임을 시작합니다.\n\n다리의 길이를 입력해주세요.\n3\n\n이동할 칸을 선택해주세요. (위: U, 아래: D)\nU\n[ O ]\n[   ]\n\n이동할 칸을 선택해주세요. (위: U, 아래: D)\nU\n[ O | X ]\n[   |   ]\n\n게임을 다시 시도할지 여부를 입력해주세요. (재시도: R, 종료: Q)\nQ\n최종 게임 결과\n[ O | X ]\n[   |   ]\n\n게임 성공 여부: 실패\n총 시도한 횟수: 1</code></pre></div>\n<hr>\n<h2 id=\"-이번-미션을-통해-배운-점\" style=\"position:relative;\"><a href=\"#-%EC%9D%B4%EB%B2%88-%EB%AF%B8%EC%85%98%EC%9D%84-%ED%86%B5%ED%95%B4-%EB%B0%B0%EC%9A%B4-%EC%A0%90\" aria-label=\" 이번 미션을 통해 배운 점 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>👨‍💻 이번 미션을 통해 배운 점</h2>\n<h3 id=\"-요구-사항에-맞게-설계하기\" style=\"position:relative;\"><a href=\"#-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD%EC%97%90-%EB%A7%9E%EA%B2%8C-%EC%84%A4%EA%B3%84%ED%95%98%EA%B8%B0\" aria-label=\" 요구 사항에 맞게 설계하기 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ 요구 사항에 맞게 설계하기</h3>\n<p>지금까지 미션을 진행하면서 클래스 구조를 어떻게 하면 잘 설계할 수 있을지에 대해 많이 고민했다.<br>\n그래서 지금까지 <strong>MVC 패턴</strong>에 가깝게 미션에 맞는 클래스 구조를 설계했고, 마지막으로 4주차 미션에서는 비슷한 방식으로 설계하되 지난 주차 미션에서 아쉬웠던 점들을 보완하고자 했다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 37.77777777777778%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABTUlEQVQoz4VS2W6DMBDkT5I2JCTc4IPLGAhHjjZ5qdT//5OpvISqVav2YWRr18zOzGJJNYAVHdw4w8r28OyEeNoF37DUzPkfrCRrkOYtIlEjEgohVzQgljXSfO75afEn4dfhFi+PKLsLoWjPyPWEZrpDjzdUxysirrDZRz9U/+aCFMp6tmw+5lUPoUakeYckb5HpE/y0pL6sJ0RCU80g1yfIeoSoBsRSI2QVHJ/BMhk24x318Ao93MCKFka1sWuIhOrByw5OwEmBfYgJm8dJ9300W3cCWDufIdMTRNUTwRKBUVA05zmO9kJZunEOx+fYeQyHKKMhWy+F4TB1201geUmO8faO/voG1b9gWZKxz8sFRwg1EEwvYNWn1YCVCHlFSz2EEpZhLrsrqUkyTY8ZWW4RywZSjbT5IC0JJqeV7WK1cek3W289rG3vcffxAWGS/y2LzWOnAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"programming-requirement.png\"\n        title=\"programming-requirement.png\"\n        src=\"/static/ee7df65f98f23100918d6d80650a5690/37523/programming-requirement.png\"\n        srcset=\"/static/ee7df65f98f23100918d6d80650a5690/e9ff0/programming-requirement.png 180w,\n/static/ee7df65f98f23100918d6d80650a5690/f21e7/programming-requirement.png 360w,\n/static/ee7df65f98f23100918d6d80650a5690/37523/programming-requirement.png 720w,\n/static/ee7df65f98f23100918d6d80650a5690/302a4/programming-requirement.png 1080w,\n/static/ee7df65f98f23100918d6d80650a5690/07a9c/programming-requirement.png 1440w,\n/static/ee7df65f98f23100918d6d80650a5690/010dc/programming-requirement.png 1714w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>4주차 미션에 추가된 프로그래밍 요구 사항에는 각 클래스 별로 제한 사항들이 많이 있었다.<br>\n그 중에서도 <code class=\"language-text\">BridgeGame 클래스에서 InputView, OutputView 를 사용하지 않는다.</code> 이 부분에 주목했다.<br>\n일단 저번 주차 미션에서 아쉬웠던 점 중 하나로 <code class=\"language-text\">InputView</code> 클래스를 만들지 않았다는 점이 있었다. <code class=\"language-text\">OutputView</code> 클래스는 구현했지만 <code class=\"language-text\">InputView</code> 클래스를 구현하지 않았었는데, 이번에는 <code class=\"language-text\">InputView</code> 클래스를 요구 사항에서부터 주었기 때문에 이 점은 쉽게 해결할 수 있었다.<br>\n하지만 지금까지 <code class=\"language-text\">InputView</code>, <code class=\"language-text\">OutputView</code> 클래스의 메서드들을 <code class=\"language-text\">service</code> 클래스에서 사용하고 <strong>Controller</strong>는 따로 구현하지 않는 방식으로 했었는데, 이번에는 요구사항에 <code class=\"language-text\">BridgeGame 클래스에서 InputView, OutputView 를 사용하지 않는다.</code> 이런 문구가 있어서 <strong>Controller</strong>와 <strong>Service</strong>를 확실하게 분리하여 구현하라는 말로 해석했다.<br>\n이전처럼 <code class=\"language-text\">InputView</code>, <code class=\"language-text\">OutputView</code> 클래스의 메서드들은 각 도메인에 해당하는 <code class=\"language-text\">service</code> 클래스에서 호출하여 사용하고, 하나의 <code class=\"language-text\">BridgeGame</code>이라는 <strong>Controller</strong> 클래스에서 각 상황에 필요한 <strong>service</strong> 메서드들을 호출하여 사용하는 방식으로 구현했다.</p>\n<p>또한 이전 미션까지는 잘못된 값을 입력한 경우 <strong>IllegalArgumentException</strong>을 발생시키고, 에러 메세지를 출력한 후 종료하는 방식으로 예외 처리를 했었다.<br>\n하지만 이번 미션부터는 기능 요구사항에서 <code class=\"language-text\">사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, \"[ERROR]\"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다.</code>라는 방식으로 예외 처리 방식이 바뀌었다.<br>\n그래서 이 부분도 반복문 안에서 try-catch 문을 사용하여 예외 상황이 발생하면 계속 반복하는 방식으로 구현했다.</p>\n<hr>\n<h3 id=\"-getter를-사용하는-대신-객체에-메시지를-보내자\" style=\"position:relative;\"><a href=\"#-getter%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EB%8C%80%EC%8B%A0-%EA%B0%9D%EC%B2%B4%EC%97%90-%EB%A9%94%EC%8B%9C%EC%A7%80%EB%A5%BC-%EB%B3%B4%EB%82%B4%EC%9E%90\" aria-label=\" getter를 사용하는 대신 객체에 메시지를 보내자 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ getter를 사용하는 대신 객체에 메시지를 보내자</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 101.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAABYlAAAWJQFJUiTwAAAC2klEQVQ4y5VUTU8aYRDev+DFpIdaDLAL+8HCsrALC1ygR1H/jL1USptsf40xGr1RCj1x0ESj8UD9/iwmBi3ECJj4NPPiq4EabEmePDPvMs/M7sw7ws3NDZaWlrC2toZSqYTV1VXUajXGKysruLy8xP/8hFarhe3tbdTrdZydnWFzcxNbW1s4ODhgOD09xcXFBfb399FoNFgC8umc/OPjY5yfnzO/1+tB6HQ6aF5f43erjV+NBvb29nB1dYVmswmqnhISt9ttPDw8vF7hz3odbvEj3C+f4H4uwHVduO5XFObnUSgU/gnFYhFzH+awsbEBofytBO/bNzACHhiBdzBkHzQliKAsQ9M0SJIEVVURDAYxMTHxIiYnJzE2NoaFhQUIlUoVgUAAjhmCZUaQSCRg2xaSySQymQwsy4LjOIjH49DDOksyjHA4zESXl5dJsAJJFGHoGmxDZcG2nUA0GmWCxKFQiAUqigJZlvusyAxk0zOqlKblWTCsQVNlhDSVZYxEIgMiHIoiD/lDgt+ZoJ9Vl47KSNsmsrn3rFIuygOHxV4UrFarkKQANC0EXaWHKnRdH6hsuMqRgj+qVShB6mS/AuooxyihEYIVRFURGVNFJq4jlUohm83CcZIsQf9VledXfu0bUlNEvx+xiAYnmWCCjpOCHdURNyOIWxbCj+My0OFRgn6/H7KisiYQTNNk40IgOxaL/f0ZlFcE6ZCGmAY7nU7Dtm0mRExn1HXyn2dxZJclNrwUTIE00CRCCUicmG6KYRgDTeOgqfB4PP2bUi6XmTq/s/wqkS0/3meqwufzwev1vghRFDE+Po7FxUUI6+vrmJmZwezsLPL5PKamphjI5j7x9HT+kacZuE1MsblcDlScQHtuZ2cHR0dHDIeHhzg5OXkCLV06p0XKbQI9o93Jlyvx/f09BFqeJLi7u8sWKy3cu7s73N7eMuY+odvtPtmdTv8//Kzb67IF+webxIg3kr3DNgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"class-getter.png\"\n        title=\"class-getter.png\"\n        src=\"/static/d966db650789e46670d02434b5a901c8/37523/class-getter.png\"\n        srcset=\"/static/d966db650789e46670d02434b5a901c8/e9ff0/class-getter.png 180w,\n/static/d966db650789e46670d02434b5a901c8/f21e7/class-getter.png 360w,\n/static/d966db650789e46670d02434b5a901c8/37523/class-getter.png 720w,\n/static/d966db650789e46670d02434b5a901c8/302a4/class-getter.png 1080w,\n/static/d966db650789e46670d02434b5a901c8/46115/class-getter.png 1290w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>3주차 피드백을 보면 위와 같이 <code class=\"language-text\">객체는 객체스럽게 사용한다</code>라는 피드백이 있다.<br>\n<strong>getter</strong> 사용해서 데이터를 직접 꺼내는 방식을 지양하고 메시지를 직접 던져주는 방식을 지향하자라는 피드백이다.<br>\n피드백으로 이전 주차 미션을 예시로 간단하게 코드를 통해 설명하고 다음의 참고 문서도 제공해주었다.</p>\n<p>참고 : <a href=\"https://tecoble.techcourse.co.kr/post/2020-04-28-ask-instead-of-getter/\">getter를 사용하는 대신 객체에 메시지를 보내자</a></p>\n<p>해당 피드백에서는 이전 주차 미션을 예시로 간단하게 코드를 통해 설명해주었지만 메시지를 던져준다는 말이 어떤 방식인지 잘 이해가 되지 않았다. 그래서 위의 링크로 들어가 문서를 참고했다.<br>\n2주차 미션에서 3주차 미션으로 넘어오면서 <strong>setter</strong>를 사용하는 방식을 지양하도록 주의하며 구현했다. 하지만 <strong>getter</strong> 사용은 크게 문제가 되지 않을 거라고 생각했는데 그렇지 않았다.<br>\n<strong>getter</strong>를 사용해서 데이터를 직접 주고 받는 방식을 사용하면, 이 또한 외부에서 값을 변경할 수 있다는 위험성이 조금이나마 생기게 된다.<br>\n이를 보고 피드백과 위 문서에서는 객체스럽지 못하다고 설명하고 있다.</p>\n<p>또한, <strong>getter</strong>를 남용하면 <code class=\"language-text\">디미터의 법칙</code>을 위반할 가능성이 생긴다고 설명하고 있다.<br>\n<code class=\"language-text\">디미터의 법칙</code>은 다른 객체가 어떤 데이터를 가지고 있는지 서로 모르게 하여 객체 간의 결합도를 낮춰야 한다는 법칙이다.<br>\n그렇기 때문에 <strong>getter</strong>를 사용해서 데이터를 직접 주고 받는 방식보다는 필요한 메시지만 주고 받는 메서드를 만들어서 이를 호출하는 방식으로 구현해야 <code class=\"language-text\">디미터의 법칙</code>을 위반하지 않게 구현할 수 있을 것이다.</p>\n<p>따라서 이번 미션에서는 최대한 <strong>getter</strong>를 지양하는 방향으로 주의하며 객체를 객체스럽게 구현하고자 했다.</p>\n<hr>\n<h3 id=\"-enum\" style=\"position:relative;\"><a href=\"#-enum\" aria-label=\" enum permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ Enum!!</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 62.77777777777778%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACOElEQVQ4y4WSwU/aYBjG+S+8TAsVFNpSaCnQ0g7bjYKZ7N/aAZMpY4GxsxfjyQMYr3hkM5nGiyaCF/8A49X8ln4DdWK2Jk/e533zvU+f78sTG52cMP7xk19nZ1xeXnJ6esrt7S2T6ZSbmxvBr66uOD8/F/zi4oLRaMTx8THj8ZiHhweef7HPrU90O216X9t87/fpdL7wrdej0+nQ6/Xoi1mHdrtNt9tld3eX7e1tWq0WOzs77O3tsb+/z8HBAXd3d8TS8ht8t4xTNCnaLjnLRslb6GaRVDJJMpkklUqxtrb2WNfX1wUivrq6iiRJor++viYWT8hsNZtUgxpGycV+9wE3bFIsO2iqiqZpC1BVVSDi2WxWcNM0mU6nxGRZptncoroRYJRdKuFHio6LomRQZov/QyaTIZ/PPwnWajUc9y0F26NQclAjMUVBUWdQlKf+RV0QjEsSjm1jmKYYqopCVtcfrxItvuZqLrogmJCWCUoa1UKGiqmy4fuEYShc53I5cViZCUdc9Mo/HS5TsXSsvIZl5ikYeSyrgFOpiIeO3lJT0ui6jmEYYvGl+78EpZVlnEKWoKzj+wG+5xD4G7iehx8Egr+vujhOBdu2cRxH/Gh+7QXBFUkSroJSFs/zCMM6jUaDcrmM67rU63Uam5tYliUWn0dmHpvIaeReCC4tLYlQRnlMJBLE43EBWU686GUR4jmifj6LzqXTaSaTCbHDw0OGwyHD4WBWX8dgMHgdwz/16OiI+/t7fgPTlQdZDxZZHgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"requirement-enum.png\"\n        title=\"requirement-enum.png\"\n        src=\"/static/13a1d35bacaee1057f788a870946a26b/37523/requirement-enum.png\"\n        srcset=\"/static/13a1d35bacaee1057f788a870946a26b/e9ff0/requirement-enum.png 180w,\n/static/13a1d35bacaee1057f788a870946a26b/f21e7/requirement-enum.png 360w,\n/static/13a1d35bacaee1057f788a870946a26b/37523/requirement-enum.png 720w,\n/static/13a1d35bacaee1057f788a870946a26b/302a4/requirement-enum.png 1080w,\n/static/13a1d35bacaee1057f788a870946a26b/9cea8/requirement-enum.png 1278w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>이전 주차 미션에서도 Enum을 사용했지만 그 때는 처음 접하는 거라 어떤 상황에서 사용해야 하는지, 어떻게 사용해야 하는지 잘 모르는 상태로 사용했다.<br>\n그렇기 때문에 이번 미션에서는 Enum에 대해 정리된 여러 문서들을 참고해서 Enum에 대해 알아본 후 구현했다.</p>\n<p>우선 이번 미션에서는 다리를 생성하기 위해 <code class=\"language-text\">BridgeNumberGenerator</code>를 사용하는데 여기서는 0과 1 중 랜덤한 정수 값이 반환된다.<br>\n그러면 이 정수 값들을 저장해서 생성된 다리 정보를 저장해야 하는데 처음 요구 사항에서 주어진 <code class=\"language-text\">makeBridge</code> 메서드의 반환 값은 <code class=\"language-text\">List&lt;String></code>이다.<br>\n따라서 랜덤 생성된 정수 값을 문자열로 반환해서 저장하는 과정이 필요했고, 이 과정을 Enum을 사용하여 해결하면 되겠다고 생각했다.</p>\n<p><strong>1</strong>이면 <code class=\"language-text\">\"U\"</code>, <strong>0</strong>이면 <code class=\"language-text\">\"D\"</code>로 반환해주면 됐기 때문에 이 값들을 각각 매핑해주고 필드 값들을 추가했다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">enum</span> <span class=\"token class-name\">Position</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">UP</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"U\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token function\">DOWN</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"D\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">int</span> positionNumber<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">String</span> positionValue<span class=\"token punctuation\">;</span>\n\n    <span class=\"token class-name\">Position</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> positionNumber<span class=\"token punctuation\">,</span> <span class=\"token class-name\">String</span> positionValue<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>positionNumber <span class=\"token operator\">=</span> positionNumber<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>positionValue <span class=\"token operator\">=</span> positionValue<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span></code></pre></div>\n<p>다음으로 이 <code class=\"language-text\">positionNumber</code>를 <code class=\"language-text\">positionValue</code>로 변환해주는 기능이 필요했는데, 다음과 같은 메서드를 만들고 <strong>stream</strong>을 이용해 값을 반환하도록 했다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">static</span> <span class=\"token class-name\">String</span> <span class=\"token function\">convertNumberToValue</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> number<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token class-name\">Arrays</span><span class=\"token punctuation\">.</span><span class=\"token function\">stream</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Position</span><span class=\"token punctuation\">.</span><span class=\"token function\">values</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span>position <span class=\"token operator\">-></span> position<span class=\"token punctuation\">.</span>positionNumber <span class=\"token operator\">==</span> number<span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">.</span><span class=\"token function\">findAny</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">.</span><span class=\"token function\">orElseThrow</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">IllegalArgumentException</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"[ERROR] 0 또는 1의 값만 가능합니다.\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">.</span>positionValue<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>또한 게임의 성공 여부를 출력하는 부분에서도 불필요한 <strong>if</strong>문이 반복되어서 이를 해결하기 위해 <strong>Enum</strong>을 사용해야겠다고 생각해 리팩토링했다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">void</span> <span class=\"token function\">printIsSuccess</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">boolean</span> status<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>status<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">System</span><span class=\"token punctuation\">.</span>out<span class=\"token punctuation\">.</span><span class=\"token function\">println</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"게임 성공 여부: 성공\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>status<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">System</span><span class=\"token punctuation\">.</span>out<span class=\"token punctuation\">.</span><span class=\"token function\">println</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"게임 성공 여부: 실패\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>위와 같이 <code class=\"language-text\">status</code> 불리언 값에 따라 출력 값이 달라지는 경우였다.<br>\n하지만 이렇게 <strong>if</strong>문을 나눠서 사용하는 것은 <strong>else</strong> 예약어를 사용하지 말라는 요구 사항에도 맞지 않다고 생각했고, <strong>Enum</strong>을 사용해 해결할 수 있을 거라 생각했다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">enum</span> <span class=\"token class-name\">Status</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">SUCCESS</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"성공\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token function\">FAIL</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"실패\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">boolean</span> check<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">String</span> message<span class=\"token punctuation\">;</span>\n\n    <span class=\"token class-name\">Status</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">boolean</span> check<span class=\"token punctuation\">,</span> <span class=\"token class-name\">String</span> message<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>check <span class=\"token operator\">=</span> check<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>message <span class=\"token operator\">=</span> message<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">static</span> <span class=\"token class-name\">String</span> <span class=\"token function\">convertCheckToMessage</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">boolean</span> check<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token class-name\">Arrays</span><span class=\"token punctuation\">.</span><span class=\"token function\">stream</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Status</span><span class=\"token punctuation\">.</span><span class=\"token function\">values</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span>status <span class=\"token operator\">-></span> status<span class=\"token punctuation\">.</span>check <span class=\"token operator\">==</span> check<span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">findAny</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">orElseThrow</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">IllegalArgumentException</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span>message<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>앞선 <code class=\"language-text\">Position</code> <strong>enum 클래스</strong>와 거의 비슷하게 <code class=\"language-text\">Status</code> <strong>enum 클래스</strong>를 만들고,<br>\n<strong>boolean</strong> 값을 <strong>String</strong> 값으로 변환해주는 메서드도 만들었다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">void</span> <span class=\"token function\">printIsSuccess</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">boolean</span> status<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token class-name\">System</span><span class=\"token punctuation\">.</span>out<span class=\"token punctuation\">.</span><span class=\"token function\">println</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"게임 성공 여부: \"</span> <span class=\"token operator\">+</span> <span class=\"token class-name\">Status</span><span class=\"token punctuation\">.</span><span class=\"token function\">convertCheckToMessage</span><span class=\"token punctuation\">(</span>status<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>이를 이용해 위에서 <strong>if</strong>문이 반복되어 문제가 되었던 코드도 한 줄로 깔끔하게 리팩토링 할 수 있었다.</p>\n<hr>\n<h2 id=\"-keep\" style=\"position:relative;\"><a href=\"#-keep\" aria-label=\" keep permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🔒 Keep</h2>\n<ul>\n<li><strong>요구 사항</strong>을 반영하면서 <strong>MVC 패턴</strong>에 가깝게 설계하기</li>\n<li><strong>getter</strong>를 사용하는 대신에 <strong>필요한 메시지</strong>만 주고 받는 메서드를 만들어서 사용하기</li>\n<li>불필요하게 if문이 반복되는 코드가 있으면 <strong>Enum</strong>을 이용해 리팩토링하기</li>\n</ul>\n<h2 id=\"-problem\" style=\"position:relative;\"><a href=\"#-problem\" aria-label=\" problem permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🚧 Problem</h2>\n<ul>\n<li>설계와 구현은 열심히 했지만 <strong>다양한 상황</strong>에 대한 <strong>테스트 코드</strong> 작성이 아직 부족함</li>\n<li>여전히 <strong>getter</strong>가 필요하다고 판단해서 사용한 곳들이 있는데, 이 때 외부에서 <strong>값이 변경될 가능성</strong>이 있음</li>\n<li><code class=\"language-text\">OutputView</code>에 단순하게 정해진 문자열만 출력하면 되는 메서드들이 있음(<strong>Enum</strong>을 사용하면 관리하기 보다 편할 것 같음)</li>\n</ul>\n<h2 id=\"-try\" style=\"position:relative;\"><a href=\"#-try\" aria-label=\" try permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🎯 Try</h2>\n<ul>\n<li><strong>테스트 코드</strong> 작성에도 집중하자</li>\n<li>getter 사용이 필요한 경우에는 <code class=\"language-text\">Collections.unmodifiableList()</code> 같은 <strong>Unmodifiable Collection</strong>을 사용하자</li>\n<li>정해진 문자열을 출력하는 부분도 <strong>Enum</strong> 사용 고려해보자</li>\n</ul>\n<hr>\n<p><a href=\"https://github.com/Go-Jaecheol/java-bridge/tree/Go-Jaecheol\">구현 코드 확인</a></p>\n<div class=\"table-of-contents\">\n<ul>\n<li>\n<p><a href=\"#-4%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%EC%86%8C%EA%B0%9C\">🎞 4주차 미션 소개</a></p>\n<ul>\n<li><a href=\"#-%EA%B8%B0%EB%8A%A5-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD\">🚀 기능 요구 사항</a></li>\n<li><a href=\"#%EC%8B%A4%ED%96%89-%EA%B2%B0%EA%B3%BC-%EC%98%88%EC%8B%9C\">실행 결과 예시</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#-%EC%9D%B4%EB%B2%88-%EB%AF%B8%EC%85%98%EC%9D%84-%ED%86%B5%ED%95%B4-%EB%B0%B0%EC%9A%B4-%EC%A0%90\">👨‍💻 이번 미션을 통해 배운 점</a></p>\n<ul>\n<li><a href=\"#-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD%EC%97%90-%EB%A7%9E%EA%B2%8C-%EC%84%A4%EA%B3%84%ED%95%98%EA%B8%B0\">✅ 요구 사항에 맞게 설계하기</a></li>\n<li><a href=\"#-getter%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EB%8C%80%EC%8B%A0-%EA%B0%9D%EC%B2%B4%EC%97%90-%EB%A9%94%EC%8B%9C%EC%A7%80%EB%A5%BC-%EB%B3%B4%EB%82%B4%EC%9E%90\">✅ getter를 사용하는 대신 객체에 메시지를 보내자</a></li>\n<li><a href=\"#-enum\">✅ Enum!!</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#-keep\">🔒 Keep</a></p>\n</li>\n<li>\n<p><a href=\"#-problem\">🚧 Problem</a></p>\n</li>\n<li>\n<p><a href=\"#-try\">🎯 Try</a></p>\n</li>\n</ul>\n</div>","frontmatter":{"date":"December 28, 2022","title":"[우아한테크코스] 우테코 프리코스 4주차 회고","categories":"우테코","author":"JFe","emoji":"🌉"},"fields":{"slug":"/wooteco-pre-4/"}},"prev":{"id":"57123275-3f75-54a2-8337-7e90489cf625","html":"<p>우테코를 시작한지 한 달.. 드디어 여유가 생겼다.<br>\n생각보다 빠르게 한 달이 지나갔다. 미션 회고도 쓰고 여러 블로그 글도 쓰고 싶었지만, 미션 진행하고 우테코 생활 적응하는 것만으로도 바빠서 못하고 있었다. 사실 글 쓸 때 쓰고 지우고 고민하느라 시간이 많이 걸리는 게 한 몫 했다ㅎ,,<br>\n이미 <code class=\"language-text\">자동차 경주</code> 미션과 <code class=\"language-text\">사다리 타기</code> 미션을 끝내고 <code class=\"language-text\">블랙잭</code> 미션을 진행하고 있지만 늦게나마 지난 미션들을 회고해보려 한다.</p>\n<p>자동차 경주 미션은 우테코에 들어와서 진행한 첫 미션이다.<br>\n모든 미션은 2개의 단계로 나뉘는데, 1단계는 페어 프로그래밍으로 진행하고 2단계는 혼자서 진행한다. 각 단계가 끝나면 리뷰어에게 코드 리뷰를 받고, 피드백을 반영하여 머지 되면 다음 단계를 진행하는 방식으로 한다.</p>\n<p>사실 처음 미션을 시작하기 전에는 페어 프로그래밍이 무서웠다.<br>\n하나의 노트북으로 같이 페어 프로그래밍을 진행하면 내 실력이 낱낱이 드러날까봐 그게 무서웠다. 물론 지금도 어떤 페어와 매칭이 될지 미션이 시작하기 전에는 떨리긴 하지만 막상 시작하면 생각했던 것만큼 힘들진 않았다. 같이 했던 페어들이 엄청 편하게 대해줬고 새로운 의견을 얘기할 때도 항상 다른 의견은 없는지 배려해줘서 편하게 페어 프로그래밍을 할 수 있었다.^^</p>\n<hr>\n<h2 id=\"-1단계---자동차-경주-구현\" style=\"position:relative;\"><a href=\"#-1%EB%8B%A8%EA%B3%84---%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B2%BD%EC%A3%BC-%EA%B5%AC%ED%98%84\" aria-label=\" 1단계   자동차 경주 구현 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🎞 1단계 - 자동차 경주 구현</h2>\n<p><a href=\"https://github.com/woowacourse/java-racingcar/pull/520\">1단계 PR</a></p>\n<h3 id=\"-1단계-기능-요구-사항-정리\" style=\"position:relative;\"><a href=\"#-1%EB%8B%A8%EA%B3%84-%EA%B8%B0%EB%8A%A5-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\" aria-label=\" 1단계 기능 요구 사항 정리 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🚀 1단계 기능 요구 사항 정리</h3>\n<ul>\n<li>\n<p>자동차 이름 입력</p>\n<ul>\n<li>자동차 이름 입력 문구 출력하는 기능</li>\n<li>자동차 이름 입력받는 기능</li>\n<li>문자열을 쉼표(,)로 구분하여 배열로 저장하는 기능\n<ul>\n<li>각 자동차의 이름이 5자 이하인지 확인하는 기능</li>\n<li>자동차의 이름이 영어 대소문자, 숫자가 아닌 경우 예외 처리</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p>시도할 횟수 입력</p>\n<ul>\n<li>시도할 횟수 입력 문구 출력하는 기능</li>\n<li>시도할 횟수 입력받는 기능\n<ul>\n<li>숫자가 아닌 경우 예외 처리</li>\n<li>0 이하의 숫자가 입력될 경우 예외 처리</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p>게임 실행</p>\n<ul>\n<li>실행 결과 문구 출력하는 기능</li>\n<li>입력된 횟수 만큼 라운드를 반복하는 기능</li>\n<li>자동차의 시작 위치가 0이 아닌 경우 예외 처리</li>\n<li>자동차의 현재 위치가 해당 라운드보다 큰 경우 예외 처리</li>\n</ul>\n</li>\n<li>\n<p>라운드 실행</p>\n<ul>\n<li>각 자동차 마다 0 ~ 9 사이의 random 값 구하는 기능</li>\n<li>random 값이 4 이상인지 확인하는 기능</li>\n<li>random 값이 4 이상이면 해당 자동차의 이동 거리를 증가시키는 기능</li>\n<li>각 라운드의 실행 결과를 출력하는 기능</li>\n</ul>\n</li>\n<li>\n<p>결과</p>\n<ul>\n<li>최종 이동 결과를 출력하는 기능</li>\n<li>가장 이동 거리가 큰 자동차를 찾는 기능</li>\n<li>우승자를 출력하는 기능</li>\n</ul>\n</li>\n</ul>\n<hr>\n<h3 id=\"-일급-컬렉션-사용\" style=\"position:relative;\"><a href=\"#-%EC%9D%BC%EA%B8%89-%EC%BB%AC%EB%A0%89%EC%85%98-%EC%82%AC%EC%9A%A9\" aria-label=\" 일급 컬렉션 사용 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ 일급 컬렉션 사용</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 35%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABHklEQVQoz33Ry26DMBCFYV6kakmAgMEGG2zMJQTSbqouuuj7P8tfkVurJurim2Nb8mhkB7nuMN2C9jPGz9Td8US3M9rtGboaYx1Z6RFV+w9PKi1B9TrgPmfc+4IfOuy0p1lm9LQn9xblDbkzpLZGuOahbM22ITU1gXxrab4mmo8J42v6wdJPHfowIEePHDuqw4gcW1KnSVtzoS9+1jujCWw/EhcFoVAkypLkFbEoiXNNUhiSQpNIQ1xotqJ8KBIViaxPGZTaI5SjqluMkTxtC17iP6JzhrEkTO5tEsU2LdnsFMFzXLB+TNMvaNefHlc1A4XpkHWPasbbPlPu3GCn7lzPg7WI0lL6I1thibKSKNNEWXVnneJ6MdzJm98NvwHzNtiYsSodfgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"first-class-collection.png\"\n        title=\"first-class-collection.png\"\n        src=\"/static/544f0206402a3c4701c0bcc0ff7c38c7/37523/first-class-collection.png\"\n        srcset=\"/static/544f0206402a3c4701c0bcc0ff7c38c7/e9ff0/first-class-collection.png 180w,\n/static/544f0206402a3c4701c0bcc0ff7c38c7/f21e7/first-class-collection.png 360w,\n/static/544f0206402a3c4701c0bcc0ff7c38c7/37523/first-class-collection.png 720w,\n/static/544f0206402a3c4701c0bcc0ff7c38c7/302a4/first-class-collection.png 1080w,\n/static/544f0206402a3c4701c0bcc0ff7c38c7/07a9c/first-class-collection.png 1440w,\n/static/544f0206402a3c4701c0bcc0ff7c38c7/6ee58/first-class-collection.png 1640w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>미션을 시작하기 전에는 나도 페어도 <code class=\"language-text\">일급 컬렉션</code>이 뭔지 몰랐다.<br>\n일급 컬렉션이 뭔지 모르니 일급 컬렉션을 써야겠다는 생각도 하진 못했고, 그냥 단순하게 구현해야겠다고 생각하고 구현했다.</p>\n<p>그러다가 자동차의 이름과 진행 상황(자동차 위치)을 어떻게 저장할지에 대해 페어랑 고민하게 됐다.<br>\n처음에는 <strong>HashMap</strong>으로 자동차 이름이랑 진행 상황들을 저장해야겠다고 생각했다.<br>\n그러면 <code class=\"language-text\">Car</code>라는 클래스에서 이름이랑 위치를 가지도록 하고, <code class=\"language-text\">Car</code>들을 <strong>List</strong>로 저장해두는 방식이 더 깔끔하지 않을까?<br>\n어, 이게 <code class=\"language-text\">일급 컬렉션</code>인가???<br>\n이렇게 페어랑 고민하는 과정을 거쳤고, 일급 컬렉션이 뭔지 알게 되었다.</p>\n<p>이번 미션에서 가장 많이 배웠고 뿌듯하다고 생각한 부분이다.<br>\n일급 컬렉션이 뭔지 알고 적용했다는 점도 중요하지만, 사용해야 하는 이유를 직접 페어랑 고민하며 찾아가는 과정을 거쳤다는 점이 뿌듯했다.<br>\n한 단계 더 성장했다는 느낌을 직접 받을 수 있었고, 이런 부분이 페어 프로그래밍을 하는 가장 큰 이유라고 생각한다.</p>\n<h3 id=\"-mvc-패턴에서-controller의-역할\" style=\"position:relative;\"><a href=\"#-mvc-%ED%8C%A8%ED%84%B4%EC%97%90%EC%84%9C-controller%EC%9D%98-%EC%97%AD%ED%95%A0\" aria-label=\" mvc 패턴에서 controller의 역할 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ MVC 패턴에서 Controller의 역할</h3>\n<p><strong>MVC 패턴</strong>을 사용하고, <strong>Controller</strong>와 <strong>Service</strong>를 나누도록 구현했다.<br>\n하지만 여전히 <strong>Controller</strong>나 <strong>Service</strong>의 제대로 된 역할을 알지 못한 채 구현했다.</p>\n<p>처음에는 <strong>Service</strong>에서 진행에 관한 기능도 다 담당하고, 입출력에 대한 책임도 담당하도록 했다.<br>\n이렇게 했을 때 문제점은 <strong>Service</strong>가 <strong>View</strong>와 관계를 가지고 서로 의존하게 된다.<br>\n여기서 <strong>Service</strong>는 <strong>MVC 패턴</strong>에서 <strong>Model</strong>의 역할을 분리한 계층 중 하나다.<br>\n<strong>MVC 패턴</strong>에서는 <strong>Model</strong>과 <strong>View</strong>가 직접 소통하지 않고 <strong>Controller</strong>를 거쳐서 소통한다. 그게 <strong>Controller</strong>의 역할이다.<br>\n하지만 이렇게 되면 <strong>Service</strong>가 <strong>View</strong>와 소통하며 <strong>Controller</strong>의 역할을 하게 되고, <strong>Controller</strong>가 필요 없어진다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 63.888888888888886%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAABT0lEQVQ4y5VT2XKCQBDkTxKRQ47FZUEOAUWjiTHn//9Mp2Y4QhElxUPX1k7t9vTM9GiezBCme4iogBMkMN0Qy9UahiP51O0AC1tAtwWfHThuCdh+BOIwPcUxzQszyGTHpCqrEcQlgqhAmO7gq7z/2BGPCSlxJ4IJ6ZOItngwPDyaBJ9Bjzv8VSd+kwzeETTbj5GUJ1ZExEFcTCpb3Ci9A901klwcXpHXF+4HyTfc8G7v/oO2dCSivIbcVBBqyyopyZQ6fSKmWZ6Cyuu+zH6y1nx1TEiqqIc07eEw5pL1CkkRWSatzpBJNehdMBv9UGggRGq15hxbYQ5ahY2JqeRJBe2g6M8tsLHJIo3bFa+eLWKsxAaWHzHISnSnuLNOeMXoveGE7Sn7OxMm1Rn1yxfKpzfszh8oj1dUp3cUxyvH9s+fOFy+eT1dmTaWGm3SsOQfYAqGe1l2O50AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"MVC-controller.png\"\n        title=\"MVC-controller.png\"\n        src=\"/static/7b218cc55e1ff5eb65e88700d6857203/37523/MVC-controller.png\"\n        srcset=\"/static/7b218cc55e1ff5eb65e88700d6857203/e9ff0/MVC-controller.png 180w,\n/static/7b218cc55e1ff5eb65e88700d6857203/f21e7/MVC-controller.png 360w,\n/static/7b218cc55e1ff5eb65e88700d6857203/37523/MVC-controller.png 720w,\n/static/7b218cc55e1ff5eb65e88700d6857203/302a4/MVC-controller.png 1080w,\n/static/7b218cc55e1ff5eb65e88700d6857203/07a9c/MVC-controller.png 1440w,\n/static/7b218cc55e1ff5eb65e88700d6857203/098c1/MVC-controller.png 1578w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p><code class=\"language-text\">그러면 Service가 너무 많은 책임을 가지지 않을까요?</code><br>\n라는 피드백을 받았고, 기존 코드에 문제점이 있다는 사실과 내가 <strong>MVC 패턴</strong>을 잘못 알고 있었다는 사실도 인지할 수 있었다.</p>\n<h3 id=\"-상수를-별도의-enum으로-분리한-이유\" style=\"position:relative;\"><a href=\"#-%EC%83%81%EC%88%98%EB%A5%BC-%EB%B3%84%EB%8F%84%EC%9D%98-enum%EC%9C%BC%EB%A1%9C-%EB%B6%84%EB%A6%AC%ED%95%9C-%EC%9D%B4%EC%9C%A0\" aria-label=\" 상수를 별도의 enum으로 분리한 이유 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ 상수를 별도의 enum으로 분리한 이유</h3>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">enum</span> <span class=\"token class-name\">CarConstant</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">NAME_MAX_LENGTH</span><span class=\"token punctuation\">(</span><span class=\"token number\">5</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token function\">NAME_MIN_LENGTH</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">int</span> number<span class=\"token punctuation\">;</span>\n\n    <span class=\"token class-name\">CarConstant</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> number<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>number <span class=\"token operator\">=</span> number<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">int</span> <span class=\"token function\">getNumber</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> number<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>처음에는 이렇게 <code class=\"language-text\">CarConstant</code>와 같이 상수를 <strong>enum</strong>으로 모아두고 사용했다.<br>\n하지만 상수를 <strong>enum</strong>으로 분리한 이유를 묻는 피드백을 받았고, <strong>enum</strong>으로 분리할 때와 안할 때 차이점을 고민해보았다.</p>\n<p>우선 <strong>enum</strong>을 사용한 가장 큰 이유는 가독성 때문이다.<br>\n필요한 상수의 개수가 많아지면 그만큼 클래스가 길어지고, 가독성이 안좋아질 것 같다고 생각해서 상수 클래스로 따로 분리하기로 결정했다.<br>\n상수만을 위한 클래스를 따로 만든다면 <strong>enum</strong>을 사용하는 것이 어떻겠냐고 페어가 의견을 제시했고, 단순히 <strong>static final</strong>로 상수를 선언하는 것보다 <strong>enum</strong>을 사용하면 가독성도 좋아지고 컴파일 단계에서 에러를 확인할 수 있는 등 장점이 많은 것 같다고 생각해서 <strong>enum</strong>을 사용하기로 했다.</p>\n<p>하지만 리뷰어의 피드백 중에 다음과 같은 의견이 있었다.<br>\n<code class=\"language-text\">Car가 어떤 역할을 하는지 알기위해 Car, CarConstant 두 클래스를 다 확인해야 알 것 같네요!</code><br>\n이 의견을 듣고나니 상수 클래스의 분리가 오히려 더 복잡한 과정을 요구하는 것 같다는 생각이 들었다.<br>\n객체는 그 자체로 의미를 갖는 게 좋은데, <code class=\"language-text\">Car</code>의 이름 최대 길이, 최소 길이 등과 같은 제약 사항도 일종의 <code class=\"language-text\">Car</code>의 속성이고 <code class=\"language-text\">Car</code> 클래스를 보았을 때 한눈에 파악되면 좋을 것 같다는 의견이었다.</p>\n<p><strong>enum</strong>을 사용하기로 마음 먹은 가장 큰 이유가 가독성 때문이었는데, 과연 <strong>enum</strong>을 사용하지 않으면 가독성이 떨어질까??<br>\n리뷰어의 의견을 보고 다시 한 번 고민해보니 어떤 방식이 더 나은지 결정할 수 있었다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 79.44444444444444%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAACM0lEQVQ4y21U6XraQAz0g7SFBB/4vg22scEcTRMa8v5PM/1G613gS38M0h5oR9LI1jBO+PniYp3UAtvP4AS5sat1hhc3/oZXL3my+r7lBjnSaoesGRGXHdJ6ENDPN3tERYvVOv2GpROZYDowYXGRb0aU7YRmuKDZncVW3RFlN8m63b+hn97Ftoc/2AwXeHFlgkpgTwW2uAizLZKqF2ZJtRPGcdmj2B4MQ6Zkz6XQYJBHlhKQP15Uwk8bedUNC5MW//Q6p7e0QyzsUPlOOEP5vGtS9sIcZXeU1FjHtN4hyDaIiw5BupnRCFPWlWdhvhVERSeZ6VKxqcKQl5mqSlvZ+3pAlLfmMaLY7pHVg8mGzGhNDbNmQN2fVCPaCUV7kA7Tr/qT1FL2twcJzCYSfIiZsN4kQNYSUMtFsZgbQ/mInNQ+kZT9U1OoOyco4ISFsBUdslM8dMMSXlRhHdfGulE5o1LncQU/aeYhaOCEtex58z1aYVi2B9FXf7xi//sL4+Umtp8+MJw/xb/v3zBevjC9XXE89QiyDnHRmiZZv+xICh3PHVOTolJlGrrgK/95Uux1AtePsLAjvLiRkZBVNR1+LB2pA1PVeiKU9gIsVsGDBu9YOLEJxvssnVXUHfykniUxCEt2TTdCdXUv+9QjG8jJoj5pKTktO9Hh0omxO10xXj7RHz8wnv9ilLrdZH7V2Q3d9C7S0bLiQ5QR5UOfkuOj1mqdyNiR7uMI/Q96nvXn7XG29d4/eLD0LREFa4UAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"constant-enum.png\"\n        title=\"constant-enum.png\"\n        src=\"/static/8140bf6b2424999e834a19b315197559/37523/constant-enum.png\"\n        srcset=\"/static/8140bf6b2424999e834a19b315197559/e9ff0/constant-enum.png 180w,\n/static/8140bf6b2424999e834a19b315197559/f21e7/constant-enum.png 360w,\n/static/8140bf6b2424999e834a19b315197559/37523/constant-enum.png 720w,\n/static/8140bf6b2424999e834a19b315197559/302a4/constant-enum.png 1080w,\n/static/8140bf6b2424999e834a19b315197559/07a9c/constant-enum.png 1440w,\n/static/8140bf6b2424999e834a19b315197559/5df5d/constant-enum.png 1572w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<hr>\n<h2 id=\"-2단계---자동차-경주-리팩터링\" style=\"position:relative;\"><a href=\"#-2%EB%8B%A8%EA%B3%84---%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B2%BD%EC%A3%BC-%EB%A6%AC%ED%8C%A9%ED%84%B0%EB%A7%81\" aria-label=\" 2단계   자동차 경주 리팩터링 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🎞 2단계 - 자동차 경주 리팩터링</h2>\n<p><a href=\"https://github.com/woowacourse/java-racingcar/pull/634\">2단계 PR</a></p>\n<h3 id=\"-2단계-리팩토링-요구-사항-정리\" style=\"position:relative;\"><a href=\"#-2%EB%8B%A8%EA%B3%84-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\" aria-label=\" 2단계 리팩토링 요구 사항 정리 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🚀 2단계 리팩토링 요구 사항 정리</h3>\n<ul>\n<li>enum으로 선언한 CarConstant를 Car 클래스 내부로 이동</li>\n<li>enum으로 선언한 InputConstant, OutputConstant를 OutputView 클래스 내부로 이동</li>\n<li>시도 횟수 검증에 대한 메서드를 Controller에서 Service로 이동</li>\n<li>distance에서 position으로 네이밍 변경</li>\n<li>Car 클래스의 책임 분리\n<ul>\n<li>Name 클래스 분리</li>\n<li>Position 클래스 분리</li>\n</ul>\n</li>\n<li>while문 대신 try-catch문 안에서 반복할 수 있도록 변경</li>\n<li>findWinner 메서드에 대한 책임 이동</li>\n<li>현재 위치 검증에 대한 메서드 위치 변경</li>\n<li>자동차 전진을 할 때 전략 패턴을 사용하도록 변경</li>\n<li>부족한 테스트 코드 작성</li>\n</ul>\n<hr>\n<h3 id=\"-전략-패턴-사용\" style=\"position:relative;\"><a href=\"#-%EC%A0%84%EB%9E%B5-%ED%8C%A8%ED%84%B4-%EC%82%AC%EC%9A%A9\" aria-label=\" 전략 패턴 사용 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ 전략 패턴 사용</h3>\n<p>랜덤 값 테스트를 위해 전략 패턴을 사용했다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">interface</span> <span class=\"token class-name\">MoveStrategy</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">boolean</span> <span class=\"token function\">isMovable</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>먼저 <code class=\"language-text\">MoveStrategy</code>라는 interface를 만들고, 목적에 맞게 이를 구현하는 <code class=\"language-text\">RandomMoveStrategy</code>와 <code class=\"language-text\">FixedMoveStrategy</code> 클래스를 만들었다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">RandomMoveStrategy</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">MoveStrategy</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">int</span> RANDOM_NUMBER_BOUNDARY <span class=\"token operator\">=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">boolean</span> <span class=\"token function\">isMovable</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">Random</span> random <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Random</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> random<span class=\"token punctuation\">.</span><span class=\"token function\">nextInt</span><span class=\"token punctuation\">(</span>RANDOM_NUMBER_BOUNDARY<span class=\"token punctuation\">)</span> <span class=\"token operator\">>=</span> <span class=\"token class-name\">Car</span><span class=\"token punctuation\">.</span>FORWARD_BOUNDARY<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><code class=\"language-text\">RandomMoveStrategy</code>에서는 랜덤 값을 생성해서 해당 랜덤 값이 4 이상이면 <code class=\"language-text\">isMovable</code> 메서드에서 <em><strong>true</strong></em>를 반환하고, 3 이하면 <em><strong>false</strong></em>를 반환하도록 구현했다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">FixedMoveStrategy</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">MoveStrategy</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">int</span> number<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">FixedMoveStrategy</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> number<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>number <span class=\"token operator\">=</span> number<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">boolean</span> <span class=\"token function\">isMovable</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> number <span class=\"token operator\">>=</span> <span class=\"token class-name\">Car</span><span class=\"token punctuation\">.</span>FORWARD_BOUNDARY<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><code class=\"language-text\">FixedMoveStrategy</code>에서는 특정 값을 파라미터로 받고, 해당 값이 4 이상이면 <code class=\"language-text\">isMovable</code> 메서드에서 <em><strong>true</strong></em>를 반환하고, 3 이하면 <em><strong>false</strong></em>를 반환하도록 구현했다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">run</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token class-name\">RandomMoveStrategy</span> randomMoveStrategy <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">RandomMoveStrategy</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">OutputView</span><span class=\"token punctuation\">.</span><span class=\"token function\">printResultMessage</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;=</span> tryCount<span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        carService<span class=\"token punctuation\">.</span><span class=\"token function\">runRound</span><span class=\"token punctuation\">(</span>randomMoveStrategy<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token class-name\">OutputView</span><span class=\"token punctuation\">.</span><span class=\"token function\">printRoundResult</span><span class=\"token punctuation\">(</span>carService<span class=\"token punctuation\">.</span><span class=\"token function\">getCarsStatus</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>이를 통해 프로덕션 코드에서는 <code class=\"language-text\">RandomMoveStrategy</code>를 사용해서 랜덤 값을 생성하도록 하고, 테스트 코드에서는 <code class=\"language-text\">FixedMoveStrategy</code>를 사용해서 랜덤 값이 아닌 특정 값으로 테스트를 할 수 있도록 변경했다.</p>\n<h3 id=\"-테스트는-어느-수준까지-고려해야-할까\" style=\"position:relative;\"><a href=\"#-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%8A%94-%EC%96%B4%EB%8A%90-%EC%88%98%EC%A4%80%EA%B9%8C%EC%A7%80-%EA%B3%A0%EB%A0%A4%ED%95%B4%EC%95%BC-%ED%95%A0%EA%B9%8C\" aria-label=\" 테스트는 어느 수준까지 고려해야 할까 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ 테스트는 어느 수준까지 고려해야 할까</h3>\n<p><code class=\"language-text\">입력 문자열을 split()으로 잘 분리가 되는지</code>, <code class=\"language-text\">random()에서 boundary에 맞게 랜덤 값이 잘 생성되는지</code><br>\n이런 테스트들도 고려해야 할까??<br>\n<code class=\"language-text\">split()</code>이나 <code class=\"language-text\">random()</code>은 자바에서 제공하는 함수들인데 이런 것들도 믿지 못하고 테스트를 만들어야 할까라는 의문이 들었다.<br>\n또한, 지금 구현한 코드에서 <code class=\"language-text\">runRound</code> 메서드는 <code class=\"language-text\">cars</code> 객체를 돌면서 각각 <code class=\"language-text\">runForward</code> 메서드를 실행하는 기능만 하고 있다.<br>\n이런 경우에 <code class=\"language-text\">runForward</code> 메서드에 대한 테스트를 구현했다면 <code class=\"language-text\">runRound</code> 메서드에 대한 테스트도 과연 필요할까..?</p>\n<p>이에 대한 리뷰어의 피드백은 다음과 같았다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 13.88888888888889%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAj0lEQVQI10WN7Q6CMAxFeRNNHMYx2PdgbCCo8f0f6ZpWIz9O7nq6tk3vC6QeoVyGspmz9zPTma83acUQCkxc2JPTseKqAk5C4dz2f5ppfSPVFyhjecKkBW7a4PMOO66w4x1hfnDSYvpD+Lyx06HysSFUPtTQMA3SAmpcbgZCWgjpfnlAvbZzDNX8Vv5wncMH5qxeXewGt1YAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"test-coverage.png\"\n        title=\"test-coverage.png\"\n        src=\"/static/eae42aecdb02610c2e60451daca41534/37523/test-coverage.png\"\n        srcset=\"/static/eae42aecdb02610c2e60451daca41534/e9ff0/test-coverage.png 180w,\n/static/eae42aecdb02610c2e60451daca41534/f21e7/test-coverage.png 360w,\n/static/eae42aecdb02610c2e60451daca41534/37523/test-coverage.png 720w,\n/static/eae42aecdb02610c2e60451daca41534/302a4/test-coverage.png 1080w,\n/static/eae42aecdb02610c2e60451daca41534/07a9c/test-coverage.png 1440w,\n/static/eae42aecdb02610c2e60451daca41534/a8a6f/test-coverage.png 1516w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>적극 공감한다.<br>\n이 외에도 자신이 생각하기에 신뢰가 간다면 테스트는 필요없다고 생각한다.<br>\n물론 단순히 귀찮아서 만들지 않는 건 안된다.<br>\n항상 자신만의 기준을 가지자!</p>\n<hr>\n<h2 id=\"-keep\" style=\"position:relative;\"><a href=\"#-keep\" aria-label=\" keep permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🔒 Keep</h2>\n<ul>\n<li><code class=\"language-text\">일급 컬렉션</code> 사용하기</li>\n<li>남들이 다 사용하는 기술이 있더라도 그 기술을 사용하지 않았을 때 단점과 장점을 직접 부딪혀보면서 알아보기</li>\n<li><strong>매직 넘버</strong> 상수화</li>\n<li><strong>기능 요구 사항</strong> 구체적으로 작성하기</li>\n<li><code class=\"language-text\">VO</code> 클래스 분리하기</li>\n</ul>\n<h2 id=\"-problem\" style=\"position:relative;\"><a href=\"#-problem\" aria-label=\" problem permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🚧 Problem</h2>\n<ul>\n<li><code class=\"language-text\">MVC 패턴</code>과 <code class=\"language-text\">전략 패턴</code>을 사용했지만 아직 깊게 공부하고 사용하진 않았음</li>\n<li>모든 요구 사항에 대한 <strong>테스트</strong> 부족</li>\n<li><strong>객체 책임 분리</strong>가 아직 명확하지 않음</li>\n</ul>\n<h2 id=\"-try\" style=\"position:relative;\"><a href=\"#-try\" aria-label=\" try permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🎯 Try</h2>\n<ul>\n<li>하나를 하더라도 그 행동에 대한 이유를 생각하고 행동하자</li>\n<li>모든 요구 사항에 대한 <strong>테스트 코드</strong>를 작성하도록 신경 쓰자</li>\n<li><strong>객체 책임 분리</strong>에 집중해서 설계하기</li>\n<li><code class=\"language-text\">TDD</code> 방식으로 개발해보기</li>\n</ul>\n<div class=\"table-of-contents\">\n<ul>\n<li>\n<p><a href=\"#-1%EB%8B%A8%EA%B3%84---%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B2%BD%EC%A3%BC-%EA%B5%AC%ED%98%84\">🎞 1단계 - 자동차 경주 구현</a></p>\n<ul>\n<li><a href=\"#-1%EB%8B%A8%EA%B3%84-%EA%B8%B0%EB%8A%A5-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\">🚀 1단계 기능 요구 사항 정리</a></li>\n<li><a href=\"#-%EC%9D%BC%EA%B8%89-%EC%BB%AC%EB%A0%89%EC%85%98-%EC%82%AC%EC%9A%A9\">✅ 일급 컬렉션 사용</a></li>\n<li><a href=\"#-mvc-%ED%8C%A8%ED%84%B4%EC%97%90%EC%84%9C-controller%EC%9D%98-%EC%97%AD%ED%95%A0\">✅ MVC 패턴에서 Controller의 역할</a></li>\n<li><a href=\"#-%EC%83%81%EC%88%98%EB%A5%BC-%EB%B3%84%EB%8F%84%EC%9D%98-enum%EC%9C%BC%EB%A1%9C-%EB%B6%84%EB%A6%AC%ED%95%9C-%EC%9D%B4%EC%9C%A0\">✅ 상수를 별도의 enum으로 분리한 이유</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#-2%EB%8B%A8%EA%B3%84---%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B2%BD%EC%A3%BC-%EB%A6%AC%ED%8C%A9%ED%84%B0%EB%A7%81\">🎞 2단계 - 자동차 경주 리팩터링</a></p>\n<ul>\n<li><a href=\"#-2%EB%8B%A8%EA%B3%84-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\">🚀 2단계 리팩토링 요구 사항 정리</a></li>\n<li><a href=\"#-%EC%A0%84%EB%9E%B5-%ED%8C%A8%ED%84%B4-%EC%82%AC%EC%9A%A9\">✅ 전략 패턴 사용</a></li>\n<li><a href=\"#-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%8A%94-%EC%96%B4%EB%8A%90-%EC%88%98%EC%A4%80%EA%B9%8C%EC%A7%80-%EA%B3%A0%EB%A0%A4%ED%95%B4%EC%95%BC-%ED%95%A0%EA%B9%8C\">✅ 테스트는 어느 수준까지 고려해야 할까</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#-keep\">🔒 Keep</a></p>\n</li>\n<li>\n<p><a href=\"#-problem\">🚧 Problem</a></p>\n</li>\n<li>\n<p><a href=\"#-try\">🎯 Try</a></p>\n</li>\n</ul>\n</div>","frontmatter":{"date":"March 18, 2023","title":"[우아한테크코스] Level 1 - 자동차 경주 회고","categories":"우테코","author":"JFe","emoji":"🏎"},"fields":{"slug":"/wooteco-racingcar/"}},"site":{"siteMetadata":{"siteUrl":"https://jfelog.netlify.app","comments":{"utterances":{"repo":"Go-Jaecheol/Jfe_Blog"}}}}},"pageContext":{"slug":"/wooteco-pre-final/","nextSlug":"/wooteco-pre-4/","prevSlug":"/wooteco-racingcar/"}},
    "staticQueryHashes": ["1073350324","1956554647","2938748437"]}