{
    "componentChunkName": "component---src-templates-blog-template-js",
    "path": "/wooteco-racingcar/",
    "result": {"data":{"cur":{"id":"57123275-3f75-54a2-8337-7e90489cf625","html":"<p>우테코를 시작한지 한 달.. 드디어 여유가 생겼다.<br>\n생각보다 빠르게 한 달이 지나갔다. 미션 회고도 쓰고 여러 블로그 글도 쓰고 싶었지만, 미션 진행하고 우테코 생활 적응하는 것만으로도 바빠서 못하고 있었다. 사실 글 쓸 때 쓰고 지우고 고민하느라 시간이 많이 걸리는 게 한 몫 했다ㅎ,,<br>\n이미 <code class=\"language-text\">자동차 경주</code> 미션과 <code class=\"language-text\">사다리 타기</code> 미션을 끝내고 <code class=\"language-text\">블랙잭</code> 미션을 진행하고 있지만 늦게나마 지난 미션들을 회고해보려 한다.</p>\n<p>자동차 경주 미션은 우테코에 들어와서 진행한 첫 미션이다.<br>\n모든 미션은 2개의 단계로 나뉘는데, 1단계는 페어 프로그래밍으로 진행하고 2단계는 혼자서 진행한다. 각 단계가 끝나면 리뷰어에게 코드 리뷰를 받고, 피드백을 반영하여 머지 되면 다음 단계를 진행하는 방식으로 한다.</p>\n<p>사실 처음 미션을 시작하기 전에는 페어 프로그래밍이 무서웠다.<br>\n하나의 노트북으로 같이 페어 프로그래밍을 진행하면 내 실력이 낱낱이 드러날까봐 그게 무서웠다. 물론 지금도 어떤 페어와 매칭이 될지 미션이 시작하기 전에는 떨리긴 하지만 막상 시작하면 생각했던 것만큼 힘들진 않았다. 같이 했던 페어들이 엄청 편하게 대해줬고 새로운 의견을 얘기할 때도 항상 다른 의견은 없는지 배려해줘서 편하게 페어 프로그래밍을 할 수 있었다.^^</p>\n<hr>\n<h2 id=\"-1단계---자동차-경주-구현\" style=\"position:relative;\"><a href=\"#-1%EB%8B%A8%EA%B3%84---%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B2%BD%EC%A3%BC-%EA%B5%AC%ED%98%84\" aria-label=\" 1단계   자동차 경주 구현 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🎞 1단계 - 자동차 경주 구현</h2>\n<p><a href=\"https://github.com/woowacourse/java-racingcar/pull/520\">1단계 PR</a></p>\n<h3 id=\"-1단계-기능-요구-사항-정리\" style=\"position:relative;\"><a href=\"#-1%EB%8B%A8%EA%B3%84-%EA%B8%B0%EB%8A%A5-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\" aria-label=\" 1단계 기능 요구 사항 정리 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🚀 1단계 기능 요구 사항 정리</h3>\n<ul>\n<li>\n<p>자동차 이름 입력</p>\n<ul>\n<li>자동차 이름 입력 문구 출력하는 기능</li>\n<li>자동차 이름 입력받는 기능</li>\n<li>문자열을 쉼표(,)로 구분하여 배열로 저장하는 기능\n<ul>\n<li>각 자동차의 이름이 5자 이하인지 확인하는 기능</li>\n<li>자동차의 이름이 영어 대소문자, 숫자가 아닌 경우 예외 처리</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p>시도할 횟수 입력</p>\n<ul>\n<li>시도할 횟수 입력 문구 출력하는 기능</li>\n<li>시도할 횟수 입력받는 기능\n<ul>\n<li>숫자가 아닌 경우 예외 처리</li>\n<li>0 이하의 숫자가 입력될 경우 예외 처리</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p>게임 실행</p>\n<ul>\n<li>실행 결과 문구 출력하는 기능</li>\n<li>입력된 횟수 만큼 라운드를 반복하는 기능</li>\n<li>자동차의 시작 위치가 0이 아닌 경우 예외 처리</li>\n<li>자동차의 현재 위치가 해당 라운드보다 큰 경우 예외 처리</li>\n</ul>\n</li>\n<li>\n<p>라운드 실행</p>\n<ul>\n<li>각 자동차 마다 0 ~ 9 사이의 random 값 구하는 기능</li>\n<li>random 값이 4 이상인지 확인하는 기능</li>\n<li>random 값이 4 이상이면 해당 자동차의 이동 거리를 증가시키는 기능</li>\n<li>각 라운드의 실행 결과를 출력하는 기능</li>\n</ul>\n</li>\n<li>\n<p>결과</p>\n<ul>\n<li>최종 이동 결과를 출력하는 기능</li>\n<li>가장 이동 거리가 큰 자동차를 찾는 기능</li>\n<li>우승자를 출력하는 기능</li>\n</ul>\n</li>\n</ul>\n<hr>\n<h3 id=\"-일급-컬렉션-사용\" style=\"position:relative;\"><a href=\"#-%EC%9D%BC%EA%B8%89-%EC%BB%AC%EB%A0%89%EC%85%98-%EC%82%AC%EC%9A%A9\" aria-label=\" 일급 컬렉션 사용 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ 일급 컬렉션 사용</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 35%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABHklEQVQoz33Ry26DMBCFYV6kakmAgMEGG2zMJQTSbqouuuj7P8tfkVurJurim2Nb8mhkB7nuMN2C9jPGz9Td8US3M9rtGboaYx1Z6RFV+w9PKi1B9TrgPmfc+4IfOuy0p1lm9LQn9xblDbkzpLZGuOahbM22ITU1gXxrab4mmo8J42v6wdJPHfowIEePHDuqw4gcW1KnSVtzoS9+1jujCWw/EhcFoVAkypLkFbEoiXNNUhiSQpNIQ1xotqJ8KBIViaxPGZTaI5SjqluMkTxtC17iP6JzhrEkTO5tEsU2LdnsFMFzXLB+TNMvaNefHlc1A4XpkHWPasbbPlPu3GCn7lzPg7WI0lL6I1thibKSKNNEWXVnneJ6MdzJm98NvwHzNtiYsSodfgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"first-class-collection.png\"\n        title=\"first-class-collection.png\"\n        src=\"/static/544f0206402a3c4701c0bcc0ff7c38c7/37523/first-class-collection.png\"\n        srcset=\"/static/544f0206402a3c4701c0bcc0ff7c38c7/e9ff0/first-class-collection.png 180w,\n/static/544f0206402a3c4701c0bcc0ff7c38c7/f21e7/first-class-collection.png 360w,\n/static/544f0206402a3c4701c0bcc0ff7c38c7/37523/first-class-collection.png 720w,\n/static/544f0206402a3c4701c0bcc0ff7c38c7/302a4/first-class-collection.png 1080w,\n/static/544f0206402a3c4701c0bcc0ff7c38c7/07a9c/first-class-collection.png 1440w,\n/static/544f0206402a3c4701c0bcc0ff7c38c7/6ee58/first-class-collection.png 1640w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>미션을 시작하기 전에는 나도 페어도 <code class=\"language-text\">일급 컬렉션</code>이 뭔지 몰랐다.<br>\n일급 컬렉션이 뭔지 모르니 일급 컬렉션을 써야겠다는 생각도 하진 못했고, 그냥 단순하게 구현해야겠다고 생각하고 구현했다.</p>\n<p>그러다가 자동차의 이름과 진행 상황(자동차 위치)을 어떻게 저장할지에 대해 페어랑 고민하게 됐다.<br>\n처음에는 <strong>HashMap</strong>으로 자동차 이름이랑 진행 상황들을 저장해야겠다고 생각했다.<br>\n그러면 <code class=\"language-text\">Car</code>라는 클래스에서 이름이랑 위치를 가지도록 하고, <code class=\"language-text\">Car</code>들을 <strong>List</strong>로 저장해두는 방식이 더 깔끔하지 않을까?<br>\n어, 이게 <code class=\"language-text\">일급 컬렉션</code>인가???<br>\n이렇게 페어랑 고민하는 과정을 거쳤고, 일급 컬렉션이 뭔지 알게 되었다.</p>\n<p>이번 미션에서 가장 많이 배웠고 뿌듯하다고 생각한 부분이다.<br>\n일급 컬렉션이 뭔지 알고 적용했다는 점도 중요하지만, 사용해야 하는 이유를 직접 페어랑 고민하며 찾아가는 과정을 거쳤다는 점이 뿌듯했다.<br>\n한 단계 더 성장했다는 느낌을 직접 받을 수 있었고, 이런 부분이 페어 프로그래밍을 하는 가장 큰 이유라고 생각한다.</p>\n<h3 id=\"-mvc-패턴에서-controller의-역할\" style=\"position:relative;\"><a href=\"#-mvc-%ED%8C%A8%ED%84%B4%EC%97%90%EC%84%9C-controller%EC%9D%98-%EC%97%AD%ED%95%A0\" aria-label=\" mvc 패턴에서 controller의 역할 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ MVC 패턴에서 Controller의 역할</h3>\n<p><strong>MVC 패턴</strong>을 사용하고, <strong>Controller</strong>와 <strong>Service</strong>를 나누도록 구현했다.<br>\n하지만 여전히 <strong>Controller</strong>나 <strong>Service</strong>의 제대로 된 역할을 알지 못한 채 구현했다.</p>\n<p>처음에는 <strong>Service</strong>에서 진행에 관한 기능도 다 담당하고, 입출력에 대한 책임도 담당하도록 했다.<br>\n이렇게 했을 때 문제점은 <strong>Service</strong>가 <strong>View</strong>와 관계를 가지고 서로 의존하게 된다.<br>\n여기서 <strong>Service</strong>는 <strong>MVC 패턴</strong>에서 <strong>Model</strong>의 역할을 분리한 계층 중 하나다.<br>\n<strong>MVC 패턴</strong>에서는 <strong>Model</strong>과 <strong>View</strong>가 직접 소통하지 않고 <strong>Controller</strong>를 거쳐서 소통한다. 그게 <strong>Controller</strong>의 역할이다.<br>\n하지만 이렇게 되면 <strong>Service</strong>가 <strong>View</strong>와 소통하며 <strong>Controller</strong>의 역할을 하게 되고, <strong>Controller</strong>가 필요 없어진다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 63.888888888888886%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAABT0lEQVQ4y5VT2XKCQBDkTxKRQ47FZUEOAUWjiTHn//9Mp2Y4QhElxUPX1k7t9vTM9GiezBCme4iogBMkMN0Qy9UahiP51O0AC1tAtwWfHThuCdh+BOIwPcUxzQszyGTHpCqrEcQlgqhAmO7gq7z/2BGPCSlxJ4IJ6ZOItngwPDyaBJ9Bjzv8VSd+kwzeETTbj5GUJ1ZExEFcTCpb3Ci9A901klwcXpHXF+4HyTfc8G7v/oO2dCSivIbcVBBqyyopyZQ6fSKmWZ6Cyuu+zH6y1nx1TEiqqIc07eEw5pL1CkkRWSatzpBJNehdMBv9UGggRGq15hxbYQ5ahY2JqeRJBe2g6M8tsLHJIo3bFa+eLWKsxAaWHzHISnSnuLNOeMXoveGE7Sn7OxMm1Rn1yxfKpzfszh8oj1dUp3cUxyvH9s+fOFy+eT1dmTaWGm3SsOQfYAqGe1l2O50AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"MVC-controller.png\"\n        title=\"MVC-controller.png\"\n        src=\"/static/7b218cc55e1ff5eb65e88700d6857203/37523/MVC-controller.png\"\n        srcset=\"/static/7b218cc55e1ff5eb65e88700d6857203/e9ff0/MVC-controller.png 180w,\n/static/7b218cc55e1ff5eb65e88700d6857203/f21e7/MVC-controller.png 360w,\n/static/7b218cc55e1ff5eb65e88700d6857203/37523/MVC-controller.png 720w,\n/static/7b218cc55e1ff5eb65e88700d6857203/302a4/MVC-controller.png 1080w,\n/static/7b218cc55e1ff5eb65e88700d6857203/07a9c/MVC-controller.png 1440w,\n/static/7b218cc55e1ff5eb65e88700d6857203/098c1/MVC-controller.png 1578w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p><code class=\"language-text\">그러면 Service가 너무 많은 책임을 가지지 않을까요?</code><br>\n라는 피드백을 받았고, 기존 코드에 문제점이 있다는 사실과 내가 <strong>MVC 패턴</strong>을 잘못 알고 있었다는 사실도 인지할 수 있었다.</p>\n<h3 id=\"-상수를-별도의-enum으로-분리한-이유\" style=\"position:relative;\"><a href=\"#-%EC%83%81%EC%88%98%EB%A5%BC-%EB%B3%84%EB%8F%84%EC%9D%98-enum%EC%9C%BC%EB%A1%9C-%EB%B6%84%EB%A6%AC%ED%95%9C-%EC%9D%B4%EC%9C%A0\" aria-label=\" 상수를 별도의 enum으로 분리한 이유 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ 상수를 별도의 enum으로 분리한 이유</h3>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">enum</span> <span class=\"token class-name\">CarConstant</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">NAME_MAX_LENGTH</span><span class=\"token punctuation\">(</span><span class=\"token number\">5</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token function\">NAME_MIN_LENGTH</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">int</span> number<span class=\"token punctuation\">;</span>\n\n    <span class=\"token class-name\">CarConstant</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> number<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>number <span class=\"token operator\">=</span> number<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">int</span> <span class=\"token function\">getNumber</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> number<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>처음에는 이렇게 <code class=\"language-text\">CarConstant</code>와 같이 상수를 <strong>enum</strong>으로 모아두고 사용했다.<br>\n하지만 상수를 <strong>enum</strong>으로 분리한 이유를 묻는 피드백을 받았고, <strong>enum</strong>으로 분리할 때와 안할 때 차이점을 고민해보았다.</p>\n<p>우선 <strong>enum</strong>을 사용한 가장 큰 이유는 가독성 때문이다.<br>\n필요한 상수의 개수가 많아지면 그만큼 클래스가 길어지고, 가독성이 안좋아질 것 같다고 생각해서 상수 클래스로 따로 분리하기로 결정했다.<br>\n상수만을 위한 클래스를 따로 만든다면 <strong>enum</strong>을 사용하는 것이 어떻겠냐고 페어가 의견을 제시했고, 단순히 <strong>static final</strong>로 상수를 선언하는 것보다 <strong>enum</strong>을 사용하면 가독성도 좋아지고 컴파일 단계에서 에러를 확인할 수 있는 등 장점이 많은 것 같다고 생각해서 <strong>enum</strong>을 사용하기로 했다.</p>\n<p>하지만 리뷰어의 피드백 중에 다음과 같은 의견이 있었다.<br>\n<code class=\"language-text\">Car가 어떤 역할을 하는지 알기위해 Car, CarConstant 두 클래스를 다 확인해야 알 것 같네요!</code><br>\n이 의견을 듣고나니 상수 클래스의 분리가 오히려 더 복잡한 과정을 요구하는 것 같다는 생각이 들었다.<br>\n객체는 그 자체로 의미를 갖는 게 좋은데, <code class=\"language-text\">Car</code>의 이름 최대 길이, 최소 길이 등과 같은 제약 사항도 일종의 <code class=\"language-text\">Car</code>의 속성이고 <code class=\"language-text\">Car</code> 클래스를 보았을 때 한눈에 파악되면 좋을 것 같다는 의견이었다.</p>\n<p><strong>enum</strong>을 사용하기로 마음 먹은 가장 큰 이유가 가독성 때문이었는데, 과연 <strong>enum</strong>을 사용하지 않으면 가독성이 떨어질까??<br>\n리뷰어의 의견을 보고 다시 한 번 고민해보니 어떤 방식이 더 나은지 결정할 수 있었다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 79.44444444444444%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAACM0lEQVQ4y21U6XraQAz0g7SFBB/4vg22scEcTRMa8v5PM/1G613gS38M0h5oR9LI1jBO+PniYp3UAtvP4AS5sat1hhc3/oZXL3my+r7lBjnSaoesGRGXHdJ6ENDPN3tERYvVOv2GpROZYDowYXGRb0aU7YRmuKDZncVW3RFlN8m63b+hn97Ftoc/2AwXeHFlgkpgTwW2uAizLZKqF2ZJtRPGcdmj2B4MQ6Zkz6XQYJBHlhKQP15Uwk8bedUNC5MW//Q6p7e0QyzsUPlOOEP5vGtS9sIcZXeU1FjHtN4hyDaIiw5BupnRCFPWlWdhvhVERSeZ6VKxqcKQl5mqSlvZ+3pAlLfmMaLY7pHVg8mGzGhNDbNmQN2fVCPaCUV7kA7Tr/qT1FL2twcJzCYSfIiZsN4kQNYSUMtFsZgbQ/mInNQ+kZT9U1OoOyco4ISFsBUdslM8dMMSXlRhHdfGulE5o1LncQU/aeYhaOCEtex58z1aYVi2B9FXf7xi//sL4+Umtp8+MJw/xb/v3zBevjC9XXE89QiyDnHRmiZZv+xICh3PHVOTolJlGrrgK/95Uux1AtePsLAjvLiRkZBVNR1+LB2pA1PVeiKU9gIsVsGDBu9YOLEJxvssnVXUHfykniUxCEt2TTdCdXUv+9QjG8jJoj5pKTktO9Hh0omxO10xXj7RHz8wnv9ilLrdZH7V2Q3d9C7S0bLiQ5QR5UOfkuOj1mqdyNiR7uMI/Q96nvXn7XG29d4/eLD0LREFa4UAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"constant-enum.png\"\n        title=\"constant-enum.png\"\n        src=\"/static/8140bf6b2424999e834a19b315197559/37523/constant-enum.png\"\n        srcset=\"/static/8140bf6b2424999e834a19b315197559/e9ff0/constant-enum.png 180w,\n/static/8140bf6b2424999e834a19b315197559/f21e7/constant-enum.png 360w,\n/static/8140bf6b2424999e834a19b315197559/37523/constant-enum.png 720w,\n/static/8140bf6b2424999e834a19b315197559/302a4/constant-enum.png 1080w,\n/static/8140bf6b2424999e834a19b315197559/07a9c/constant-enum.png 1440w,\n/static/8140bf6b2424999e834a19b315197559/5df5d/constant-enum.png 1572w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<hr>\n<h2 id=\"-2단계---자동차-경주-리팩터링\" style=\"position:relative;\"><a href=\"#-2%EB%8B%A8%EA%B3%84---%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B2%BD%EC%A3%BC-%EB%A6%AC%ED%8C%A9%ED%84%B0%EB%A7%81\" aria-label=\" 2단계   자동차 경주 리팩터링 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🎞 2단계 - 자동차 경주 리팩터링</h2>\n<p><a href=\"https://github.com/woowacourse/java-racingcar/pull/634\">2단계 PR</a></p>\n<h3 id=\"-2단계-리팩토링-요구-사항-정리\" style=\"position:relative;\"><a href=\"#-2%EB%8B%A8%EA%B3%84-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\" aria-label=\" 2단계 리팩토링 요구 사항 정리 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🚀 2단계 리팩토링 요구 사항 정리</h3>\n<ul>\n<li>enum으로 선언한 CarConstant를 Car 클래스 내부로 이동</li>\n<li>enum으로 선언한 InputConstant, OutputConstant를 OutputView 클래스 내부로 이동</li>\n<li>시도 횟수 검증에 대한 메서드를 Controller에서 Service로 이동</li>\n<li>distance에서 position으로 네이밍 변경</li>\n<li>Car 클래스의 책임 분리\n<ul>\n<li>Name 클래스 분리</li>\n<li>Position 클래스 분리</li>\n</ul>\n</li>\n<li>while문 대신 try-catch문 안에서 반복할 수 있도록 변경</li>\n<li>findWinner 메서드에 대한 책임 이동</li>\n<li>현재 위치 검증에 대한 메서드 위치 변경</li>\n<li>자동차 전진을 할 때 전략 패턴을 사용하도록 변경</li>\n<li>부족한 테스트 코드 작성</li>\n</ul>\n<hr>\n<h3 id=\"-전략-패턴-사용\" style=\"position:relative;\"><a href=\"#-%EC%A0%84%EB%9E%B5-%ED%8C%A8%ED%84%B4-%EC%82%AC%EC%9A%A9\" aria-label=\" 전략 패턴 사용 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ 전략 패턴 사용</h3>\n<p>랜덤 값 테스트를 위해 전략 패턴을 사용했다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">interface</span> <span class=\"token class-name\">MoveStrategy</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">boolean</span> <span class=\"token function\">isMovable</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>먼저 <code class=\"language-text\">MoveStrategy</code>라는 interface를 만들고, 목적에 맞게 이를 구현하는 <code class=\"language-text\">RandomMoveStrategy</code>와 <code class=\"language-text\">FixedMoveStrategy</code> 클래스를 만들었다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">RandomMoveStrategy</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">MoveStrategy</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">int</span> RANDOM_NUMBER_BOUNDARY <span class=\"token operator\">=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">boolean</span> <span class=\"token function\">isMovable</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">Random</span> random <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Random</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> random<span class=\"token punctuation\">.</span><span class=\"token function\">nextInt</span><span class=\"token punctuation\">(</span>RANDOM_NUMBER_BOUNDARY<span class=\"token punctuation\">)</span> <span class=\"token operator\">>=</span> <span class=\"token class-name\">Car</span><span class=\"token punctuation\">.</span>FORWARD_BOUNDARY<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><code class=\"language-text\">RandomMoveStrategy</code>에서는 랜덤 값을 생성해서 해당 랜덤 값이 4 이상이면 <code class=\"language-text\">isMovable</code> 메서드에서 <em><strong>true</strong></em>를 반환하고, 3 이하면 <em><strong>false</strong></em>를 반환하도록 구현했다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">FixedMoveStrategy</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">MoveStrategy</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">int</span> number<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">FixedMoveStrategy</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> number<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>number <span class=\"token operator\">=</span> number<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">boolean</span> <span class=\"token function\">isMovable</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> number <span class=\"token operator\">>=</span> <span class=\"token class-name\">Car</span><span class=\"token punctuation\">.</span>FORWARD_BOUNDARY<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><code class=\"language-text\">FixedMoveStrategy</code>에서는 특정 값을 파라미터로 받고, 해당 값이 4 이상이면 <code class=\"language-text\">isMovable</code> 메서드에서 <em><strong>true</strong></em>를 반환하고, 3 이하면 <em><strong>false</strong></em>를 반환하도록 구현했다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">run</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token class-name\">RandomMoveStrategy</span> randomMoveStrategy <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">RandomMoveStrategy</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">OutputView</span><span class=\"token punctuation\">.</span><span class=\"token function\">printResultMessage</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;=</span> tryCount<span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        carService<span class=\"token punctuation\">.</span><span class=\"token function\">runRound</span><span class=\"token punctuation\">(</span>randomMoveStrategy<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token class-name\">OutputView</span><span class=\"token punctuation\">.</span><span class=\"token function\">printRoundResult</span><span class=\"token punctuation\">(</span>carService<span class=\"token punctuation\">.</span><span class=\"token function\">getCarsStatus</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>이를 통해 프로덕션 코드에서는 <code class=\"language-text\">RandomMoveStrategy</code>를 사용해서 랜덤 값을 생성하도록 하고, 테스트 코드에서는 <code class=\"language-text\">FixedMoveStrategy</code>를 사용해서 랜덤 값이 아닌 특정 값으로 테스트를 할 수 있도록 변경했다.</p>\n<h3 id=\"-테스트는-어느-수준까지-고려해야-할까\" style=\"position:relative;\"><a href=\"#-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%8A%94-%EC%96%B4%EB%8A%90-%EC%88%98%EC%A4%80%EA%B9%8C%EC%A7%80-%EA%B3%A0%EB%A0%A4%ED%95%B4%EC%95%BC-%ED%95%A0%EA%B9%8C\" aria-label=\" 테스트는 어느 수준까지 고려해야 할까 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ 테스트는 어느 수준까지 고려해야 할까</h3>\n<p><code class=\"language-text\">입력 문자열을 split()으로 잘 분리가 되는지</code>, <code class=\"language-text\">random()에서 boundary에 맞게 랜덤 값이 잘 생성되는지</code><br>\n이런 테스트들도 고려해야 할까??<br>\n<code class=\"language-text\">split()</code>이나 <code class=\"language-text\">random()</code>은 자바에서 제공하는 함수들인데 이런 것들도 믿지 못하고 테스트를 만들어야 할까라는 의문이 들었다.<br>\n또한, 지금 구현한 코드에서 <code class=\"language-text\">runRound</code> 메서드는 <code class=\"language-text\">cars</code> 객체를 돌면서 각각 <code class=\"language-text\">runForward</code> 메서드를 실행하는 기능만 하고 있다.<br>\n이런 경우에 <code class=\"language-text\">runForward</code> 메서드에 대한 테스트를 구현했다면 <code class=\"language-text\">runRound</code> 메서드에 대한 테스트도 과연 필요할까..?</p>\n<p>이에 대한 리뷰어의 피드백은 다음과 같았다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 13.88888888888889%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAj0lEQVQI10WN7Q6CMAxFeRNNHMYx2PdgbCCo8f0f6ZpWIz9O7nq6tk3vC6QeoVyGspmz9zPTma83acUQCkxc2JPTseKqAk5C4dz2f5ppfSPVFyhjecKkBW7a4PMOO66w4x1hfnDSYvpD+Lyx06HysSFUPtTQMA3SAmpcbgZCWgjpfnlAvbZzDNX8Vv5wncMH5qxeXewGt1YAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"test-coverage.png\"\n        title=\"test-coverage.png\"\n        src=\"/static/eae42aecdb02610c2e60451daca41534/37523/test-coverage.png\"\n        srcset=\"/static/eae42aecdb02610c2e60451daca41534/e9ff0/test-coverage.png 180w,\n/static/eae42aecdb02610c2e60451daca41534/f21e7/test-coverage.png 360w,\n/static/eae42aecdb02610c2e60451daca41534/37523/test-coverage.png 720w,\n/static/eae42aecdb02610c2e60451daca41534/302a4/test-coverage.png 1080w,\n/static/eae42aecdb02610c2e60451daca41534/07a9c/test-coverage.png 1440w,\n/static/eae42aecdb02610c2e60451daca41534/a8a6f/test-coverage.png 1516w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>적극 공감한다.<br>\n이 외에도 자신이 생각하기에 신뢰가 간다면 테스트는 필요없다고 생각한다.<br>\n물론 단순히 귀찮아서 만들지 않는 건 안된다.<br>\n항상 자신만의 기준을 가지자!</p>\n<hr>\n<h2 id=\"-keep\" style=\"position:relative;\"><a href=\"#-keep\" aria-label=\" keep permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🔒 Keep</h2>\n<ul>\n<li><code class=\"language-text\">일급 컬렉션</code> 사용하기</li>\n<li>남들이 다 사용하는 기술이 있더라도 그 기술을 사용하지 않았을 때 단점과 장점을 직접 부딪혀보면서 알아보기</li>\n<li><strong>매직 넘버</strong> 상수화</li>\n<li><strong>기능 요구 사항</strong> 구체적으로 작성하기</li>\n<li><code class=\"language-text\">VO</code> 클래스 분리하기</li>\n</ul>\n<h2 id=\"-problem\" style=\"position:relative;\"><a href=\"#-problem\" aria-label=\" problem permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🚧 Problem</h2>\n<ul>\n<li><code class=\"language-text\">MVC 패턴</code>과 <code class=\"language-text\">전략 패턴</code>을 사용했지만 아직 깊게 공부하고 사용하진 않았음</li>\n<li>모든 요구 사항에 대한 <strong>테스트</strong> 부족</li>\n<li><strong>객체 책임 분리</strong>가 아직 명확하지 않음</li>\n</ul>\n<h2 id=\"-try\" style=\"position:relative;\"><a href=\"#-try\" aria-label=\" try permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🎯 Try</h2>\n<ul>\n<li>하나를 하더라도 그 행동에 대한 이유를 생각하고 행동하자</li>\n<li>모든 요구 사항에 대한 <strong>테스트 코드</strong>를 작성하도록 신경 쓰자</li>\n<li><strong>객체 책임 분리</strong>에 집중해서 설계하기</li>\n<li><code class=\"language-text\">TDD</code> 방식으로 개발해보기</li>\n</ul>\n<div class=\"table-of-contents\">\n<ul>\n<li>\n<p><a href=\"#-1%EB%8B%A8%EA%B3%84---%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B2%BD%EC%A3%BC-%EA%B5%AC%ED%98%84\">🎞 1단계 - 자동차 경주 구현</a></p>\n<ul>\n<li><a href=\"#-1%EB%8B%A8%EA%B3%84-%EA%B8%B0%EB%8A%A5-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\">🚀 1단계 기능 요구 사항 정리</a></li>\n<li><a href=\"#-%EC%9D%BC%EA%B8%89-%EC%BB%AC%EB%A0%89%EC%85%98-%EC%82%AC%EC%9A%A9\">✅ 일급 컬렉션 사용</a></li>\n<li><a href=\"#-mvc-%ED%8C%A8%ED%84%B4%EC%97%90%EC%84%9C-controller%EC%9D%98-%EC%97%AD%ED%95%A0\">✅ MVC 패턴에서 Controller의 역할</a></li>\n<li><a href=\"#-%EC%83%81%EC%88%98%EB%A5%BC-%EB%B3%84%EB%8F%84%EC%9D%98-enum%EC%9C%BC%EB%A1%9C-%EB%B6%84%EB%A6%AC%ED%95%9C-%EC%9D%B4%EC%9C%A0\">✅ 상수를 별도의 enum으로 분리한 이유</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#-2%EB%8B%A8%EA%B3%84---%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B2%BD%EC%A3%BC-%EB%A6%AC%ED%8C%A9%ED%84%B0%EB%A7%81\">🎞 2단계 - 자동차 경주 리팩터링</a></p>\n<ul>\n<li><a href=\"#-2%EB%8B%A8%EA%B3%84-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\">🚀 2단계 리팩토링 요구 사항 정리</a></li>\n<li><a href=\"#-%EC%A0%84%EB%9E%B5-%ED%8C%A8%ED%84%B4-%EC%82%AC%EC%9A%A9\">✅ 전략 패턴 사용</a></li>\n<li><a href=\"#-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%8A%94-%EC%96%B4%EB%8A%90-%EC%88%98%EC%A4%80%EA%B9%8C%EC%A7%80-%EA%B3%A0%EB%A0%A4%ED%95%B4%EC%95%BC-%ED%95%A0%EA%B9%8C\">✅ 테스트는 어느 수준까지 고려해야 할까</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#-keep\">🔒 Keep</a></p>\n</li>\n<li>\n<p><a href=\"#-problem\">🚧 Problem</a></p>\n</li>\n<li>\n<p><a href=\"#-try\">🎯 Try</a></p>\n</li>\n</ul>\n</div>","excerpt":"우테코를 시작한지 한 달.. 드디어 여유가 생겼다. 생각보다 빠르게 한 달이 지나갔다. 미션 회고도 쓰고 여러 블로그 글도 쓰고 싶었지만, 미션 진행하고 우테코 생활 적응하는 것만으로도 바빠서 못하고 있었다. 사실 글 쓸 때 쓰고 지우고 고민하느라 시간이 많이 걸리는 게 한 몫 했다ㅎ,, 이미  미션과  미션을 끝내고  미션을 진행하고 있지만 늦게나마 지난 미션들을 회고해보려 한다. 자동차 경주 미션은 우테코에 들어와서 진행한 첫 미션이다. 모든 미션은 2개의 단계로 나뉘는데, 1단계는 페어 프로그래밍으로 진행하고 2단계는 혼자서 진행한다. 각 단계가 끝나면 리뷰어에게 코드 리뷰를 받고, 피드백을 반영하여 머지 되면 다음 단계를 진행하는 방식으로 한다. 사실 처음 미션을 시작하기 전에는 페어 프로그래밍이 무서웠다. 하나의 노트북으로 같이 페어 프로그래밍을 진행하면 내 실력이 낱낱이 드러날까봐 그게 무서웠다. 물론 지금도 어떤 페어와 매칭이 될지 미션이 시작하기 전에는 떨리긴 하지만…","frontmatter":{"date":"March 18, 2023","title":"[우아한테크코스] Level 1 - 자동차 경주 회고","categories":"우테코","author":"JFe","emoji":"🏎"},"fields":{"slug":"/wooteco-racingcar/"}},"next":{"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/"}},"prev":{"id":"531eee63-abcd-5ef4-a0e0-ac777ae9a54e","html":"<h2 id=\"-1단계---사다리-생성\" style=\"position:relative;\"><a href=\"#-1%EB%8B%A8%EA%B3%84---%EC%82%AC%EB%8B%A4%EB%A6%AC-%EC%83%9D%EC%84%B1\" aria-label=\" 1단계   사다리 생성 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🎞 1단계 - 사다리 생성</h2>\n<p><a href=\"https://github.com/woowacourse/java-ladder/pull/129\">1단계 PR</a></p>\n<h3 id=\"-1단계-기능-요구-사항-정리\" style=\"position:relative;\"><a href=\"#-1%EB%8B%A8%EA%B3%84-%EA%B8%B0%EB%8A%A5-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\" aria-label=\" 1단계 기능 요구 사항 정리 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🚀 1단계 기능 요구 사항 정리</h3>\n<ul>\n<li>사람 이름\n<ul>\n<li>입력받을 수 있다.\n<ul>\n<li>최대5글자까지 부여할 수 있다.</li>\n<li>사람 이름은 쉼표(,)를 기준으로 구분한다.</li>\n<li>영문만 입력받을 수 있다.</li>\n</ul>\n</li>\n<li>출력 형식에 맞게 변환하여 저장한다.\n<ul>\n<li>길이 제한에 따라 빈칸을 추가해 저장한다.</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>사다리 게임\n<ul>\n<li>사다리 높이를 입력받을 수 있다.\n<ul>\n<li>높이는 숫자여야 한다.</li>\n<li>숫자 제한: 음이 아닌 정수</li>\n</ul>\n</li>\n<li>라인을 추가할 수 있다.\n<ul>\n<li>추가되는 라인의 위치는 랜덤으로 결정된다.</li>\n<li>인접한 라인은 서로 겹치지 않도록 해야 한다.\n<ul>\n<li>ex) |-----|-----| 모양과 같이 가로 라인이 겹치는 경우</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>폭을 조정할 수 있다.\n<ul>\n<li>이름 길이 제한 기준을 따른다.\n<ul>\n<li>ex) 최대 5글자까지 부여 가능할 때, 사다리 폭은 5이다.</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>출력할 수 있다.\n<ul>\n<li>사람 이름도 같이 출력한다.</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<h3 id=\"-1단계-리팩토링-요구-사항-정리\" style=\"position:relative;\"><a href=\"#-1%EB%8B%A8%EA%B3%84-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\" aria-label=\" 1단계 리팩토링 요구 사항 정리 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🚀 1단계 리팩토링 요구 사항 정리</h3>\n<ul>\n<li>DTO 사용</li>\n<li>User 생성에 대한 예외 처리 문구 출력하도록 변경</li>\n<li>createLadder() 메서드 -> Ladder 생성자로 위치 이동</li>\n<li>points 네이밍 변경</li>\n<li>isContinuousTrue()에서 index를 직접 넘겨주지 않도록 변경</li>\n<li>isContinuousTrue()에서 RandomNumberGenerator 객체 생성 위치 변경</li>\n<li>LineStatus enum을 domain 패키지에서 view 패키지로 이동</li>\n<li>domain 패키지 내부에 하위 패키지 두기</li>\n<li>이름에 빈칸 추가하는 로직을 → 출력에 대한 부분으로 옮기기</li>\n<li>FixedNumberGenerator 클래스를 테스트 패키지로 이동</li>\n<li>NumberGenerator에서 BooleanGenerator로 네이밍 변경</li>\n<li>사용하지 않는 코드 삭제\n<ul>\n<li>사용하지 않는 import문 삭제</li>\n<li>InputVerifier 삭제</li>\n<li>중복된 테스트 삭제</li>\n</ul>\n</li>\n<li>테스트 파일이 테스트하는 객체와 동일한 이름의 패키지에 있도록 패키지 변경</li>\n</ul>\n<hr>\n<h3 id=\"-tdd\" style=\"position:relative;\"><a href=\"#-tdd\" aria-label=\" tdd 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>✅ TDD!</h3>\n<p>이번 프로그래밍 요구 사항에는<br>\n<code class=\"language-text\">모든 기능을 TDD로 구현해 단위 테스트가 존재해야 한다. 단, UI(System.out, System.in) 로직은 제외</code><br>\n라는 요구 사항이 추가되어서 TDD로 미션을 진행했다.</p>\n<p>TDD를 위해</p>\n<ol>\n<li>실패하는 테스트를 구현</li>\n<li>테스트를 통과하도록 프로덕션 코드에서 기능을 구현</li>\n<li>코드 리팩토링</li>\n</ol>\n<p>위 과정을 거쳐가며 구현했다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB6UlEQVQoz4WSzWsTQRiH8+8oBj2ooCCCtNgGbRADDVhFaq1ojSe/QLDeRA/ePHiwRXOp30KhstIKTaJSKiI223bpxn6QjNmuu7ObTDLZ3Zl5dXdjSzTW9zgzz8z7/N6JwBYlBAAwrUTT9+mzEW6bG4thRbYmOanaqSTu2mF2bq/eSjXJ3/y/Yc5cADqbxd07rQsJa+CoFd/jrqjc3+KbsPirAKBB6btsjq6odu8BHNtldkUrZ3sa2EBljTH2n5cRQjVCAMD9lKteHyDDF70lGQCqFVvTtE3YsiyMcSUo0zSFEISQctk/IbhoURF+w+h7yXGcJowQKhQKxWJRlmVVVR3HrdUqtE5Co8BQ+CEJwQPbhfyiPDffpu1QuLD64/GrvJRddt2mnoAgCEYzSHqhpNeM5T8DCy8u66Rn8GW0e3Tb4ZF7D2eDdJspPsjfTUzsT0oHr3w4bTu45WUWGI6NL0Rjo4mh14dOjHWeemrgerhrUr1/Mpaa7r2a6z8+sS9TklpgHsAzX9DeY+mOk092xx+dH57a6JkJ7+bMUN/bjsGp+JnJI0vWfKTdv4Lnb5TkpfHLtzPT77+urX5zPa9O642as6jN3fl87cbHc5mS1H7OIe8x319fX1cUBWOs67phGNwXE+HAfsE/AQEgs82x8IDlAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"tdd-cycle.png\"\n        title=\"tdd-cycle.png\"\n        src=\"/static/ba927de9e78cead37683e3bcd9645827/37523/tdd-cycle.png\"\n        srcset=\"/static/ba927de9e78cead37683e3bcd9645827/e9ff0/tdd-cycle.png 180w,\n/static/ba927de9e78cead37683e3bcd9645827/f21e7/tdd-cycle.png 360w,\n/static/ba927de9e78cead37683e3bcd9645827/37523/tdd-cycle.png 720w,\n/static/ba927de9e78cead37683e3bcd9645827/5caea/tdd-cycle.png 996w\"\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>개인적으로 아직 TDD가 좋은 개발 방법인지는 모르겠다.<br>\n일반적인 인간의 사고 방식과는 반대로 되어 있어서 이해하기 힘들다는 생각이 들기도 하고, 그래서인지 구현 후 테스트 작성을 하는 방식보다 더 시간이 오래걸렸다.</p>\n<p>그렇다고 장점이 아예 없다고 생각하지는 않는다.</p>\n<p>우선, 가장 큰 장점은 테스트를 강제하기 때문에 테스트 커버리지가 높아진다는 점.<br>\n기능 구현 후 단위 테스트를 작성하는 방식으로 해도 되지만, 아직은 익숙하지 않아서인지 단위 테스트를 작성하지 않고 수동 테스트를 통해 확인하고 넘어가는 경우가 많다. 서비스가 커지면 수동 테스트보다 단위 테스트를 통해 테스트를 하는 게 효율이 좋다고 생각하는데, 이 때 TDD로 개발하면 단위 테스트 작성을 강제할 수 있어서 좋다고 생각한다.</p>\n<p>또한 기능 구현 후 단위 테스트를 작성하는 방식은 이미 구현한 기능을 바탕으로 테스트 하게 되어서 예상 가능한 테스트만 하는 현상이 생길 수 있지만, 테스트 작성 후에 기능을 구현하면 이를 방지할 수 있다는 장점도 있다. (베로와의 대화에서 발췌,,)</p>\n<p>따라서 TDD도 각자 기준을 정해두는 것이 좋다고 생각한다.<br>\n지금은 학습 단계여서 100% TDD로 구현하고 있지만, 실제 서비스를 구현할 때는 TDD의 장단점을 잘 구분해서 상황에 맞게 사용해야 한다고 생각한다.</p>\n<h3 id=\"-모든-원시-값과-문자열을-포장하라\" style=\"position:relative;\"><a href=\"#-%EB%AA%A8%EB%93%A0-%EC%9B%90%EC%8B%9C-%EA%B0%92%EA%B3%BC-%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84-%ED%8F%AC%EC%9E%A5%ED%95%98%EB%9D%BC\" aria-label=\" 모든 원시 값과 문자열을 포장하라 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ 모든 원시 값과 문자열을 포장하라</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 41.11111111111111%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAzUlEQVQoz42S2QqEMAwA/f+f9Ml623orHlkmS6ULilsIqcGM09RoHEeJ41jSNJUkScRaK6zjOOQ8T9n3XfdhLczbtuk7PBMRxbZtFVgUheR5LmVZXjnLMq1XVaXRdZ2Gc076vtdepFgKZMMLxhiFkgFga0xymZMBAvHN4foxbJpGIaEJZlj6AOicvRqfQoF1XSvAW/KBZVlkmiY9zjzPMgyD1kKbWyAD9UBMgDIChn23Xg1pBPSdmdHMZazr+tr8eGQGze/CjWH8r80d8AN24mznYzYwxgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"additional-requirement.png\"\n        title=\"additional-requirement.png\"\n        src=\"/static/2f33181f7029d743277bb3307788715d/37523/additional-requirement.png\"\n        srcset=\"/static/2f33181f7029d743277bb3307788715d/e9ff0/additional-requirement.png 180w,\n/static/2f33181f7029d743277bb3307788715d/f21e7/additional-requirement.png 360w,\n/static/2f33181f7029d743277bb3307788715d/37523/additional-requirement.png 720w,\n/static/2f33181f7029d743277bb3307788715d/302a4/additional-requirement.png 1080w,\n/static/2f33181f7029d743277bb3307788715d/07a9c/additional-requirement.png 1440w,\n/static/2f33181f7029d743277bb3307788715d/c4451/additional-requirement.png 1450w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>이번 미션에는 여러 요구 사항이 추가되었는데 이 중에는 <code class=\"language-text\">모든 원시 값과 문자열을 포장한다</code>와 <code class=\"language-text\">일급 컬렉션을 쓴다</code>라는 객체지향 생활 체조 원칙 내용들도 포함되어 있었다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">User</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">Name</span> name<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">Position</span> position<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">User</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> position<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>name <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Name</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>position <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Position</span><span class=\"token punctuation\">(</span>position<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <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>그래서 위 코드와 같이 원시 값들을 포장하는 방식으로 구현했다.</p>\n<p>단순히 아래와 같이 원시 값을 필드로 가져도 되지만</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\">final</span> <span class=\"token class-name\">String</span> name<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">int</span> position<span class=\"token punctuation\">;</span></code></pre></div>\n<p><code class=\"language-text\">Name</code>과 <code class=\"language-text\">Position</code> 클래스를 새로 만들어서 각각의 역할과 책임을 따로 관리하도록 했다.</p>\n<p>처음에는 단순히 요구 사항이기 때문에 요구 사항을 만족시키기 위해 이렇게 구현했지만, 계속 미션을 진행하면서 코드가 길어지는 걸 보니 왜 이런 방식을 추구하는지 이해할 수 있었다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">Name</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">int</span> MIN_NAME_LENGTH <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">int</span> MAX_NAME_LENGTH <span class=\"token operator\">=</span> <span class=\"token number\">5</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">String</span> NAME_LENGTH_ERROR_MESSAGE <span class=\"token operator\">=</span>\n            <span class=\"token string\">\"[ERROR] 사람 이름은 \"</span> <span class=\"token operator\">+</span> MIN_NAME_LENGTH <span class=\"token operator\">+</span> <span class=\"token string\">\"~\"</span> <span class=\"token operator\">+</span> MAX_NAME_LENGTH <span class=\"token operator\">+</span> <span class=\"token string\">\"글자로 입력해 주세요.\"</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">String</span> NAME_FORMAT_ERROR_MESSAGE <span class=\"token operator\">=</span> <span class=\"token string\">\"[ERROR] 사람 이름은 영문자만 가능합니다.\"</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">String</span> NAME_REGEX_FORMAT <span class=\"token operator\">=</span> <span class=\"token string\">\"^[a-zA-z]*$\"</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">String</span> name<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">Name</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">validateNameLength</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token function\">validateNameFormat</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>name <span class=\"token operator\">=</span> name<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">void</span> <span class=\"token function\">validateNameLength</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">isValidLength</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">IllegalArgumentException</span><span class=\"token punctuation\">(</span>NAME_LENGTH_ERROR_MESSAGE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">boolean</span> <span class=\"token function\">isValidLength</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> name<span class=\"token punctuation\">.</span><span class=\"token function\">length</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;</span> MIN_NAME_LENGTH <span class=\"token operator\">||</span> name<span class=\"token punctuation\">.</span><span class=\"token function\">length</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> MAX_NAME_LENGTH<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">void</span> <span class=\"token function\">validateNameFormat</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>name<span class=\"token punctuation\">.</span><span class=\"token function\">matches</span><span class=\"token punctuation\">(</span>NAME_REGEX_FORMAT<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">IllegalArgumentException</span><span class=\"token punctuation\">(</span>NAME_FORMAT_ERROR_MESSAGE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">String</span> <span class=\"token function\">getName</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> name<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\">Name</code> 클래스에 대한 코드가 점점 길어졌다.<br>\n검증에 대한 일 뿐만 아니더라도 추후에 다른 메서드가 추가될 수 있다는 확장성을 고려한다면, 이렇게 원시값을 포장하는 것이 좋다고 생각한다.</p>\n<p>또한 <code class=\"language-text\">Name</code> 뿐만 아니라 <code class=\"language-text\">Position</code> 클래스도 상황이 비슷하기 때문에, 이런 코드들을 다 <code class=\"language-text\">User</code> 클래스에 두는 것보다는 클래스를 따로 만들어서 관리하는 것이 직관성에도 좋다고 생각한다.</p>\n<h3 id=\"-dto를-사용해보아요\" style=\"position:relative;\"><a href=\"#-dto%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EC%95%84%EC%9A%94\" aria-label=\" dto를 사용해보아요 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>✅ DTO를 사용해보아요</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: 21.111111111111114%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAxklEQVQY032O227CMBBE8ymlJTQX4ksax05i52YCVEGoD/3/XxnkDY+Ih9HujHRmNxK1w2n9h/U39Msd4+UP3bzS7k43yp1fMSx36P6MdvqF6jykGcGqDqyyJK4sEqYQZUKj6jxC8U87Q+oe2i1oxiukHra8mVCaEVw5AgOTCfOcGrk0SHmNOJOIirKFsh5VO8P6FWa40AdH2dDFlNUEBSD4oFCQi61kK2yQcY19KhAlhUKcl/j8ZqSvhNP8iI9vlL/0u0OBB6Mcf/IrHbI3AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"dto.png\"\n        title=\"dto.png\"\n        src=\"/static/8b8ef29d2f488e4b8e66125ed541851d/37523/dto.png\"\n        srcset=\"/static/8b8ef29d2f488e4b8e66125ed541851d/e9ff0/dto.png 180w,\n/static/8b8ef29d2f488e4b8e66125ed541851d/f21e7/dto.png 360w,\n/static/8b8ef29d2f488e4b8e66125ed541851d/37523/dto.png 720w,\n/static/8b8ef29d2f488e4b8e66125ed541851d/302a4/dto.png 1080w,\n/static/8b8ef29d2f488e4b8e66125ed541851d/07a9c/dto.png 1440w,\n/static/8b8ef29d2f488e4b8e66125ed541851d/c0566/dto.png 1544w\"\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>기존 코드에서는 View에 도메인 객체를 직접 넘겨주고 출력하도록 했다.<br>\n하지만 이렇게 하면 View에서 도메인 객체를 조작하는 문제가 생길 수 있어서 이를 방지하기 위해 DTO를 사용해서 도메인과 View 사이의 의존 관계를 끊어보라는 리뷰어의 피드백이 있었고, 이를 바탕으로 다음과 같이 수정했다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">LadderDto</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">LineDto</span><span class=\"token punctuation\">></span></span> lines<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token class-name\">LadderDto</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">LineDto</span><span class=\"token punctuation\">></span></span> lines<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>lines <span class=\"token operator\">=</span> lines<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\">LadderDto</span> <span class=\"token function\">from</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Ladder</span> ladder<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">LadderDto</span><span class=\"token punctuation\">(</span>ladder<span class=\"token punctuation\">.</span><span class=\"token function\">getLines</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">LineDto</span><span class=\"token punctuation\">></span></span> <span class=\"token function\">getLines</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> lines<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">LineDto</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Boolean</span><span class=\"token punctuation\">></span></span> line<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token class-name\">LineDto</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Boolean</span><span class=\"token punctuation\">></span></span> line<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>line <span class=\"token operator\">=</span> line<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\">LineDto</span> <span class=\"token function\">from</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Line</span> line<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">LineDto</span><span class=\"token punctuation\">(</span>line<span class=\"token punctuation\">.</span><span class=\"token function\">getLine</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Boolean</span><span class=\"token punctuation\">></span></span> <span class=\"token function\">getLine</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> line<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\">LadderDto</code>, <code class=\"language-text\">LineDto</code>, <code class=\"language-text\">PrizesDto</code>, <code class=\"language-text\">UsersDto</code>를 각각 만들어서 출력을 위해 <code class=\"language-text\">OutputView</code>에 넘겨줄 때, 도메인 객체를 넘기는 것이 아니라 해당하는 DTO 객체를 넘기도록 수정했다.</p>\n<hr>\n<h2 id=\"-2단계---사다리-게임-실행\" style=\"position:relative;\"><a href=\"#-2%EB%8B%A8%EA%B3%84---%EC%82%AC%EB%8B%A4%EB%A6%AC-%EA%B2%8C%EC%9E%84-%EC%8B%A4%ED%96%89\" aria-label=\" 2단계   사다리 게임 실행 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🎞 2단계 - 사다리 게임 실행</h2>\n<p><a href=\"https://github.com/woowacourse/java-ladder/pull/246\">2단계 PR</a></p>\n<h3 id=\"-2단계-리팩토링-요구-사항-정리\" style=\"position:relative;\"><a href=\"#-2%EB%8B%A8%EA%B3%84-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\" aria-label=\" 2단계 리팩토링 요구 사항 정리 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🚀 2단계 리팩토링 요구 사항 정리</h3>\n<ul>\n<li>enum으로 선언한 CarConstant를 Car 클래스 내부로 이동</li>\n<li>enum으로 선언한 InputConstant, OutputConstant를 OutputView 클래스 내부로 이동</li>\n<li>시도 횟수 검증에 대한 메서드를 Controller에서 Service로 이동</li>\n<li>distance에서 position으로 네이밍 변경</li>\n<li>Car 클래스의 책임 분리\n<ul>\n<li>Name 클래스 분리</li>\n<li>Position 클래스 분리</li>\n</ul>\n</li>\n<li>while문 대신 try-catch문 안에서 반복할 수 있도록 변경</li>\n<li>findWinner 메서드에 대한 책임 이동</li>\n<li>현재 위치 검증에 대한 메서드 위치 변경</li>\n<li>자동차 전진을 할 때 전략 패턴을 사용하도록 변경</li>\n<li>부족한 테스트 코드 작성</li>\n</ul>\n<hr>\n<h3 id=\"-요구사항과-확장성은-어디까지-고려해야-할까\" style=\"position:relative;\"><a href=\"#-%EC%9A%94%EA%B5%AC%EC%82%AC%ED%95%AD%EA%B3%BC-%ED%99%95%EC%9E%A5%EC%84%B1%EC%9D%80-%EC%96%B4%EB%94%94%EA%B9%8C%EC%A7%80-%EA%B3%A0%EB%A0%A4%ED%95%B4%EC%95%BC-%ED%95%A0%EA%B9%8C\" aria-label=\" 요구사항과 확장성은 어디까지 고려해야 할까 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>✅ 요구사항과 확장성은 어디까지 고려해야 할까</h3>\n<p>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: 67.22222222222223%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB1klEQVQ4y21T27KbMAzkKzrNycmFEG4GY2MDDklOL///UdtZGTPtTB+EJINXq5XIDscL8qKGNg79MKIfHAbrMbpFcm285MYFeG/R6x6na4mPz+s/djhGn/Fxvt5hxxluesDPD4w+iJ+WVc7S+WAnLI83zDijURpl3aFue4kbNeB0KZAdT7kgt90APz0EmCzJkMBmnFA1vXRRlC3uVSvxvVIoykbeMaa/3qoISGPV19cv6MFJxU5b8WyZcqjeou2M5Eka5p0eoXojOYGl5c9zvlWM1Vnpdm92VpGZ2o1saGw3vWP7l7yMDDkYHkzLU9p0UxD9Uj76RZgQ5PvHWb7/n+1DISNSpvjWLRvYCutmAWTMtih83WqozggBtswilIM5yWVEJu15eQogV4SD4TS9THcVm8MTc3jJeVjfUoQx76SYOFlsV8klYydpl+vB6TKOenWiE3VNWifPM3oy5PoJIKf5/vEb6+unWFi/9pjMnA/CLsqwiKbMo38KGTKVPUwt80MKn3RMe0UGjMkgTlP9NfF2yyPjHZCXYpWwMQg7cKuGvWUOJK1I02oUlUatrOwlyRBYABlQv2EzLjUXnb8bJ5tYkSm7qZsOt7LH4huYLse3w2X/p/8ATDiGoMxfxxwAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"qna-1.png\"\n        title=\"qna-1.png\"\n        src=\"/static/8519143ac6d6f61d91e877a63df5759f/37523/qna-1.png\"\n        srcset=\"/static/8519143ac6d6f61d91e877a63df5759f/e9ff0/qna-1.png 180w,\n/static/8519143ac6d6f61d91e877a63df5759f/f21e7/qna-1.png 360w,\n/static/8519143ac6d6f61d91e877a63df5759f/37523/qna-1.png 720w,\n/static/8519143ac6d6f61d91e877a63df5759f/302a4/qna-1.png 1080w,\n/static/8519143ac6d6f61d91e877a63df5759f/daed9/qna-1.png 1426w\"\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: 88.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAABYlAAAWJQFJUiTwAAACk0lEQVQ4y21U2W4UMRDcP0C8ICDJ3jv37blndpMNCrxHKHwREuKnC1U5HiLBQ8s943Z3dXXZq083G5z8GOP8gKYbESUFtnsPn2+3Mu5VdY+mm3A4Bbjb7HG3OeDmbvdfW/HQ7XoPP0wxjBfMlyvyskZeNihNiyQrZWlu4AUxkqxS7MfPaxDMW2OuFZ3DKUSclsiKGnU7oqga1O2Aompl3CPS/THAyY/kE+3Ri5b/9De7k0VIhwiYkG0TGZMSJVfumaYXurJyezVK0ymGZppBVK1c72Gc6xCDGUhkRMtAVicKdkJ/d/C10rb70/J/vT3ahETJBOSvG85CxGREy2E4nwVN3aMfz6Kk7WdUptPQ2n5ClOR/EZILJmXbnOLu4Km6279d28L0iYQxNPrrrfU5XHFIRERGNP1wVpuUUT9eEKeFpBREmeJIjS2w1+qm62z17v0HcSLogt8tg2EbHARb4hDSvNLEKSMWoYwc6kWHz8/f8eXpmwbBBERCFFYSkQ44FE57bxH+I+zfv37i5eUH/CgT2WzLiTd8bZOoWITmKCDnQZQKgB8miteUbVU75evjV5zvHzFM93i4PmE6X8XpND+I4/l81T45VuG0RF7UAkAtssgiG1a32hukRYnYdDpstdnqmxxTPt0wL9KhT7qWhOSF8DkMbtjBTKrqBYk1P9YBa5H+0Xft0tdNITo6PBwnBcI4QxCm4o2B9v7GC1cuESfM/aMXauX3wiFJni+PKEyHOKvET5SUr/fUckTJkBI3HN4KJmfhKM5VkFdQrw0rFHwIigpt06KqDKqyQtv1at9e/h7DdFFxSsq1ydX51LMSslLbj2iMwdi3aGuDsav1beoWdTcKlXsE+HRZbmN907cPhYc/1EQfzkWKBikAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"qna-2.png\"\n        title=\"qna-2.png\"\n        src=\"/static/cd59ff9cbc2fc6f292c5a2d7dd534974/37523/qna-2.png\"\n        srcset=\"/static/cd59ff9cbc2fc6f292c5a2d7dd534974/e9ff0/qna-2.png 180w,\n/static/cd59ff9cbc2fc6f292c5a2d7dd534974/f21e7/qna-2.png 360w,\n/static/cd59ff9cbc2fc6f292c5a2d7dd534974/37523/qna-2.png 720w,\n/static/cd59ff9cbc2fc6f292c5a2d7dd534974/302a4/qna-2.png 1080w,\n/static/cd59ff9cbc2fc6f292c5a2d7dd534974/e515d/qna-2.png 1430w\"\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>아래는 고민 과정을 담은 학습로그.<br>\n<a href=\"http://jfelog.netlify.app/wooteco-writing-1/\">요구사항과 확장성은 어디까지 고려해야 할까</a></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>TDD 적용하기</li>\n<li>기능 요구 사항과 구현할 내용을 미리 정리해두고 구현하기</li>\n<li>일관성 있게 코드 작성하기</li>\n<li>도메인과 뷰 사이의 의존 관계 제거하기</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\">DTO</code>에 대해 제대로 이해하고 사용하지 않았음</li>\n<li>테스트가 필요하지만 작성하지 않은 부분이 아직 있음</li>\n<li>변수 명이나 메서드 명의 네이밍이 명확하지 않음</li>\n<li>메서드의 역할과 책임 분리 생각하기</li>\n</ul>\n<h2 id=\"-try\" style=\"position:relative;\"><a href=\"#-try\" aria-label=\" try permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🎯 Try</h2>\n<ul>\n<li>메서드의 책임을 고려해 필요한 인자만 전달하기</li>\n<li>지난 미션의 피드백도 기억하고 계속 반영하기</li>\n<li>테스트 커버리지 100% 가깝게 도전</li>\n</ul>\n<div class=\"table-of-contents\">\n<ul>\n<li>\n<p><a href=\"#-1%EB%8B%A8%EA%B3%84---%EC%82%AC%EB%8B%A4%EB%A6%AC-%EC%83%9D%EC%84%B1\">🎞 1단계 - 사다리 생성</a></p>\n<ul>\n<li><a href=\"#-1%EB%8B%A8%EA%B3%84-%EA%B8%B0%EB%8A%A5-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\">🚀 1단계 기능 요구 사항 정리</a></li>\n<li><a href=\"#-1%EB%8B%A8%EA%B3%84-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\">🚀 1단계 리팩토링 요구 사항 정리</a></li>\n<li><a href=\"#-tdd\">✅ TDD!</a></li>\n<li><a href=\"#-%EB%AA%A8%EB%93%A0-%EC%9B%90%EC%8B%9C-%EA%B0%92%EA%B3%BC-%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84-%ED%8F%AC%EC%9E%A5%ED%95%98%EB%9D%BC\">✅ 모든 원시 값과 문자열을 포장하라</a></li>\n<li><a href=\"#-dto%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EC%95%84%EC%9A%94\">✅ DTO를 사용해보아요</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#-2%EB%8B%A8%EA%B3%84---%EC%82%AC%EB%8B%A4%EB%A6%AC-%EA%B2%8C%EC%9E%84-%EC%8B%A4%ED%96%89\">🎞 2단계 - 사다리 게임 실행</a></p>\n<ul>\n<li><a href=\"#-2%EB%8B%A8%EA%B3%84-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-%EC%9A%94%EA%B5%AC-%EC%82%AC%ED%95%AD-%EC%A0%95%EB%A6%AC\">🚀 2단계 리팩토링 요구 사항 정리</a></li>\n<li><a href=\"#-%EC%9A%94%EA%B5%AC%EC%82%AC%ED%95%AD%EA%B3%BC-%ED%99%95%EC%9E%A5%EC%84%B1%EC%9D%80-%EC%96%B4%EB%94%94%EA%B9%8C%EC%A7%80-%EA%B3%A0%EB%A0%A4%ED%95%B4%EC%95%BC-%ED%95%A0%EA%B9%8C\">✅ 요구사항과 확장성은 어디까지 고려해야 할까</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#-keep\">🔒 Keep</a></p>\n</li>\n<li>\n<p><a href=\"#-problem\">🚧 Problem</a></p>\n</li>\n<li>\n<p><a href=\"#-try\">🎯 Try</a></p>\n</li>\n</ul>\n</div>","frontmatter":{"date":"April 19, 2023","title":"[우아한테크코스] Level 1 - 사다리 타기 회고","categories":"우테코","author":"JFe","emoji":"🪜"},"fields":{"slug":"/wooteco-ladder/"}},"site":{"siteMetadata":{"siteUrl":"https://jfelog.netlify.app","comments":{"utterances":{"repo":"Go-Jaecheol/Jfe_Blog"}}}}},"pageContext":{"slug":"/wooteco-racingcar/","nextSlug":"/wooteco-pre-final/","prevSlug":"/wooteco-ladder/"}},
    "staticQueryHashes": ["1073350324","1956554647","2938748437"]}