{
    "componentChunkName": "component---src-templates-blog-template-js",
    "path": "/wooteco-pre-4/",
    "result": {"data":{"cur":{"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>","excerpt":"프리코스 끝난지 한달 됐는데 아직 회고 쓰는 사람이 있다..?! 그게 나야 사실 3주차 회고를 쓰는 중에 프리코스 결과가 발표났다. 하나도 기대 안하고 있다가 발표 났다는 소식을 듣고 확인했는데, 어떻게 된 건지는 몰라도 됐다,,, 엄청 당황했지만 바로 힘들게 기차 표 예매하고, 최종 코테 대비하고, 토요일에 최종 코테 치러 서울 갔다 오고 하다 보니 시간이 바쁘게 빠르게 지나갔다,,, 그리고 솔직히 말하면 프리코스 결과 발표는 하나도 기대 안했지만, 최종 코테는 정말 이게 올해 마지막이라는 마음에 간절해졌었다. 그러다보니 회고 쓰려고 프리코스 다시 보면 최종 코테에서 못한 것들이 생각나고 집중이 안돼서 회고는 최종 코테 발표날 때까지 넣어두고 다른 일들부터 했다. 한 달 뒤에 쓰는 회고도 그 때 생각을 다시 떠올리고, 그 때 생각 못했던 것들도 다시 떠올릴 수 있어서 나름 괜찮은 것 같다.  이번 4주차 미션도 저번 주차 미션보다 기능 요구 사항과 프로그래밍 요구 사항이 많아졌다…","frontmatter":{"date":"December 28, 2022","title":"[우아한테크코스] 우테코 프리코스 4주차 회고","categories":"우테코","author":"JFe","emoji":"🌉"},"fields":{"slug":"/wooteco-pre-4/"}},"next":{"id":"a0e954df-dd46-51b5-a187-bc59ae2c1374","html":"<p>프리코스가 끝나자마자 바로 회고를 작성하려고 했는데 다른 일들을 하다 보니 생각보다 늦어졌다. 예전 프로젝트 회고를 작성하면서도 느꼈지만 블로그 글 쓰는 것부터가 아직 서툴고 회고를 쓰는 데 생각보다 시간이 오래 걸리는 것 같다,, 많이 쓰다 보면 나아지겠지</p>\n<p>2주차 미션이 끝나고 바로 3주차 미션이 시작되었다.<br>\n3주차 미션은 로또 게임 구현으로 이전 미션보다 <strong>기능 요구 사항</strong>이 많아졌고, <strong>프로그래밍 요구 사항</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: 34.44444444444444%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABKElEQVQoz2VR15KDMBDjU+6SUEIxYONGCQRSb/L/v6Ob3ZRL5h409nptSdYGdjhC+T10t2ArDL6jAqu4xCoWH9hsq39nhPv9vzpIhEGpB1RmRGV2KFQHaScWqO0E5fYsKFTHQt9RziTvRO/7IC4a6P4AO5yg/AzlJiRCI6sc0tIirQgOm23NLp9YJ3fyrzB/kRICKppuge4OaKcrE9d2ZMdNO7OIfvR5bQ9Q7cwm8tqz+IdDyo2+QwTSTYgyiTCtEWWK1zCTD3d3hKnkXpw3SAr9InySBvQdctYvN/jxgm7+AQ1qWG5wuzM789MVpj/CjRcWzioP0fQMypyE14+hBZRBVnt2SU2hehSy5UFJv4cZThyD6U+wuzNK3XOmdIcyzmXL74iDCH8BunTcWFZMB8cAAAAASUVORK5CYII='); 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/ae98237546623cdb959a516338e4639f/37523/programming-requirement.png\"\n        srcset=\"/static/ae98237546623cdb959a516338e4639f/e9ff0/programming-requirement.png 180w,\n/static/ae98237546623cdb959a516338e4639f/f21e7/programming-requirement.png 360w,\n/static/ae98237546623cdb959a516338e4639f/37523/programming-requirement.png 720w,\n/static/ae98237546623cdb959a516338e4639f/302a4/programming-requirement.png 1080w,\n/static/ae98237546623cdb959a516338e4639f/12470/programming-requirement.png 1311w\"\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>또한, 2주차 미션에서 추가로 다음과 같은 2가지 목표가 추가되었다.</p>\n<ol>\n<li><strong>클래스(객체)를 분리하는 연습</strong></li>\n<li><strong>도메인 로직에 대한 단위 테스트를 작성하는 연습</strong></li>\n</ol>\n<hr>\n<h2 id=\"-3주차-미션-소개\" style=\"position:relative;\"><a href=\"#-3%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%EC%86%8C%EA%B0%9C\" aria-label=\" 3주차 미션 소개 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>🎞 3주차 미션 소개</h2>\n<p><a href=\"https://github.com/woowacourse-precourse/java-lotto\">3주차 미션 소개</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<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">- 로또 번호의 숫자 범위는 1~45까지이다.\n- 1개의 로또를 발행할 때 중복되지 않는 6개의 숫자를 뽑는다.\n- 당첨 번호 추첨 시 중복되지 않는 숫자 6개와 보너스 번호 1개를 뽑는다.\n- 당첨은 1등부터 5등까지 있다. 당첨 기준과 금액은 아래와 같다.\n    - 1등: 6개 번호 일치 / 2,000,000,000원\n    - 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원\n    - 3등: 5개 번호 일치 / 1,500,000원\n    - 4등: 4개 번호 일치 / 50,000원\n    - 5등: 3개 번호 일치 / 5,000원</code></pre></div>\n<ul>\n<li>로또 구입 금액을 입력하면 구입 금액에 해당하는 만큼 로또를 발행해야 한다.</li>\n<li>로또 1장의 가격은 1,000원이다.</li>\n<li>당첨 번호와 보너스 번호를 입력받는다.</li>\n<li>사용자가 구매한 로또 번호와 당첨 번호를 비교하여 당첨 내역 및 수익률을 출력하고 로또 게임을 종료한다.</li>\n<li>사용자가 잘못된 값을 입력할 경우 <code class=\"language-text\">IllegalArgumentException</code>를 발생시키고, “[ERROR]“로 시작하는 에러 메시지를 출력 후 종료한다.</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\">구입금액을 입력해 주세요.\n8000\n\n8개를 구매했습니다.\n[8, 21, 23, 41, 42, 43] \n[3, 5, 11, 16, 32, 38] \n[7, 11, 16, 35, 36, 44] \n[1, 8, 11, 31, 41, 42] \n[13, 14, 16, 38, 42, 45] \n[7, 11, 30, 40, 42, 43] \n[2, 13, 22, 32, 38, 45] \n[1, 3, 5, 14, 22, 45]\n\n당첨 번호를 입력해 주세요.\n1,2,3,4,5,6\n\n보너스 번호를 입력해 주세요.\n7\n\n당첨 통계\n---\n3개 일치 (5,000원) - 1개\n4개 일치 (50,000원) - 0개\n5개 일치 (1,500,000원) - 0개\n5개 일치, 보너스 볼 일치 (30,000,000원) - 0개\n6개 일치 (2,000,000,000원) - 0개\n총 수익률은 62.5%입니다.</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=\"#-%ED%95%98%EB%82%98%EC%9D%98-%ED%95%A8%EC%88%98%EA%B0%80-%ED%95%9C-%EA%B0%80%EC%A7%80-%EA%B8%B0%EB%8A%A5%EB%A7%8C-%EB%8B%B4%EB%8B%B9%ED%95%98%EB%8F%84%EB%A1%9D\" 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>이전 2주차 미션에서도 필요한 기능을 먼저 나누고 구현하는 방식으로 진행했지만, 기능을 충분히 더 작은 단위로 분리할 수 있었기 때문에 아쉬움이 있었다.</p>\n<p>그래서 이번에도 <strong>전체 흐름</strong>을 먼저 정리하고 필요한 <strong>기능 목록</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: 36.11111111111111%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAvUlEQVQoz5WRSw6DMAxEc5S2kPINkBAgEGgpn/sfaaq4QmJXshjZC/tpxma6rNHbBc24ISlahEkFnipSEJe4PwUeUXFZLEgqlM0E2b1R9wuU+aBqXyShBm8o46mEHhbUZiao60VtkVYGUa5p6AC6+k/MOXBuGruiHXdou1LfTTti0eDGc7/IbsHdTnUzlJkpfms3CGWRyx5hKv0iO2AmDfTwc6XtRuDD2TnutafEJR3fxY6FBs8UffoM8HH4Bfas06YB7lbbAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"workflow.png\"\n        title=\"workflow.png\"\n        src=\"/static/c9665244260299c5e876456130abfa9b/37523/workflow.png\"\n        srcset=\"/static/c9665244260299c5e876456130abfa9b/e9ff0/workflow.png 180w,\n/static/c9665244260299c5e876456130abfa9b/f21e7/workflow.png 360w,\n/static/c9665244260299c5e876456130abfa9b/37523/workflow.png 720w,\n/static/c9665244260299c5e876456130abfa9b/302a4/workflow.png 1080w,\n/static/c9665244260299c5e876456130abfa9b/07a9c/workflow.png 1440w,\n/static/c9665244260299c5e876456130abfa9b/016a8/workflow.png 1576w\"\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><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: 77.77777777777777%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAABS0lEQVQ4y6VUSW7DMBDzS4pm875KsuUlTpyt//8RC44TtAl6sNIDoYMFDjmk7Gk7wvRnwcrPsA7yf8FT9ohMD9iEhRCu/PR+/sCJMFMdinpEbvaCtOqwjSvsYiV4DOLl10F/wSvrEZU9IsxrxIVFXFoEqUaQGkRFI+QuKr2yGaG7E5KyRZQ3gqTqkKpOhjyUOVmuhwtMP8OOXzIgUz12VOcaSmEGSZi2edJ2kBn4iRJCZ4WVPUC1E4p6L6RUx2DCrEb0jmUSSA+HM8rmIFb54WMT43OXPiW80HKPerhCdSdRyGSZ8Jy2+UWULQ+FKtlFVkjZCQ/V3KdzsVlmIWon6HaScjMQP9EC5x2yh6wNbRO6nUOh9fXLK1lcm2Z/hR1vYpXB0D7Ded7hUsu6v+/sIrYrOwkpX842Kt/7Oah2DoH743NjB8N7uV0JvwG8ZeP0arNl6wAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"function-list.png\"\n        title=\"function-list.png\"\n        src=\"/static/af1ddc102092256195012ba165cfb41e/37523/function-list.png\"\n        srcset=\"/static/af1ddc102092256195012ba165cfb41e/e9ff0/function-list.png 180w,\n/static/af1ddc102092256195012ba165cfb41e/f21e7/function-list.png 360w,\n/static/af1ddc102092256195012ba165cfb41e/37523/function-list.png 720w,\n/static/af1ddc102092256195012ba165cfb41e/302a4/function-list.png 1080w,\n/static/af1ddc102092256195012ba165cfb41e/07a9c/function-list.png 1440w,\n/static/af1ddc102092256195012ba165cfb41e/e405b/function-list.png 1566w\"\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이 때 기능이 최소 단위가 되도록 더 나눌 수 있으면 분리하는 방식으로 진행하며, 이 후 구현 과정에서 하나의 함수가 정말 한 가지 기능만 담당할 수 있도록 했다.</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: 85.55555555555556%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABYlAAAWJQFJUiTwAAADJUlEQVQ4y61UWU8aYRSdP2Ca9KG0YQsMtBQYhmGGYROKS9xaHvpbeGiiBqu4/AJf2yZG7LvxxRdN9KEBNW4xMdG4L+Cu4ALV09wPIdqHPnWSk3Pn3jvnux/hXO7s7Axzc3NYWFjA6uoq1tbWsLy8jJWVFczPz2NmZgbT09OYnZ3F0tISqP9fD3d5eYmNjQ0cHBxgb28P+/v7jLe3t1l+fX2dHUK5ra0tJnh7e4vr62vc3NywuFAoIJ/P4+7uDtz5+Tk2NzeRzWarooeHh4yPjo5YnmKq5XI5Jrqzs4Pd3V0WE+h7qhWLRXD39/coln7jfz1cJv0LnV/iSH5NoLu7G729vUgmk9WY0NXVhfb2dnR0dFS5s7OzikQigXg8jtHRUXA/vn/Dq5cv4PcqkCQPZI8HqqrC6XRAEJ1wCHbY7O/w1mYBbzXDarVCp9NBq9VWYTAYUFNTw8S5VCoFnregsbER9fX1iEajiEQi8Pv9CAe8CIdrWY4QDAbh8/ngdrvhcrmqkCQJJpMJAwMD4IaHUzDqtAgHVUSDXvh9KsLhMOrq6hD9EEFDQwOL6bBAIACHwwG73c64AhLV6/Xo6+sjwWEY9HqoqhceWYFXVaEoj9eXFXg8HjYRseSW4LCXBZ/iuWAqBT1N6JMR8ikIqApCoRACwSC7NgkRZFmGSxQgSgLjcuyC4HJCEAQYDI+CIz9HYLaa4PPLUGURkihAVhR4vV4GmrYCtyTCLbnKgi4SJUEBoijCaDSiv78f3NDQEN681sAjvIeDfhunEzxvhpnnwf8Fi8UCC28p8yOsFitsNhs0Gg16enrAjY2NIVxbi8+xNnz62IZYLIaWlha0trYyPI2bm5ur7xVuampiMf0DBgcHwRXyeebfbC7HrEa2IxuRtSimHNXJesfHx8yKVKN3ytMuuLq6Yky+5siH6XSabRdaBIuLi2zbjI+Psw1DoK0zNTXFemjjTE5OIpPJYGJiAqVS6bn1aGucnJww0AQVPj09ZUzb5eLigk1N0xIoT0w91E9Tkw4TpBVERfqQitREApVDKgdQD8VUo17K0SF0Vco9PDwwwT8sCpiT632XDAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"function-limit.png\"\n        title=\"function-limit.png\"\n        src=\"/static/9fbe71fd9511d755347381d65756193f/37523/function-limit.png\"\n        srcset=\"/static/9fbe71fd9511d755347381d65756193f/e9ff0/function-limit.png 180w,\n/static/9fbe71fd9511d755347381d65756193f/f21e7/function-limit.png 360w,\n/static/9fbe71fd9511d755347381d65756193f/37523/function-limit.png 720w,\n/static/9fbe71fd9511d755347381d65756193f/906b5/function-limit.png 950w\"\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>2주차 미션 공통 피드백 중 하나로 <code class=\"language-text\">함수가 한 가지 기능을 하는지 확인하는 기준을 세운다</code>가 있었다.</p>\n<p>기능 목록을 설계할 때, 가장 작은 단위로 기능을 분리하려고 했지만 그래도 여전히 더 분리할 수 있을 수도 있다.<br>\n이를 위해서 15라인 제한을 두었고, 구현 단계에서 만약 함수가 15라인을 넘어가면 기능 설계에 문제가 있었다는 것을 인지할 수 있도록 해 기능 분리와 함수 분리 연습에 많은 도움이 되었다.</p>\n<hr>\n<h3 id=\"-mvc-패턴\" style=\"position:relative;\"><a href=\"#-mvc-%ED%8C%A8%ED%84%B4\" aria-label=\" mvc 패턴 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 패턴..?</h3>\n<p><a href=\"https://jfelog.netlify.app/wooteco-pre-2/#-%ED%81%B4%EB%9E%98%EC%8A%A4-%EA%B5%AC%EC%A1%B0\">2주차 미션</a> 에서도 <strong>MVC 패턴</strong>에 가깝게 클래스 구조를 설계하려고 했지만 이 때는 MVC 패턴이 무엇인지 정확하게 모르고 있었기 때문에 이번 주차 미션에서는 MVC 패턴에 대해 공부한 후, 클래스 구조를 설계했다.</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: 50%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAm0lEQVQoz62SSw6DMBBDuQ2fYZKm0NCUlE9FlQgWLfc/jCui3mBYWJqVNc92dncvuD4grwcU9VOsrKg9TBdAesZxiw1z6tG6DXxdkJNHwdIPqQf7HaqNKHk4AVnPILsm5FMMD2R+fGC6DaQncY6pFOW/MHYFmwWlGmWGlRqhbhGVmpKk2BlrD+sjyLz/0xFmWF0mNMMO3YRTSvkBmeA7Ho3cpK8AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"structure-code.png\"\n        title=\"structure-code.png\"\n        src=\"/static/56e3c72d7b040aedc7cb1c6c96e70013/37523/structure-code.png\"\n        srcset=\"/static/56e3c72d7b040aedc7cb1c6c96e70013/e9ff0/structure-code.png 180w,\n/static/56e3c72d7b040aedc7cb1c6c96e70013/f21e7/structure-code.png 360w,\n/static/56e3c72d7b040aedc7cb1c6c96e70013/37523/structure-code.png 720w,\n/static/56e3c72d7b040aedc7cb1c6c96e70013/302a4/structure-code.png 1080w,\n/static/56e3c72d7b040aedc7cb1c6c96e70013/07a9c/structure-code.png 1440w,\n/static/56e3c72d7b040aedc7cb1c6c96e70013/8963a/structure-code.png 1918w\"\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\">view</code> 패키지를 만드는 것이었다.<br>\n<strong>MVC 패턴</strong>에서는 <strong>View</strong>를 통해서 사용자가 요청을 보내면 <strong>Controller</strong>가 <strong>Model</strong>에게 데이터를 받아서 처리하고, 처리한 데이터를 다시 <strong>View</strong>에게 보내서 출력한다.<br>\n그리고 이 미션에서 <strong>View</strong>는 콘솔 창이 담당한다. 그렇기 때문에 콘솔 창에서 받은 요청을 <strong>Controller</strong>에서 <strong>Model</strong>을 통해 데이터를 처리하는데, 이 때 이를 출력하는 것을 담당하는 메서드가 필요하다고 생각했다.<br>\n그래서 <code class=\"language-text\">view</code> 패키지에 <code class=\"language-text\">OutputView</code>라는 클래스를 만들었고, 콘솔 화면에 출력해야 되는 것들을 이 클래스에서 메서드를 만들어서 담당하도록 했다.</p>\n<p>여기서 한 가지 아쉬웠던 점이 있는데, 사용자 입력을 담당하는 <code class=\"language-text\">InputView</code> 클래스는 따로 만들지 않았다는 점이다.<br>\n출력을 담당하는 <code class=\"language-text\">OutputView</code>가 필요하다고 생각했으면 입력을 담당하는 <code class=\"language-text\">InputView</code>도 만들어야지라는 생각이 자연스럽게 들만한데 생각 못했다.. 아니. 굳이 이것까지 만들어야 하나..?라는 생각이 잠시 머리 속에 자리 잡고 있었던 것 같다…</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,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABBUlEQVQoz6WSy07DMBRE8ym4JW/bsZ3ESZpXFQIRhaoSLNjz//8wKJeXirpowmIWlqVzZ+5cRyYGIq3APAnmCTBfYvMPOUneQqQ7etyGCtsgwY3LCb4KaNt71MMBeTOi6icU3QNiXdLnN5T54mo59fCE4fCKbjzCNiOUbRGrEttQrQOKtAbXFXyewo0N3MicRV4CI6AueorrxQaRKggeiPyzoC9tlgCbu2ec3t4xPL6gHY/YTyeU/URFzQPmkpa4JYfKdoiSAr7ICBImFm6kCfZbzpUOudlBZjUCmdMemcd/drgqsswazJqBgcjoFs9va0UputwjlBbcVOR2jntpb3/hl4Z9ANbGSj42xRs9AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"structure.png\"\n        title=\"structure.png\"\n        src=\"/static/4507e35490beafa0b83a4bdf8e884fa6/37523/structure.png\"\n        srcset=\"/static/4507e35490beafa0b83a4bdf8e884fa6/e9ff0/structure.png 180w,\n/static/4507e35490beafa0b83a4bdf8e884fa6/f21e7/structure.png 360w,\n/static/4507e35490beafa0b83a4bdf8e884fa6/37523/structure.png 720w,\n/static/4507e35490beafa0b83a4bdf8e884fa6/302a4/structure.png 1080w,\n/static/4507e35490beafa0b83a4bdf8e884fa6/07a9c/structure.png 1440w,\n/static/4507e35490beafa0b83a4bdf8e884fa6/7831d/structure.png 2116w\"\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>다음으로 클래스 구조 측면에서 바꿨던 점은 <strong>service</strong> 부분이다.<br>\n이전 주차 미션처럼 MVC 패턴 중 <strong>Model</strong>에 해당하는 부분을 <code class=\"language-text\">domain</code> 패키지와 <code class=\"language-text\">service</code> 패키지로 나누어 구현했다.<br>\n<code class=\"language-text\">domain</code> 패키지에서 핵심 비즈니스 로직을 다루고, <code class=\"language-text\">service</code> 패키지에서는 비즈니스 로직에 필요한 작업들을 처리하도록 했다.<br>\n하지만 이번에 달라진 점은 <strong>domain</strong>에 맞춰서 <strong>service</strong>를 분리했다는 점이다.<br>\n이전 주차 미션에서는 비즈니스 로직에 대한 작업들을 처리하는 <code class=\"language-text\">service</code> 클래스를 하나만 만들어서 했지만, 이번 주차 미션에서는 <strong>domain</strong> 별로 나누어서 <code class=\"language-text\">service</code> 클래스를 만들었다.<br>\n<strong>service</strong>를 도메인 로직에 맞춰 분리하여 구현하면서 보다 관리하기 편하게 했고, <strong>Controller</strong> 역할은 기능 범위가 크지 않아서 <strong>main</strong>에 있는 <code class=\"language-text\">Application</code> 클래스에서 담당하도록 했다.</p>\n<p>마지막으로 <code class=\"language-text\">domain</code> 클래스에 값을 저장하는 방법도 바꿨다.<br>\n이전 주차 미션에서는 <strong>setter</strong>를 사용하여 값을 저장하는 방식을 사용했는데, <strong>setter</strong>를 사용하면 사용 의도를 알기 어렵고 값의 일관성을 유지하기 어렵다는 단점이 있다. 이런 이유 때문에 <strong>setter</strong> 사용은 지양하고 있고, 그래서 이번 주차에서는 생성자를 사용하는 방식으로 변경했다.<br>\n<strong>Setter 사용 지양</strong>과 관련해서는 추후 따로 포스팅할 예정이다.</p>\n<hr>\n<h3 id=\"-도메인-로직에-대한-단위-테스트\" style=\"position:relative;\"><a href=\"#-%EB%8F%84%EB%A9%94%EC%9D%B8-%EB%A1%9C%EC%A7%81%EC%97%90-%EB%8C%80%ED%95%9C-%EB%8B%A8%EC%9C%84-%ED%85%8C%EC%8A%A4%ED%8A%B8\" 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>2주차 미션에서도 단위 테스트 코드를 작성해서 테스팅을 진행했지만, 이 때는 정말 예제 코드를 따라서 몇 개 끄적여본 수준이었다.<br>\n이번에는 미션 목표에서부터 <code class=\"language-text\">도메인 로직에 대한 단위 테스트를 작성하는 연습</code>이라고 적혀있을 정도로 단위 테스트 구현에 대한 방향성이 제시되어 있었고, 그래서 이에 따라 구현하려고 노력했다.</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: 60.55555555555555%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAABXklEQVQoz4WT63KCMBCFeRNt5SKXECDhogTFIkzb0U7/6fu/yOnseplaK/7YCezMnnxnd2PZvoDUNdKqRZQuMLFDvLjiYbx68WhYXqSQlS3mIocXabihghtm/4SCE2ZPRS0nSKEWG8i8gVA1AlnCjRSL0yW/vz2hbwT/c8CCadmexJKKi4j6QkRiJ0GN2Ty5E7wjnM0lsmoD87bDcvOJshmQFCsm5lM3kPkKablGrA1sP8HUDh+KWkSk6w55veVi+iebTpAxKQnM/IRPzpEDoccJTbfD8HVEvz+g3x3OpD0Ks2WyrGqhlx2KZkDR9Ew+KpibLUy3v9qOdYNYGbZ4sU5BvfZliYkdjFsmArJJCbrg761TJ+K4GYgnxgj7M9mJSPJproPwZXG3Mg8tU7PXwzeG/RF53XHfKGjay/aDc7QytEbPXsmVkKa8WL/zLsa6ZirqWXbez4tlLnryBH8AEERxJuK5hugAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"test-list.png\"\n        title=\"test-list.png\"\n        src=\"/static/f905fff7a3f2f0635f549f47d9d24509/37523/test-list.png\"\n        srcset=\"/static/f905fff7a3f2f0635f549f47d9d24509/e9ff0/test-list.png 180w,\n/static/f905fff7a3f2f0635f549f47d9d24509/f21e7/test-list.png 360w,\n/static/f905fff7a3f2f0635f549f47d9d24509/37523/test-list.png 720w,\n/static/f905fff7a3f2f0635f549f47d9d24509/302a4/test-list.png 1080w,\n/static/f905fff7a3f2f0635f549f47d9d24509/07a9c/test-list.png 1440w,\n/static/f905fff7a3f2f0635f549f47d9d24509/01294/test-list.png 1615w\"\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>우선 메인에서 만들어진 <strong>domain</strong> 클래스에 맞춰서 테스트 클래스를 하나씩 만들어 여기에 단위 테스트를 작성했다.<br>\n처음에 나누어둔 기능 목록에 따라 구현을 하기 때문에 <strong>도메인 로직</strong>에 맞춰서 하나씩 구현을 했고, 다음 도메인을 구현하기 전에 만든 도메인에 대한 <strong>단위 테스트</strong>를 진행하고 통과하면 다음 도메인에 대한 기능을 구현하는 방식으로 진행했다.</p>\n<p>하지만 역시 처음 해보는 방식이니 생각대로 되지는 않았다.<br>\n처음에는 한 기능을 구현하고 그 기능에 대한 단위 테스트를 작성하는 방식으로 순조롭게 진행했지만, 나중에는 시간에 쫓기다보니 점점 테스트를 미루고 기능 구현에만 집중하게 되었다..</p>\n<p>그리고 단위 테스트도 보통 예외 상황인 경우에만 집중해서 작성했는데, 이 외에도 여러 예외 상황이나 실제 작동되어야 하는 상황에 대한 테스트도 작성했으면 좋았을 것 같다.<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>기능 설계 단계에서부터 <strong>한</strong> 기능이 정말 <strong>하나</strong>의 기능만 담당하도록 하기</li>\n<li>함수 <strong>라인 수</strong>에 제한을 두어 함수가 한 가지 기능만 할 수 있도록 하기</li>\n<li>비즈니스 로직에 맞춰 domain 정하고, service 분리하기</li>\n<li>setter 사용 지양하기</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\">OutputView</code>는 구현했지만 입력을 담당하는 부분은 여전히 <strong>service</strong>에서 분리되어 있지 않음</li>\n<li><strong>단위 테스트</strong>보다 <strong>기능 구현</strong>에만 집중</li>\n<li><strong>다양한 경우</strong>에 대한 <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>입력을 담당하는 <code class=\"language-text\">InputView</code> 클래스도 만들어서 분리하기</li>\n<li>한 가지 기능을 구현한 뒤, 그 기능에 대한 <strong>단위 테스트</strong> 바로 작성해서 진행하기</li>\n<li><strong>다양한 경우</strong>에 대한 <strong>단위 테스트</strong> 진행하기</li>\n</ul>\n<hr>\n<p><a href=\"https://github.com/Go-Jaecheol/java-lotto/tree/Go-Jaecheol\">구현 코드 확인</a></p>\n<div class=\"table-of-contents\">\n<ul>\n<li>\n<p><a href=\"#-3%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%EC%86%8C%EA%B0%9C\">🎞 3주차 미션 소개</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=\"#-%ED%95%98%EB%82%98%EC%9D%98-%ED%95%A8%EC%88%98%EA%B0%80-%ED%95%9C-%EA%B0%80%EC%A7%80-%EA%B8%B0%EB%8A%A5%EB%A7%8C-%EB%8B%B4%EB%8B%B9%ED%95%98%EB%8F%84%EB%A1%9D\">✅ 하나의 함수가 한 가지 기능만 담당하도록</a></li>\n<li><a href=\"#-mvc-%ED%8C%A8%ED%84%B4\">✅ MVC 패턴..?</a></li>\n<li><a href=\"#-%EB%8F%84%EB%A9%94%EC%9D%B8-%EB%A1%9C%EC%A7%81%EC%97%90-%EB%8C%80%ED%95%9C-%EB%8B%A8%EC%9C%84-%ED%85%8C%EC%8A%A4%ED%8A%B8\">✅ 도메인 로직에 대한 단위 테스트</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 12, 2022","title":"[우아한테크코스] 우테코 프리코스 3주차 회고","categories":"우테코","author":"JFe","emoji":"🎰"},"fields":{"slug":"/wooteco-pre-3/"}},"prev":{"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>","frontmatter":{"date":"January 18, 2023","title":"[우아한테크코스] 우테코 최종 코딩 테스트 후기","categories":"우테코","author":"JFe","emoji":"🍽"},"fields":{"slug":"/wooteco-pre-final/"}},"site":{"siteMetadata":{"siteUrl":"https://jfelog.netlify.app","comments":{"utterances":{"repo":"Go-Jaecheol/Jfe_Blog"}}}}},"pageContext":{"slug":"/wooteco-pre-4/","nextSlug":"/wooteco-pre-3/","prevSlug":"/wooteco-pre-final/"}},
    "staticQueryHashes": ["1073350324","1956554647","2938748437"]}