{
    "componentChunkName": "component---src-templates-blog-template-js",
    "path": "/wooteco-pre-3/",
    "result": {"data":{"cur":{"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>","excerpt":"프리코스가 끝나자마자 바로 회고를 작성하려고 했는데 다른 일들을 하다 보니 생각보다 늦어졌다. 예전 프로젝트 회고를 작성하면서도 느꼈지만 블로그 글 쓰는 것부터가 아직 서툴고 회고를 쓰는 데 생각보다 시간이 오래 걸리는 것 같다,, 많이 쓰다 보면 나아지겠지 2주차 미션이 끝나고 바로 3주차 미션이 시작되었다. 3주차 미션은 로또 게임 구현으로 이전 미션보다 기능 요구 사항이 많아졌고, 프로그래밍 요구 사항도 많아졌다.  또한, 2주차 미션에서 추가로 다음과 같은 2가지 목표가 추가되었다. 클래스(객체)를 분리하는 연습 도메인 로직에 대한 단위 테스트를 작성하는 연습 🎞 3주차 미션 소개 3주차 미션 소개 🚀 기능 요구 사항 로또 게임 기능을 구현해야 한다. 로또 게임은 아래와 같은 규칙으로 진행된다. 로또 구입 금액을 입력하면 구입 금액에 해당하는 만큼 로또를 발행해야 한다. 로또 1장의 가격은 1,000원이다. 당첨 번호와 보너스 번호를 입력받는다. 사용자가 구매한 로또 번호와…","frontmatter":{"date":"December 12, 2022","title":"[우아한테크코스] 우테코 프리코스 3주차 회고","categories":"우테코","author":"JFe","emoji":"🎰"},"fields":{"slug":"/wooteco-pre-3/"}},"next":{"id":"389be15a-11bc-5d94-badb-af6c3a17dab8","html":"<p>지난 10월 26일부터 우테코 프리코스를 시작했다.<br>\n우아한테크코스 5기에 최종 합격하는 것을 목표로 지원했지만, 아직 자바에 익숙하지 않은 나로서는 프리코스만으로도 많은 것들을 얻어갈 수 있을 거라 생각했다.</p>\n<p>1주차와 2주차를 진행하는 시기에는 다른 면접들이 많이 잡혀있었어서 빠르게 구현만 하고 회고를 쓸 생각은 하지도 못했다.<br>\n하지만 3주차 미션을 다 구현하고 나서는 배운 점들을 꼭 회고로 남겨야겠다는 생각이 들었고, 온보딩이었던 1주차를 제외하고 2주차부터 다시 복기해가며 회고록을 써볼 생각이다.</p>\n<h2 id=\"-2주차-미션-소개\" style=\"position:relative;\"><a href=\"#-2%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%EC%86%8C%EA%B0%9C\" 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-precourse/java-baseball\">2주차 미션 소개</a></p>\n<p>🚀 기능 요구 사항</p>\n<p>기본적으로 1부터 9까지 서로 다른 수로 이루어진 3자리의 수를 맞추는 게임이다.</p>\n<ul>\n<li>같은 수가 같은 자리에 있으면 스트라이크, 다른 자리에 있으면 볼, 같은 수가 전혀 없으면 낫싱이란 힌트를 얻고, 그 힌트를 이용해서 먼저 상대방(컴퓨터)의 수를 맞추면 승리한다.\n<ul>\n<li>예) 상대방(컴퓨터)의 수가 425일 때\n<ul>\n<li>123을 제시한 경우 : 1스트라이크</li>\n<li>456을 제시한 경우 : 1볼 1스트라이크</li>\n<li>789를 제시한 경우 : 낫싱</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>위 숫자 야구 게임에서 상대방의 역할을 컴퓨터가 한다. 컴퓨터는 1에서 9까지 서로 다른 임의의 수 3개를 선택한다. 게임 플레이어는 컴퓨터가 생각하고 있는 서로 다른 3개의 숫자를 입력하고, 컴퓨터는 입력한 숫자에 대한\n결과를 출력한다.</li>\n<li>이 같은 과정을 반복해 컴퓨터가 선택한 3개의 숫자를 모두 맞히면 게임이 종료된다.</li>\n<li>게임을 종료한 후 게임을 다시 시작하거나 완전히 종료할 수 있다.</li>\n<li>사용자가 잘못된 값을 입력할 경우 <code class=\"language-text\">IllegalArgumentException</code>을 발생시킨 후 애플리케이션은 종료되어야 한다.</li>\n</ul>\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%84%EC%9A%94%ED%95%9C-%EA%B8%B0%EB%8A%A5-%EB%B6%84%EB%A6%AC\" 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>이전 1주차 온보딩에서도 문제 요구사항에 따라 필요한 기능을 나누고 구현했지만, 1주차 미션은 코딩 테스트 같은 형태의 문제여서 기능 분리에 크게 집중하지 않았다.</p>\n<p>하지만 이번 2주차 미션은 숫자 야구라는 하나의 게임을 구현하는 미션이어서 기능을 분리하는 것에 보다 집중했다.</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,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAAA0ElEQVQoz5WR3RKCIBCFfZKmVBREUUCRNMP+pvd/otNAU5M3ZRcHdnbgm7NnI6sMRneHdXeQQiLOxVsJrRHT+nl/9L8pooWENEfU3YRKD6CiQ8Y18lKD1QZMGJRyD8IVdln1G5gWCt14hd6f0A5nCD2i0iMa40CrdgHx9S9FW1IGB9I46OEcwNrO4I1FyprF4xf0q0N/eEceJHsX3GZcYZMw7Ei5gKwaOWENVD+jHS4BaKYbRHsAlzbkuAayAPoPfmRzuAb5HP1iUibDdv8FPgAB/dNaqMp43AAAAABJRU5ErkJggg=='); 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/ee1997ae4aae8a779263fc5c6a46433f/37523/workflow.png\"\n        srcset=\"/static/ee1997ae4aae8a779263fc5c6a46433f/e9ff0/workflow.png 180w,\n/static/ee1997ae4aae8a779263fc5c6a46433f/f21e7/workflow.png 360w,\n/static/ee1997ae4aae8a779263fc5c6a46433f/37523/workflow.png 720w,\n/static/ee1997ae4aae8a779263fc5c6a46433f/302a4/workflow.png 1080w,\n/static/ee1997ae4aae8a779263fc5c6a46433f/07a9c/workflow.png 1440w,\n/static/ee1997ae4aae8a779263fc5c6a46433f/54d4c/workflow.png 1571w\"\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><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: 23.888888888888886%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAl0lEQVQY052PWw6CMBBFuxQQCyItpdBWWx5GDBrd/36uoTXGmJg0fpxM5mPO3Eu0m2HGBQVXSGiFNOdIixqbPyGNmSDUgEpasNaBSYtt2QTxB9FCd75D+ZRX6P6CstbIdgJZ2Xgx3Uu/fz/4BbGnG8ywoJ8fOLykK0KPqOTRJ85ZF52SrDV56/xxmBa8c2BtECWUvWUx9Z8Za5dCWMDyZgAAAABJRU5ErkJggg=='); 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/ae18d8ce85c7447df0b7ca28599e8100/37523/function-list.png\"\n        srcset=\"/static/ae18d8ce85c7447df0b7ca28599e8100/e9ff0/function-list.png 180w,\n/static/ae18d8ce85c7447df0b7ca28599e8100/f21e7/function-list.png 360w,\n/static/ae18d8ce85c7447df0b7ca28599e8100/37523/function-list.png 720w,\n/static/ae18d8ce85c7447df0b7ca28599e8100/302a4/function-list.png 1080w,\n/static/ae18d8ce85c7447df0b7ca28599e8100/07a9c/function-list.png 1440w,\n/static/ae18d8ce85c7447df0b7ca28599e8100/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>기능을 미리 정해두고 맞춰서 구현해서 커밋하는 방식으로 하긴 했지만, 위에서도 보이는 것처럼 아직 기능이 가장 작은 단위로 분리되지는 않았고 유효성 검사에 대한 기능도 적은 상태다.</p>\n<p>가령 위의 경우에서 <code class=\"language-text\">입력받은 숫자와 컴퓨터 숫자 비교해서 볼, 스트라이크 반환하는 기능</code> 같은 경우에는 <code class=\"language-text\">숫자를 비교하는 기능</code>과 <code class=\"language-text\">볼, 스트라이크 반환하는 기능</code>으로 나눌 수 있을 것이다.</p>\n<p>이런 면에서 2주차 미션에서는 필요한 기능을 분리하려고 시도는 했으나,, 아직 완전히 만족스러운 형태로 작게 분리하지는 못해서 아쉬움이 남았었다,,</p>\n<hr>\n<h3 id=\"-이름을-통해-의도-드러내기\" style=\"position:relative;\"><a href=\"#-%EC%9D%B4%EB%A6%84%EC%9D%84-%ED%86%B5%ED%95%B4-%EC%9D%98%EB%8F%84-%EB%93%9C%EB%9F%AC%EB%82%B4%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>1주차 미션 공통 피드백 중 하나로 <code class=\"language-text\">이름을 통해 의도를 드러낸다</code>와 <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: 63.888888888888886%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAABcUlEQVQ4y42TSYvCQBCF8///jzcPgiLiSSHeFLfEuMd91zd8NVRoxJEJPF51dXXtiUqlksrlshqNhtrttiqVilqtlprNpjqdjv77vV4v46jb7arf72s4HGo8HmswGJjc6/WUJIkOh4N2u532+71Op5MB3fF41Pl8LtidRrPZTKvVSovFQsjz+VyTyUTT6dTOyAQCnLMss4AERuYeEMgyJAsuYR65MxhdmqYFuzwajYzzPC+yv9/vvw4fj4cul4uBlF2+Xq8WFZmSOPsd4N17D5/Pp6Jqtap6va44jlWr1bRcLv9seggef0KUJomlT+9g+rnZbKyU7XZr8ns23z4rmfpvt5shLNGniN4zwD5k4CtjU+YhZTJlmEZ7luv12oCeCcPcUQ32yNhjUwyFjDAISwzLdscezB2EgZGpwhxSFtE9osMfeWYEdQbYsOBsgpdc9BCn4UqE8H76CnmvPw3KekhTabz/Yh4VXcjocfhtlcjwB/VF5B2RZUnlAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"naming.png\"\n        title=\"naming.png\"\n        src=\"/static/e6543ed27860338dd7055cf781c67cfc/37523/naming.png\"\n        srcset=\"/static/e6543ed27860338dd7055cf781c67cfc/e9ff0/naming.png 180w,\n/static/e6543ed27860338dd7055cf781c67cfc/f21e7/naming.png 360w,\n/static/e6543ed27860338dd7055cf781c67cfc/37523/naming.png 720w,\n/static/e6543ed27860338dd7055cf781c67cfc/914c7/naming.png 978w\"\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>기존 1주차 미션이나 평소 코딩 스타일에서도 메서드 명이나 변수 명으로 그 메서드와 변수의 역할을 드러내려고 했었는데, 이 피드백에서 집중했던 점은 <code class=\"language-text\">축약하지 않는다</code>였다.</p>\n<p>평소에는 예를 들어, 사용자 상세 정보를 저장하는 변수면 <code class=\"language-text\">userInfo</code>로 변수 명을 정했었다. 당연히 이렇게 변수의 역할은 드러내면서 최대한 간결하게 이름을 작성하는게 좋다고 생각했기 때문에 이번 피드백은 많이 와닿았다.<br>\n피드백에서 원하는 대로 변수 명을 고친다면 <code class=\"language-text\">userInformation</code>이 될 것이다.</p>\n<p>이름을 축약하는 게 당연하다고 생각했지만 사실 이것도 계속 긴 변수 명을 적기 싫었던 귀찮음에서 온 게 아닐까 다시 생각하게 됐다.<br>\n그래서 2주차 미션부터는 클래스 명, 메서드 명, 변수 명 전부 하나하나 신경써가며 이름을 지었다.<br>\n<strong>축약하지 않고, 최대한 그 역할을 드러내도록!</strong></p>\n<hr>\n<h3 id=\"-클래스-구조\" style=\"position:relative;\"><a href=\"#-%ED%81%B4%EB%9E%98%EC%8A%A4-%EA%B5%AC%EC%A1%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>필요한 기능들을 정의하고 난 다음에는 전체 <strong>클래스 구조</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: 45.55555555555556%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAqUlEQVQoz6WSWw6CMBREWQ3SB72lJUSkQMWiEhJfMe5/J2MgxgXQj/k9OffOJLb0OIcJZK/gqkcmHTLZbk6Scgffj6iaGYIGsLyLA2bCIaUBqnuDigChhyjLFcjIQ/sPJPkoux+wAatvIPeCUD12wsUDd9UMWk42AbkJYGs5G4GLUVlPKPbzWgiPgP1/KG0AuQckHaHMCFmcIgz5Aaq9w7gntL1A6rjpfAHDGhyt+8Y/wAAAAABJRU5ErkJggg=='); 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/de7a7ff3be3774077455d70acd360bf7/37523/structure-code.png\"\n        srcset=\"/static/de7a7ff3be3774077455d70acd360bf7/e9ff0/structure-code.png 180w,\n/static/de7a7ff3be3774077455d70acd360bf7/f21e7/structure-code.png 360w,\n/static/de7a7ff3be3774077455d70acd360bf7/37523/structure-code.png 720w,\n/static/de7a7ff3be3774077455d70acd360bf7/302a4/structure-code.png 1080w,\n/static/de7a7ff3be3774077455d70acd360bf7/89048/structure-code.png 1242w\"\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: 33.888888888888886%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAv0lEQVQoz6WR2Q6CMBBF+yduyNoWOtDQIoIYo4b//59rWoLGF9eHk5mHyZmbGUalRq73WIUC60j+DROFBqcGyy33Usfc/yQMUgXbX1F3Z8iqRa5bqLrzlSuLICnu8nnhK9hik0K3JzTDCNOfYfoL2uMIWe2eRFMC8RYWZoSqOUJQg0hUiKVGmte+hrzENlUPcSTewhKpYbopGZkDRLkDmR6ZsuBkEQv9ndANuluRHUBm8CKX0D8nyLAK+ccyJ7wBJAnScaJ7ZMQAAAAASUVORK5CYII='); 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/ab472932cdc7a96a7251ccbee2c14463/37523/structure.png\"\n        srcset=\"/static/ab472932cdc7a96a7251ccbee2c14463/e9ff0/structure.png 180w,\n/static/ab472932cdc7a96a7251ccbee2c14463/f21e7/structure.png 360w,\n/static/ab472932cdc7a96a7251ccbee2c14463/37523/structure.png 720w,\n/static/ab472932cdc7a96a7251ccbee2c14463/302a4/structure.png 1080w,\n/static/ab472932cdc7a96a7251ccbee2c14463/07a9c/structure.png 1440w,\n/static/ab472932cdc7a96a7251ccbee2c14463/2ed34/structure.png 1776w\"\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\">MVC 패턴</code>이었다.<br>\n<strong>Spring Boot</strong>를 사용해 프로젝트를 진행하면서 <strong>MVC 패턴</strong>으로 구현한 경험이 있었기 때문에 <strong>MVC 패턴</strong>을 고려했다. 더군다나 저번 카카오 2차 코딩테스트를 준비하면서도 다들 나름 잘했다고 생각이 드는 사람들은 <strong>MVC 패턴</strong>으로 과제를 해결하려고 했던 점들을 보고 나도 저렇게 해봐야지 생각했기 때문에, 이번에는 <strong>MVC 패턴</strong>을 적용해봐야겠다는 생각이 들었다.</p>\n<p>하지만 <strong>MVC 패턴</strong>을 적용해서 클래스 구조를 설계하려고 하니 막막했다.<br>\n지금까지 알고 있는 방식은 <strong>MVC 패턴</strong>이라는 <code class=\"language-text\">디자인 패턴</code>에 대해서 알고 있는 것이 아니라, <strong>Spring</strong>에서 주로 사용하는 <code class=\"language-text\">클래스 구조</code>에 대해서만 알고 있었다는 걸 깨닫게 되었다.<br>\nMVC 패턴이니까 <strong>Model</strong> 부분은 <code class=\"language-text\">domain</code>이라는 패키지 명으로 만들고, <code class=\"language-text\">service</code> 패키지에서 필요한 기능들을 나누고 각 <strong>service</strong>를 호출할 <code class=\"language-text\">controller</code>까지는 음.. 굳이 안만들어도 되겠다고 생각했다. 그리고 <strong>View</strong> 부분도 콘솔 입출력만 필요하니까 굳이 따로 안만들어도 되겠다고 생각했고, 그 결과 위와 같은 구조가 만들어지게 되었다.</p>\n<p>음.. 다 지나고 생각해보니 내가 왜 저랬을까,,<br>\n모르면 찾아보고 했어도 되는데 클래스 구조 설계에 많은 시간을 낭비하자는 생각에 쫓겨 저런 구조를 만들어버렸다.<br>\n내가 지금까지 알고 있다고 생각했던 MVC 패턴은 그저 <strong>Spring</strong>에서 주로 사용하는 구조에 불과했다. <code class=\"language-text\">구조</code>만 알고 있었던거지 <code class=\"language-text\">패턴</code>은 모르고 있었다.<br>\n다행히도 2주차 미션을 끝내고 뭔가 이상하다는 생각이 들었고, 다음 미션부터는 생각을 조금씩 바꾸게 되었다.<br>\n나중에 작성할 3주차, 4주차 회고를 본다면 차츰차츰 나아지는 모습을 볼 수 있을 것이다..^^</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> 짓기</li>\n<li><code class=\"language-text\">기능 분리</code> -> <code class=\"language-text\">구조 설계</code> -> <code class=\"language-text\">구현</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>기능을 여전히 <strong>더 작은 단위</strong>로 분리할 수 있음</li>\n<li><strong>유효성 검사</strong>에 대한 기능이 적음</li>\n<li><strong>MVC 패턴</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>우선 <strong>MVC 패턴</strong>에 대해 공부하고, 제대로 구조 설계하기</li>\n</ul>\n<hr>\n<p><a href=\"https://github.com/Go-Jaecheol/java-baseball/tree/Go-Jaecheol\">구현 코드 확인</a></p>\n<div class=\"table-of-contents\">\n<ul>\n<li>\n<p><a href=\"#-2%EC%A3%BC%EC%B0%A8-%EB%AF%B8%EC%85%98-%EC%86%8C%EA%B0%9C\">🎞 2주차 미션 소개</a></p>\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%84%EC%9A%94%ED%95%9C-%EA%B8%B0%EB%8A%A5-%EB%B6%84%EB%A6%AC\">✅ 필요한 기능 분리</a></li>\n<li><a href=\"#-%EC%9D%B4%EB%A6%84%EC%9D%84-%ED%86%B5%ED%95%B4-%EC%9D%98%EB%8F%84-%EB%93%9C%EB%9F%AC%EB%82%B4%EA%B8%B0\">✅ 이름을 통해 의도 드러내기</a></li>\n<li><a href=\"#-%ED%81%B4%EB%9E%98%EC%8A%A4-%EA%B5%AC%EC%A1%B0\">✅ 클래스 구조</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":"November 26, 2022","title":"[우아한테크코스] 우테코 프리코스 2주차 회고","categories":"우테코","author":"JFe","emoji":"⚾"},"fields":{"slug":"/wooteco-pre-2/"}},"prev":{"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/"}},"site":{"siteMetadata":{"siteUrl":"https://jfelog.netlify.app","comments":{"utterances":{"repo":"Go-Jaecheol/Jfe_Blog"}}}}},"pageContext":{"slug":"/wooteco-pre-3/","nextSlug":"/wooteco-pre-2/","prevSlug":"/wooteco-pre-4/"}},
    "staticQueryHashes": ["1073350324","1956554647","2938748437"]}