<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>이재원의 티스토리</title>
    <link>https://slog2.tistory.com/</link>
    <description>코드리뷰와 테스트코드를 좋아하는 백엔드 개발자의 티스토리입니다</description>
    <language>ko</language>
    <pubDate>Fri, 31 Jul 2026 17:16:17 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>이재원님</managingEditor>
    <image>
      <title>이재원의 티스토리</title>
      <url>https://tistory1.daumcdn.net/tistory/1647822/attach/957fdf9c95804f06804a7cbe7e8cfdc3</url>
      <link>https://slog2.tistory.com</link>
    </image>
    <item>
      <title>[리팩터링 2판] 2장 리팩터링 원칙</title>
      <link>https://slog2.tistory.com/40</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 장에서는 시야를 넓혀 리팩터링 전반에 적용되는 원칙 몇 가지를 이야기하는 시간을 가져보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2.1 리팩터링 정의&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리팩터링 : [명사] 소프트웨어의 겉보기 동작은 그대로 유지한 채, 코드를 이해하고 수정하기 쉽도록 내부 구조를 변경하는 기법&lt;/li&gt;
&lt;li&gt;리팩터링(하다) : [동사] 소프트웨어의 겉보기 동작은 그대로 유지한 채, 여러 가지 리팩터링 기법을 적용해서 소프트웨어를 재구성하다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;수많은 사람이 코드를 정리하는 작업을 모조리 리팩터링이라고 표현하고 있는데, 앞에서 제시한 정의한 방식에 따라 코드를 정리하는 것만이 리팩터링이다.&lt;/u&gt; 리팩터링을 동작을 보존하는 작은 단계들을 거쳐 코드를 수정하고, 이러한 단계 들을 순차적으로 연결하여 큰 변화를 만들어내는 일이다. 개별 리팩터링은 아주 작을 수도 있고, 작은 단계 여러 개가 합쳐진 모습일 수도 있다. 따라서 리팩터링 하는 동안에는 코드가 항상 정상 작동하기 때문에 전체 작업이 끝나지 않았더라도 언제든 멈출 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;누군가 &quot;리팩터링 하다가 코드가 깨져서 며칠이나 고생했다&quot; 라고 한다면, 십중팔구 리팩터링한 것이 아니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 번에 바꿀 수 있는 작업을 수많은 단계로 잘게 나눠서 작업하는 모습을 처음 접하면 리팩터링하는 것이 오히려 비효율적이라고 생각하기 쉽다. 하지만 이렇게 나눔으로써 오히려 더 빨리 작업할 수 있다. 단계들이 체계적으로 구성되어 있고, &lt;u&gt;무엇보다 디버깅하는 데 시간을 뺏기지 않기 때문이다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링은 성능 최적화와 비슷하다. 둘 다 코드를 변경하지만 프로그램의 전반적인 기능은 그대로 유지한다. 단지 목적이 다를 뿐이다.&lt;br /&gt;리팩터링의 목적은 코드를 이해하고 수정하기 쉽게 만드는 것이다. 프로그램 성능은 좋아질 수도, 나빠질 수도 있다. 반면 성능 최적화는 오로지 속도 개선에만 신경 쓴다. 그래서 목표 성능에 반드시 도달해야 한다면 코드는 다루기에 더 어렵게 바뀔 수도 있음을 각오해야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2.2 두 개의 모자&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 소프트웨어를 개발할 때 목적이 '기능 추가'냐, 아니면 '리팩터링'이냐를 명확히 구분해 작업한다.&lt;br /&gt;켄트 벡은 이를 두 개의 모자에 비유했다. 기능을 추가할 때는 '기능 추가' 모자를 쓴 다음 기존 코드는 절대 건드리지 않고 새 기능을 추가하기만 한다. 진척도는 테스트를 추가해서 통과하는지 확인하는 방식으로 측정한다. 반면 리팩터링 할 때는 '리팩터링' 모자를 쓴 다음 기능 추가는 하지 않기도 다짐한 뒤 오로지 코드 재구성에만 전념한다. 테스트도 새로 만들지 않는다. 부득이 인터페이스를 변경해야 할 때만 기존 테스트를 수정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 소프트웨어를 개발하는 동안 두 모자를 자주 바꿔 쓴다. 새 기능을 추가하다 보면 코드 구조를 바꿔야 작업하기 쉽겠다는 생각이 들거나 코드가 이해하기 어렵게 짜인 경우 모자를 바꿔 쓰고 리팩터링한 후에 어느 정도 개선되면 다시 모자를 바꿔 쓰고 기능 추가를 이어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;전체 작업 시간이 10분 정도로 짧다 해도, 항상 내가 쓰고 있는 모자가 무엇인지와 그에 따른 미묘한 작업 방식의 차이를 분명하게 인식해야 한다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2.3 리팩터링하는 이유&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링이 모든 문제를 해결하는 만병통치약은 절대 아니다. 하지만 코드를 건강하게 유지하는데 도와주는 약임은 분명하다. 리팩터링은 다양한 용도로 활용할 수 있고, 반드시 그래야 하는 도구다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;리팩터링 하면 소프트웨어 설계가 좋아진다&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링하지 않으면 소프트웨어의 내부 설계(아키텍처)가 썩기 쉽다. &lt;u&gt;아키텍처를 충분히 이해하지 못한 채 단기 목표만을 위해 수정하다 보면 기반 구조가 무너지기 쉽다.&lt;/u&gt; 그러면 코드를 보고 설계를 파악하기 어려워진다. 코드만으로 설계를 파악하기 어려워질수록 설계를 유지하기 어려워지고, 설계가 부패되는 속도는 더욱 빨라진다. 반면 규칙적인 리팩터링은 코드의 구조를 지탱해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설계가 나쁘면 코드가 길어지기 십상이다. 같은 일을 하는 코드가 여러 곳에 나타날 수 있기 때문이다. 그래서 중복 코드 제거는 설계 개선 작업의 중요한 한 축을 차지한다. 코드량을 줄인다고 시스템이 빨라지는 것은 아니다. 프로그램의 용량이 속도에 영향을 주는 경우는 별로 없다. 하지만 코드량이 줄면 수정하는데 드는 노력은 크게 달라진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드가 길수록 실수 없이 수정하기 어려워진다. 이해해야 할 코드량도 늘어난다. 비슷한 일을 하는 코드가 산재해 있다면 한 부분만 살짝 바꿔서는 시스템이 예상대로 작동하지 않을 수 있다. 반면 중복 코드를 제거하면 모든 코드가 언제나 고유한 일을 수행함을 보장할 수 있으며 이는 바람직한 설계의 핵심이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;리팩터링하면 소프트웨어를 이해하기 쉬워진다&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래밍은 여러 면에서 컴퓨터와 대화하는 것과 같다. 컴퓨터에게 시킬 일을 표현하는 코드를 작성하면, 컴퓨터는 정확히 시킨 대로 반응한다. 그런데 내 소스 코드를 컴퓨터만 사용하는 게 아니다. 예컨대 몇 달이 지나 누군가 내 코드를 수정하고자 읽게 될 수 있다. 사실 프로그래밍에서는 사람이 가장 중요하지만 소홀하기 쉽다.&lt;br /&gt;코드를 컴파일하는데 시간이 살짝 더 걸린다고 누가 뭐라 하겠는가? &lt;u&gt;하지만 다른 프로그래머가 내 코드를 제대로 이해했다면 한 시간에 끝낼 수정을 일주일이나 걸린다면 사정이 달라진다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 프로그램을 동작시키는 데만 신경 쓰다 보면 나중에 그 코드를 다룰 개발자를 배려하지 못한다는데 있다. 잘 작동하지만 이상적인 구조는 아닌 코드가 있다면, 잠깐 시간을 내서 리팩터링해보자. 그러면 코드를 작성한 의도를 더 명확하게 전달하도록 개선할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단지 다른 사람을 배려하기 위해서는 아니다. 사실 그 다른 사람이 바로 나 자신일 때가 많다. 그래서 더더욱 리팩터링이 중요하다. 난 굉장히 게으른 프로그래머다. 단적인 예로 내가 작성한 코드를 전혀 머리에 담아두지 않는다. 코드를 보면 알 수 있는 것들은 의도적으로 기억하지 않는다. 내 기억 용량을 초과할까 봐 두렵기 때문이다. 그래서 기억할 필요가 있는 것들은 최대한 코드에 담으려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;리팩터링하면 버그를 쉽게 찾을 수 있다&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 이해하기 쉽다는 말은 버그를 찾기 쉽다는 말이기도 하다. 리팩터링하면 코드가 하는 일을 깊이 파악하게 되면서 새로 깨달은 것을 곧바로 코드에 반영하게 된다. 프로그램의 구조를 명확하게 다듬으면 그냥 '이럴 것이다'라고 가정하던 점들이 분명하게 드러나는데, 버그를 지나치려야 지나칠 수 없을 정도까지 명확해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 사실은 켄트 벡의 말을 떠올리게 해준다. &quot;난 뛰어난 프로그래머가 아니에요. 단지 뛰어난 습관을 지닌 괜찮은 프로그래머일 뿐이에요.&quot; 리팩터링은 견고한 코드를 작성하는 데 무척 효과적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;리팩터링하면 프로그래밍 속도를 높일 수 있다&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 내용을 정리하면 다음과 같다. &lt;u&gt;리팩터링하면 코드 개발 속도를 높일 수 있다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;얼핏 그 반대로 생각할 수 있다. 내가 사람들에게 리팩터링에 대해 설명하면 품질을 높일 수 있다는 점에는 대부분 쉽게 수긍한다. 내부 설계와 가독성이 개선되고 버그가 줄어든다는 점은 모두 품질 향상에 직결된다. 하지만 리팩터링 하는데 시간이 드니 전체 개발 속도는 떨어질까 봐 걱정할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 시스템을 오래 개발 중인 개발자들과 얘기하다 보면 초기에는 진척이 빨랐지만 현재는 새 기능을 하나 추가하는 데 훨씬 오래 걸린다는 말을 많이 한다. 새로운 기능을 추가할수록 기존 코드베이스에 잘 녹여낼 방법을 찾는 데 드는 시간이 늘어난다는 것이다. 게다가 기능을 추가하고 나면 버그가 발생하는 일이 잦고, 이를 해결하는 시간은 한층 더 걸린다. 패치에 패치가 덧붙여지면서 프로그램의 동작을 파악하기가 거의 고대 유적 발굴만큼 어려워진다. 이러한 부담이 기능 추가 속도를 계속 떨어뜨리면서, 차라리 처음부터 새로 개발하는 편이 낫겠다고 생각하는 지경에 이른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정을 그래프로 표현하면 대략 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;poor.png&quot; data-origin-width=&quot;857&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cC0nwz/btrwm9y92Kl/OQJkrCpLlzLNGfNqWRqEn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cC0nwz/btrwm9y92Kl/OQJkrCpLlzLNGfNqWRqEn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cC0nwz/btrwm9y92Kl/OQJkrCpLlzLNGfNqWRqEn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcC0nwz%2Fbtrwm9y92Kl%2FOQJkrCpLlzLNGfNqWRqEn0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;857&quot; height=&quot;257&quot; data-filename=&quot;poor.png&quot; data-origin-width=&quot;857&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&amp;lt;그래프 용어 설명&amp;gt;&lt;br /&gt;- cumulative functionality : 기능의 누적&lt;br /&gt;- time : 구현 속도&lt;br /&gt;- high internal quality : 좋은 설계&lt;br /&gt;- low internal quality : 나쁜 설계&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 어떤 팀은 이와 전혀 다른 양상을 보인다. 이들은 기존에 작성한 코드를 최대한 활용할 수 있어서 새 기능을 더 빨리 추가한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;both.png&quot; data-origin-width=&quot;857&quot; data-origin-height=&quot;406&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ellbc7/btrwp03rP6e/gwkulbaJzFKHHLv6SkKzs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ellbc7/btrwp03rP6e/gwkulbaJzFKHHLv6SkKzs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ellbc7/btrwp03rP6e/gwkulbaJzFKHHLv6SkKzs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fellbc7%2Fbtrwp03rP6e%2FgwkulbaJzFKHHLv6SkKzs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;857&quot; height=&quot;406&quot; data-filename=&quot;both.png&quot; data-origin-width=&quot;857&quot; data-origin-height=&quot;406&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 차이의 원인은 소프트웨어의 내부 품질에 있다. 내부 설계가 잘 된 소프트웨어는 새로운 기능을 추가할 지점과 어떻게 고칠지를 쉽게 찾을 수 있다. 모듈화가 잘 되어 있으면 전체 코드베이스 중 작은 일부만 이해하면 된다. 코드가 명확하면 버그를 만들 가능성도 줄고, 버그를 만들더라도 디버깅하기가 훨씬 쉽다. 내부 품질이 뛰어난 코드베이스는 새 기능 구축을 돕는 견고한 토대가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 이 효과를 설계 지구력 가설(Design Stamina Hypothesis)이라고 부른다. 내부 설계에 심혈을 기울이면 소프트웨어의 지구력이 높아져서 빠르게 개발할 수 있는 상태를 더 오래 지속할 수 있다. 정말 그런지는 증명할 수 없어서 '가설'이라고 표현했다. 하지만 수많은 뛰어난 프로그래머들의 경험이 이를 뒷받침한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;20년 전만 해도 설계를 잘하려면 코딩을 시작하기 전에 설계부터 완벽히 마쳐야 한다는 것이 정설이었다. 코딩 단계에 한번 들어서면 코드가 부패할 일만 남았기 때문이다. 한변 리팩터링을 하면 기존 코드의 설계를 얼마든지 개선할 수 있으므로, 설령 프로그램 요구사항이 바뀌더라도 설계를 지속해서 개선할 수 있다. 처음부터 좋은 설계를 마련하기란 매우 어렵다. 그래서 빠른 개발이라는 숭고한 목표를 달성하려면 리팩터링이 반드시 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2.4 언제 리팩터링해야 할까?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 프로그래밍할 때 거의 한 시간 간격으로 리팩터링한다. 그러다 보니 내 작업 흐름에 리팩터링을 녹이는 방법이 여러 가지임을 알게 됐다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;준비를 위한 리팩터링: 기능을 쉽게 추가하게 만들기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링하기 가장 좋은 시점은 코드베이스에 기능을 새로 추가하기 직전이다. 이 시점에 코드를 살펴보면서, 구조를 살짝 바꾸면 다른 작업을 하기 훨씬 쉬워질 만한 부분을 찾는다. 버그를 잡을 때도 마찬가지다. 오류를 일으키는 코드가 세 곳에 복제되어 퍼져 있다면, 우선 한 곳으로 합치는 편이 작업하기에 훨씬 편하다. 또는 질의 코드에 섞여 있는 갱신 로직을 분리하면 두 작업이 꼬여서 생기는 오류를 줄일 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;비유하면 지금 위치에서 동쪽으로 100km를 이동하려는데 그 사이를 숲이 가로막고 있다면, &lt;br /&gt;좀 둘러가더라도 20km 북쪽에 있는 고속도로를 타는 편이 세 배나 빠를 수 있다. &lt;br /&gt;다들 &quot;직진!&quot;을 외치더라도, 떄로는 &quot;잠깐, 지도를 보고 가장 빠른 경로를 찾아보자&quot;라고 말할 줄 알아야 한다. &lt;br /&gt;준비를 위한 리팩터링이 바로 이런 역할을 한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;이해를 위한 리팩터링: 코드를 이해하기 쉽게 만들기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 수정하려면 먼저 그 코드가 하는 일을 파악해야 한다. 그 사람은 자신일 수도 있고 다른 사람일 수도 있다. 나는 코드를 파악할 때마다 그 코드의 의도가 더 명확하게 드러나도록 리팩터링할 여지가 없는지 찾아본다. 조건부 로직의 구조가 이상하지 않은지 살펴보기도 하고, 함수 이름을 잘못 정해서 실제로 하는 일을 파악하는 데 시간이 오래 걸리지는 않는지도 살펴본다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 나중은 물론 지금 당장 효과를 볼 떄도 많다. 어떤 역할을 하는지 이해된 변수는 적절한 이름으로 바꿔주고, 긴 함수를 잘게 나누기도 한다. 그러면 코드가 깔끔하게 정리되어 전에는 보이지 않던 설계가 눈에 들어오기 시작한다. 코드를 분석할 때 리팩터링을 해보면, 그렇지 않았더라면 도달하지 못했을 더 깊은 수준까지 이해하게 된다. 이해를 위한 리팩터링을 의미 없이 코드를 만지작거리는 것이라고 무시하는 이들은 코드 아래 숨어 있는 다양한 기회를 결코 발견할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;쓰레기 줍기 리팩터링&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 파악하던 중에 비효율적으로 처리하는 모습을 발견할 때가 있다. 이때 약간 절충을 해야 한다. 원래 하려던 작업과 관련 없는 일에 너무 많은 시간을 빼앗기긴 싫을 것이다. 그렇다고 쓰레기가 나뒹굴게 방치해서 나중에 일을 방해하도록 내버려 두는 것도 좋지 않다. 조금이나마 개선해두는 것이 좋다. 캠핑 규칙이 제안하듯, 항상 처음 봤을 때보다 깔끔하게 정리하고 떠나자. 코드를 훑어볼 때마다 조금씩 개선하다 보면 결국 문제가 해결될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;계획된 리팩터링과 수시로 하는 리팩터링&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링은 과거에 저지른 실수를 바로잡거나 보기 싫은 코드를 정리하는 작업이라고 오해하기 쉽다. 잘 작성된 코드 역시 수많은 리팩터링을 거쳐야 한다. 어제는 적합했던 기준이 오늘 하는 다른 작업에는 맞지 않을 수 있다. 상황이 변해 기준을 변경해야 할 때 코드가 이미 깔끔하다면 리팩터링하기가 더 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뛰어난 개발자는 새 기능을 추가하기 쉽도록 코드를 '수정'하는 것이 그 기능을 가장 빠르게 추가하는 길일 수 있음을 안다. 소프트웨어 개발을 끝이 있는 작업으로 보면 안 된다. 새 기능이 필요할 떄마다 소프트웨어는 이를 반영하기 위해 수정된다. 이때 새로 작성해 넣는 코드보다 기존 코드의 수정량이 큰 경우가 대체로 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그동안 리팩터링에 소홀했다면, 따로 시간을 내서 새 기능을 추가하기 쉽도록 코드베이스를 개선할 필요가 있다. 하지만 계획된 리팩터링을 하게 되는 일은 최소한으로 줄여야 한다. 리팩터링 작업 대부분은 드러나지 않게, 기회가 될 때마다 해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;오래 걸리는 리팩터링&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링은 대부분 몇 분 안에 끝난다. 하지만 팀 전체가 달려들어도 몇 주는 걸리는 대규모 리팩터링도 있다. 라이브러리를 새것으로 교체하거나 골치 아픈 의존성을 정리하는 작업일 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 상황에 처하더라도 팀 전체가 리팩터링에 매달리는 데는 회의적이다. 그보다는 주어진 문제를 몇 주에 걸쳐 조금씩 해결해가는 편이 효과적일 때가 많다. 누구든지 리팩터링해야 할 코드와 관련한 작업을 하게 될 때마다 원하는 방향으로 조금씩 개선하는 식이다. 리팩터링이 코드를 깨트리지 않는다는 장점을 활용하는 것이다. 일부를 변경해도 모든 기능이 항상 올바르게 동작한다. 예컨대 라이브러리를 교체할 때는 기존 것과 새것 모두를 포용하는 추상 인터페이스부터 마련한다. (이 전략을 &lt;a href=&quot;https://martinfowler.com/bliki/BranchByAbstraction.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;추상화 갈아타기&lt;/a&gt;라 한다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;코드 리뷰에 리팩터링 활용하기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 작성자가 참석해야 맥락을 설명해줄 수 있고 작성자도 리뷰어의 변경 의도를 제대로 이해할 수 있으므로, 이왕이면 참석자가 참석하는 방식이 좋다. 가장 좋은 방법은 작성자와 나란히 앉아서 코드를 훑어가면서 리팩터링하는 것이다. 이렇게 하면 자연스럽게 짝 프로그래밍이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;관리자에게는 뭐라고 말해야 할까?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 가장 많이 받는 질문 중 하나는 &quot;관리자에게 리팩터링에 대해 어떻게 말해야 하나요?다. 리팩터링만을 위한 일정을 몇 주씩 잡는 개발팀을 보면 오해는 더욱 커진다. 설상가상으로 실제로는 리팩터링이 아닌, 어설픈 재구성 작업을 하면서 코드베이스를 오히려 망가뜨리는 모습을 보면 불신이 증폭된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관리자가 기술에 정통하고 설계 지구력 가설도 잘 이해하고 있다면 오히려 관리자가 리팩터링을 권장할 뿐만 아니라 팀이 리팩터링을 충분히 하고 있는지 살펴보기도 한다. 그러면 팀이 수행하는 리팩터링이 과도할 수는 있어도, 부족할 가능성은 거의 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 기술을 모르는 상당수의 관리자와 고객은 코드베이스의 건강 상태가 생산성에 미치는 영향을 모른다. 이런 상황에 있는 이들에게는 &quot;리팩터링한다고 말하지 말라&quot;고 조언하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하극상일까? 그렇진 않다. 소프트웨어 개발자는 프로다. 프로 개발자의 역할은 효과적인 소프트웨어를 최대한 빨리 만드는 것이다. 내 경험상 리팩터링하면 소프트웨어를 빨리 만드는데 아주 효과적이다. 일정을 최우선으로 여기는 관리자는 최대한 빨리 끝내는 방향으로 진행하기를 원한다. 그리고 구체적인 방법은 개발자가 판단해야 한다. 프로 개발자에게 주어진 임무는 새로운 기능을 빠르게 구현하는 것이고, 가장 빠른 방법은 리팩터링이다. 그래서 리팩터링부터 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;리팩터링하지 말아야 할 때&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지의 이야기가 무조건 리팩터링을 권장한다고 들릴 수 있는데, 리팩터링하면 안 되는 상황도 있다.&lt;br /&gt;지저분한 코드를 발견해도 굳이 수정할 필요가 없다면 리팩터링하지 않는다. 외부 API 다루듯 호출해서 쓰는 코드라면 지저분해도 그냥 둔다. 내부 동작을 이해해야 할 시점에 리팩터링해야 효과를 제대로 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링하는 것보다 새로 작성하는 게 쉬울 때도 리팩터링하지 않는다. 이런 결정을 내리기는 쉽지 않다. 직접 리팩터링해보기 전에는 어느 쪽이 쉬운지 확실히 알 수 없을 때도 많기 때문이다. 리팩터링할지 새로 작성할지를 잘 결정하려면 뛰어난 판단력과 경험이 뒷받침돼야 한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2.5 리팩터링 시 고려할 문제&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;새 기능 개발 속도 저하&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링의 궁극적인 목적은 개발 속도를 높이는 데 있다. 하지만 리팩터링으로 인해 진행이 느려진다고 생각하는 사람이 여전히 많다. 이 점이 실전에서 리팩터링을 제대로 적용하는 데 가장 큰 걸림돌인 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇더라도 상황에 맞게 조율해야 한다. 예컨대 대대적인 리팩터링이 필요해 보이지만, 추가하려는 새 기능이 아주 작아서 기능 추가부터 하고 싶을 수 있다. 이럴 때는 프로 개발자로서 가진 경험을 잘 발휘해서 결정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;코드 소유권&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링하다 보면 모듈의 내부뿐 아니라 시스템의 다른 부분과 연동하는 방식에도 영향을 주는 경우가 많다. 함수를 호출하는 코드의 소유자가 다른 팀이라서 나에게는 쓰기 권한이 없을 수 있다. 또는 바꾸려는 함수가 고객에게 API로 제공되는 것이라면 누가 얼마나 쓰고 있는지, 실제로 쓰이기나 하는지조차 모를 수 있다. 이런 공개된 인터페이스는 사용하여 기존 함수를 그대로 유지하되 함수 본문에서 새 함수를 호출하도록 수정하는 전략이 필요하다. (deprecated)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 복잡해지기 때문에 나는 코드 소유권을 작은 단위로 나눠 엄격히 관리하는 데 반대하는 입장이다. 내가 선호하는 방식은 코드의 소유권을 팀에 두는 것이다. 그래서 팀원이라면 누구나 팀이 소유한 코드를 수정할 수 있게 한다. 프로그래머마다 각자가 책임지는 영역이 있을 수는 있다. 이 말은 자신이 맡은 영역의 변경 사항을 관리하라는 뜻이지, 다른 사람이 수정하지 못하게 막으라는 뜻이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 코드 소유권을 느긋하게 정하는 방식은 여러 팀으로 구성된 조직에도 적용할 수 있다. 다른 팀 코드의 브랜치를 따서 수정하고 커밋을 요청하는 흡사 오픈소스 개발 모델을 권장하기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;브랜치&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능 브랜치 방식에는 단점이 있다. 독립 브랜치로 작업하는 기간이 길어질수록 작업 결과를 마스터로 통합하기 어려워진다. 머지가 복잡해지는 문제는 기능별 브랜치들이 독립적으로 개발되는 기간이 길어질수록 기하급수적으로 늘어난다. 이 때문에 기능별 브랜치의 통합 주기를 2~3일 단위로 짧게 관리해야 한다고 주장하는 사람이 많다. 한편 나와 같은 사람들은 더 짧아야 한다고 주장한다. 이 방식을 지속적 통합(CI, Continuous Integration), 또는 트렁크 기반 개발(TBD, Trunk-Based Development)이라 한다. CI에 따르면 모든 팀원이 하루에 최소 한 번은 마스터와 통합한다. 하지만 &lt;u&gt;CI를 적용하기 위해서는 마스터를 건강하게 유지하고, 거대한 기능을 잘게 쪼개는 법을 배우고, 각 기능을 끌 수 있는 기능 토글(feature toggle(flag))를 적용하여 완료되지 않은 기능이 시스템 전체를 망치지 않도록 해야 한다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;머지의 복잡도를 줄일 수 있어서 CI를 선호하기도 하지만, 가장 큰 이유는 리팩터링과 궁합이 좋기 때문이다. 켄트 벡이 CI와 리팩터링을 합쳐서 익스트림 프로그래밍(XP)을 만든 이유도 바로 두 기법이 궁합이 잘 맞기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능별 브랜치를 사용하면 안 된다는 말을 아니다. 브랜치를 자주 통합할 수만 있다면 문제가 발생할 가능성을 크게 줄일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스팅&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;절차를 지켜 제대로 리팩터링하면 동작이 깨지지 않아야 한다. 핵심은 오류를 재빨리 잡는 데 있다. 실제로 이렇게 하려면 코드의 다양한 측면을 검사하는 테스트 스위트(test suite)가 필요하다. 그리고 이를 빠르게 실행할 수 있어야 수시로 테스트하는데 부담이 없다. 리팩터링을 하기 위해서는 자가 테스트 코드를 마련해야 한다는 뜻이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자가 테스트 코드는 리팩터링을 할 수 있게 해 줄 뿐만 아니라, 새 기능 추가도 훨씬 안전하게 진행할 수 있도록 도와준다. 실수로 만든 버그를 빠르게 찾아서 제거할 수 있기 때문이다.&amp;nbsp; 이때 핵심은 테스트가 실패한다면 가장 최근에 통과한 버전에서 무엇이 달라졌는지 살펴볼 수 있다는 데 있다. 테스트 주기가 짧다면 단 몇 줄만 비교하면 버그를 훨씬 쉽게 찾을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자가 테스트 코드는 통합 과정에서 발생하는 의미 충돌을 잡는 메커니즘으로 활용할 수 있어서 자연스럽게 CI와도 밀접하게 연관된다. CI에 통합된 테스트는 XP의 권장사항이자 지속적 배포(CD, Continous Delivery)의 핵심이기도 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;레거시 코드&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레거시 시스템을 파악할 때 리팩터링이 굉장히 도움된다. 제 기능과 맞지 않은 함수 이름을 바로 잡고 어설픈 프로그램 구문을 매끄럽게 다듬어서 거친 원석 같던 프로그램을 반짝이는 보석으로 만들 수 있다. 하지만 이러한 희망찬 스토리에 테스트가 없다는 사실이 찬물을 끼얹는 때가 많다. 대규모 레거시 시스템을 테스트 코드 없이 명료하게 리팩터링하기는 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제의 정답은 당연히 테스트 보강이다. 하지만, 막상 해보면 생각보다 훨씬 까다롭다. 테스트를 염두에 두고 설계한 시스템만 쉽게 테스트할 수 있기 때문이다. 물론 그런 시스템이라며 테스트를 갖추고 있을 것이라서 애초에 이런 걱정을 할 일이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 해결할 방법은 없다. 그나마 레거시 코드 활용 전략의 조언에 따르면 '프로그램에서 테스트를 추가할 틈새를 찾아서 시스템을 테스트해야 한다'는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;데이터베이스&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 리팩터링은 프로덕션 환경에 여러 단계로 나눠서 릴리즈하는 것이 대체로 좋다. 이렇게 하면 프로덕션 환경에서 문제가 생겼을 때 변경을 되돌리기 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를테면 필드 이름을 바꿀 때 첫 번째 커밋에서는 새로운 필드를 추가만 하고 사용하지 않는다. 그런 다음 기존 필드와 새 필드를 동시에 업데이트하도록 설정한다. 그다음에는 데이터베이스를 읽는 클라이언트들을 새 필드를 사용하는 버전으로 조금씩 교체한다. 이 과정에서 발생하는 버그도 해결하면서 클라이언트 교체 작업을 모두 끝냈다면, 더는 필요가 없어진 예전 필드를 삭제한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;필드 이름 바꾸기 순서&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;데이터베이스에 새로운 필드를 추가만하고 사용하지 않는다.&lt;/li&gt;
&lt;li&gt;기존 필드와 새 필드를 동시에 업데이트 하도록 변경한다.&lt;/li&gt;
&lt;li&gt;데이터베이스를 읽는 클라이언트들을 새 필드를 사용하는 버전으로 조금씩 교체한다.&lt;/li&gt;
&lt;li&gt;교체 작업을 모두 끝냈다면 더는 필요 없어진 예전 필드를 삭제한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 데이터베이스를 변경하는 방식은 병렬 수정(parallel change) 또는 팽창-수축(expend-contract)의 일반적인 예다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2.6 리팩터링, 아키텍처, 애그니(YAGNI)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 프로그래밍을 시작하던 시절에는 코딩을 시작하기 전에 소프트웨어 설계와 아키텍처를 거의 완료해야 한다고 배웠다. 일단 코드로 작성된 뒤로는 아키텍처를 바꿀 수 없고 부주의로 인해 부패할 일만 남았다고 여기곤 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코딩 전에 아키텍처를 확정지으려 할 때의 대표적인 문제는 소프트웨어 요구사항을 사전에 모두 파악해야 한다는 것이다. 하지만 막상 우리는 소프트웨어를 실제로 사용해보고 업무에 미치는 영향을 직접 확인하고 나서야 정말로 원하는 바를 알게 되는 경우가 허다하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 가지 방법은 향후 변경에 유연하게 대처할 수 있는 유연성 메커니즘을 소프트웨어에 심어두는 것이다. 물론 메커니즘들이 대개 그렇듯 치러야 할 비용이 있다. 당장의 쓰임에 비해 함수가 너무 복잡해지며 간혹 유연성 메커니즘을 잘못 구현할 때도 있다. 요구사항이 당초 예상과 다르게 바뀌기 때문일 수도 있고, 설계한 메커니즘 자체에 결함이 있어서일 때도 있다. 이 모든 상황을 고려하다 보면 유연성 메커니즘이 오히려 변화에 대응하는 능력을 떨어뜨릴 때가 대부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링을 활용하면 그저 현재까지 파악한 요구사항만을 해결하는 소프트웨어를 구축한다. 단, 이 요구를 멋지게 해결하도록 설계한다. 진행하면서 사용자의 요구사항을 더 잘 이해하게 되면 아키텍처도 그에 맞게 리팩터링해서 바꾼다. 그 과정에서 복잡도를 높일 수 있는 유연성 메커니즘은 반드시 검증을 거친 후에 추가한다. 예상되는 변경을 미리 반영하는 리팩터링을 미루면 나중에 얼마나 어려워질지를 가늠해보면 판단에 도움 될 때가 많다. &lt;u&gt;리팩터링을 미루면 훨씬 힘들어진다는 확신이 들 때만 유연성 메커니즘을 미리 추가한다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 설계하는 방식을 간결한 설계, 점진적 설계, YAGNI(you aren't going to need it, 필요 없을 거다) 등으로 부른다. YAGNI를 받아들인다고 해서 선제적인 아키텍처에 소홀해도 된다는 뜻은 아니다. 리팩터링으로는 변경하기 어려워서 미리 생각해두면 시간이 절약되는 경우도 얼마든지 있다. 다만 이제는 둘 사이의 균형점이 크게 달라졌다. 나는 나중에 문제를 더 깊이 이해하게 됐을 때 처리하는 쪽이 훨씬 낫다고 생각하는 편이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2.7 리팩터링과 소프트웨어 개발 프로세스&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.5절을 읽었다면 팀이 따르는 실천법에 따라 리팩터링의 효과가 크게 달라진다. 실제로 리팩터링이 퍼지기 시작한 것도 익스트림 프로그래밍에 도입됐기 때문이다. XP의 특징은 지속적 통합, 자가 테스트 코드, 리팩터링 등의 개성이 강하면서 상호 의존하는 기법들을 하나로 묶은 프로세스라는 점이다.&lt;br /&gt;참고로 자가 테스트 코드와 리팩터링을 묶어서 테스트 주도 개발(TDD)이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;XP는 수년에 걸쳐 애자일의 부흥을 이끌었다. 지금은 상당수의 프로젝트에서 애자일을 적용하고 있어서 애자일 사고가 주류로 자리 잡았다. 하지만 현재 '애자일'을 내세우는 프로젝트 중에는 이름만 애자일인 경우가 대부분이다. 애자일을 제대로 적용하려면 리팩터링에 대한 팀의 역량과 열정이 뒷받침되어 프로세스 전반에 리팩터링이 자연스럽게 스며들도록 해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링의 첫 번째 토대는 자가 테스트 코드다. 다시 말해 프로그래밍 도중 발생한 오류를 확실히 걸러내는 테스트를 자동으로 수행할 수 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀으로 개발하면서 리팩터링을 하려면 각 팀원이 다른 사람의 작업을 방해하지 않으면서 언제든지 리팩터링할 수 있어야 한다. 지속적 통합을 적극 권장하는 이유도 바로 이 때문이다. 지속적 통합을 적용하면 각자가 수행한 리팩터링 결과를 빠르게 동료와 공유할 수 있다. 리팩터링한 결과가 다른 팀원의 작업에 문제를 일으키면 즉시 알아낼 수 있다. 자가 테스트 코드 역시 지속적 통합의 핵심 요소다. 따라서 자가 테스트 코드, 지속적 통합, 리팩터링이라는 세 기법은 서로 강력한 상승효과를 발휘한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이상의 세 실천법을 적용한다면 앞 절에서 설명한 YAGNI 설계 방식으로 개발을 진행할 수 있따. 리팩터링과 YAGNI는 서로 긍정적인 영향을 준다. 리팩터링이 YAGNI의 토대인 동시에, YAGNI로 인해 리팩터링을 더욱 쉽게 할 수 있다. 추측에 근거한 수많은 유연성 메커니즘을 갖춘 시스템보다는 단순한 시스템이 변경하기가 훨씬 쉽기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지의 설명이 다소 간단해 보일 수 있지만 실무에 적용하기는 만만치 않다. 어떤 방법으로 하든 소프트웨어 개발을 여러 사람과 기계가 복잡하게 엮어 상호작용하는 까다로운 일이다. 지금까지 소개한 접근법은 이 복잡도를 다루는 데 효과적이라고 검증된 것이다. 물론 어떠한 접근법이든지 충분한 연습과 뒷받침돼야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2.8 리팩터링과 성능&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'직관적인 설계 vs 성능'은 중요한 주제다. 리팩터링하면 소프트웨어가 느려질 수도 있는 건 사실이다. 하지만 그와 동시에 성능을 튜닝하기는 더 쉬워진다. 하드 리얼타임 시스템을 제외한 소프트웨어를 빠르게 만드는 비결은, 먼저 튜닝하기 쉽게 만들고 나서 원하는 속도가 나게끔 튜닝하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 빠른 소프트웨어를 작성하는 방법 세 가지를 경험했다. 그중 가장 엄격한 방법은 시간 예산 분배(time budgeting) 방식으로, 하드 리얼타임 시스템에서 많이 사용한다. 설계를 여러 컴포넌트로 나눠서 컴포넌트마다 자원(시간과 공간) 예산을 할당한다. 심장 박동 조율기처럼 데이터가 늦게 도착하면 안 되는 시스템에서는 이러한 점이 굉장히 중요하다. 반면, 사내 정보 시스템과 같은 부류에는 맞지 않는 기법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 방법은 끊임없이 관심을 기울이는 것이다. 프로그래머라면 누구나 높은 성능을 유지하기 위해 무슨 일이든 한다. 직관적이어서 흔히 사용하는 방식이지만 실제 효과는 변변치 않다. 성능을 개선하기 위해 코드를 수정하다 보면 프로그램은 다루기 어려운 형태로 변하기 쉽고, 결국 개발이 더뎌진다. 결과적으로 소프트웨어가 더 빨라지면 충분한 보상을 얻겠지만 실제로 그런 경우는 별로 없다. 이 방식에서는 성능을 개선하기 위한&amp;nbsp; 최적화가 프로그램 전반에 퍼지게 되는데, 각각의 개선은 프로그램의 특정 동작에만 관련될 뿐, 정작 컴파일러와 런타임과 하드웨어의 동작을 제대로 이해하지 못한 채 작성할 때도 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성능에 대한 흥미로운 사실은, 대부분 프로그램은 전체 코드 중 극히 일부에서 대부분의 시간을 소비한다는 것이다. 그래서 코드 전체를 고르게 최적화한다면 그중 90%는 효과가 거의 없기 때문에 시간 낭비인 셈이다. 속도를 높이기 위해 투자한 시간(다른 관점에서 보자면 코드를 덜 명료하게 바꾸느라 투자한 시간)을 모두 날리는 행위다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성능 개선을 위한 세 번째 방법은 이 '90%의 시간은 낭비'라는 통계에서 착안한 것이다. 의도적으로 성능 최적화에 돌입하기 전까지는 성능에 신경 쓰지 않고 코드를 다루기 쉽게 만드는데 집중한다. 그러다 성능 최적화 단계가 되면 다음의 구체적인 절차를 따라 프로그램을 튜닝한다.&lt;br /&gt;먼저 프로파일러로 프로그램을 분석하여 시간과 공간을 많이 잡아먹는 지점을 알아낸다. 그러면 성능에 큰 영향을 주는 작은 부분들을 찾을 수 있다. 그런 다음 그 부분들을 개선한다. 이렇게 하면 성능에 큰 영향을 주는 부분만 집중해서 최적화하기 때문에 적은 노력으로 훨씬 큰 효과를 볼 수 있다. 이때도 물론 신중하게 작업해야 한다. 리팩터링할 때처럼 최적화를 위한 수정도 작은 단계로 나눠서 진행한다. 각 단계마다 컴파일과 테스트를 거치고 프로파일러를 다시 실행해본다. 성능이 개선되지 않았다면 수정 내용을 되돌린다. 이런 식으로 만족하는 성능에 도달할 때 까지 최적화 대상을 찾아서 제거하는 일을 계속한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로그램을 잘 리팩터링해두면 이런 식의 최적화에 두 가지 면에서 도움이 된다.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;첫째, 성능 튜닝에 투입할 시간을 벌 수 있다. 리팩터링이 잘 되어 있다면 기능 추가가 빨리 끝나서 성능에 집중할 시간을 더 벌 수 있다.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;둘째, 리팩터링이 잘 되어 있는 프로그램은 성능을 더 세밀하게 분석할 수 있다. 프로파일러가 지적해주는 코드의 범위가 더 좁아질 것이고, 그래서 튜닝하기 쉬워진다. 코드가 깔끔하면 개선안들이 더 잘 떠오를 것이고, 그중 어떤 튜닝이 효과가 좋을지 파악하기 쉽다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;리팩터링은 성능 좋은 소프트웨어를 만드는 데 기여한다. 단기적으로 보면 리팩터링 단계에서는 성능이 느려질 수도 있다. 하지만 최적화 단계에서 코드를 튜닝하기 훨씬 쉬워지기 때문에 결국 더 빠른 소프트웨어를 얻게 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2.9 리팩터링의 유래&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'리팩터링'이란 용어의 정확한 유래는 찾을 수 없었다. 실력 있는 프로그래머는 항상 자신의 코드를 정리하는 데 어느 정도의 시간을 할애해왔다. 복잡하고 지저분한 코드보다는 깔끔한 코드가 수정하기 쉽고, 처음부터 깔끔하게 작성하는 경우는 거의 없다는 것을 경험을 통해 알기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;켄트와 함께 프로젝트를 진행하면서 그가 리팩터링하는 모습을 지켜볼 수 있었고, 그래서 리팩터링할 때와 안 할 때의 생산성과 품질의 차이를 확실히 경험할 수 있었다. 하지만 아쉽게도 당시에는 실무 프로그래머가 읽을 책이 하나도 없었고, 리팩터링 전문가 중에서 그런 책을 쓰겠다는 사람도 없었다. 그래서 내가 그들의 도움을 받아서 이 책의 초판을 쓰게 된 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다행히 리팩터링이란 개념을 업계에서 잘 받아들였다. 이 책도 꽤 팔렸고 거의 모든 프로그래머가 리팩터링이란 용어를 쓰게 되었다. 하지만 이처럼 대중화되면서 코드를 재구성하는 모든 작업을 가리키는 느슨한 의미로 사용하는 사람이 많아졌다. 어쨌든 리팩터링은 주류 개발 기법으로 자리 잡았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2.10 리팩터링 자동화&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링과 관련하여 지난 수십 년 사이에 일어난 가장 큰 변화는 자동 리팩터링을 지원하는 도구가 등장한 것이다. 예를 들어 인텔리제이 IDEA, 이클립스에서 메서드 이름을 바꾸는 작업을 메뉴에서 클릭하는 것만으로 처리할 수 있다. 실제 리팩터링은 나 대신 개발 도구가 처리해주며, 따로 테스트할 필요가 없을 정도로 안정적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 자동 리팩터링이 믿을만하더라도 중간에 꼬인 부분이 없는지 이따금 테스트로 확인하는 것이 바람직하다. 나는 주로 자동 리팩터링과 수동 리팩터링을 함께 사용한다. 그래서 테스트도 충분히 거친다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2.11 더 알고 싶다면&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책은 특정 리팩터링 기법이 궁금할 때 찾아볼 수 있는 레퍼런스를 제공하는 데 주력했다. 리팩터링 연습에 주력한 책을 원한다면 윌리엄 웨이크가 쓴 '리팩터링 워크북'을 추천한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링 개척자 중 많은 이가 소프트웨어 패턴 커뮤니티에서도 활발히 활동하고 있다. 조슈야 케리에프스카는 '패턴을 활용한 리팩터링' 을 통해 두 분야를 잘 접목하고 있다. 이 책은 소프트웨어 패턴 분야에 지대한 영향을 준 '디자인 패턴' 책에서 가장 핵심적인 패턴을 골라, 코드를 패턴대로 재구성하기 위해 리팩터링하는 방법을 다룬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 분야에 특화된 리팩터링 책&lt;br /&gt;- 리팩토링 데이터베이스 (스캇 엠블러, 프라모드 사달게)&lt;br /&gt;- 리팩토링 HTML (엘리엇 러스티 해롤드)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 언어에 특화된 리팩터링 책&lt;br /&gt;- Refactoring: Ruby Edition (제이 필즈, 셰인 하비)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최신 자료를 보고 싶다면 이 책의 깃허브 지원 페이지와 리팩터링 웹사이트를 참고하기 바란다.&lt;br /&gt;- &lt;a href=&quot;https://github.com/WegraLee/Refactoring&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/WegraLee/Refactoring&lt;/a&gt;&lt;br /&gt;- &lt;a href=&quot;https://refactoring.com&quot;&gt;https://refactoring.com&lt;/a&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>소프트웨어공학, CS/리팩터링 2판</category>
      <category>Refactoring</category>
      <author>이재원님</author>
      <guid isPermaLink="true">https://slog2.tistory.com/40</guid>
      <comments>https://slog2.tistory.com/40#entry40comment</comments>
      <pubDate>Sat, 23 Apr 2022 15:08:31 +0900</pubDate>
    </item>
    <item>
      <title>[리팩터링 2판] 1장 리팩터링: 첫번째 예시</title>
      <link>https://slog2.tistory.com/39</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1장은 리팩터링의 진행 절차에 대한 구체적인 예시를 보여주는 리팩터링 맛보기 장이다.&lt;br /&gt;하지만 1장의 읽어보고 내용을 요약하는 게 무의미하다고 보여서 과감히 생략하고... 책을 읽는데 앞서 중요하다고 보이는 서문의 내용 일부를 대신 정리했다.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;리팩터링이란&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;u&gt;리팩터링은 겉으로 드러나는 코드의 기능(겉보기 동작)은 바꾸지 않으면서 내부 구조를 개선하는 방식&lt;/u&gt;으로 소프트웨어를 수정하는 과정이다.&lt;br /&gt;- 버그가 생길 가능성을 최소로 줄이면서 코드를 정리하는 정제된 방법으로 코드를 작성하고 난 뒤에 설계를 개선하는 일이다.&lt;br /&gt;- 예전부터 따르던 소프트웨어 개발 방법은 설계부터 하고 코드를 작성하는 순서다. 하지만 시간이 흐르면서 코드는 수정되고 시스템의 설계에 맞춘 구조는 점차 뒤죽박죽이 되어간다. 공학에 가깝던 코딩 작업은 서서히 해킹에 가까워진다.&lt;br /&gt;- 리팩터링의 각 단계는 간단하다 못해 지나칠 정도로 단순하지만 이런 사소한 수정도 누적되면 설계가 놀라도록 개선된다. 소프트웨어가 부식된다는 개념의 정반대가 바로 리팩터링이다.&lt;br /&gt;- 리팩터링을 하면 일의 균형이 바뀐다. 처음부터 완벽한 설계를 갖추기보다는 개발을 진행하면서 지속적으로 설계한다. 시스템을 구축하는 과정에서 더 나은 설계가 무엇인지 배우게 된다. 그 결과, &lt;u&gt;개발의 시작부터 끝까지 프로그램을 줄곧 우수한 설계를 유지한다.&lt;br /&gt;&lt;br /&gt;&lt;/u&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;책 전부를 읽지 않고 보는 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;리팩터링이 뭔지 모른다면 1장을&lt;/b&gt; : 1장의 예시를 보면 리팩터링 진행 절차를 명확하게 알 수 있다.&lt;br /&gt;- &lt;b&gt;리팩터링해야 하는 이유를 모르겠다면 1장과 2장을&lt;/b&gt; : 리팩터링이 무엇이고 왜 필요한지 설명해준다.&lt;br /&gt;- &lt;b&gt;리팩터링해야 할 곳을 찾고 싶을 때는 3장을&lt;/b&gt; : 리팩터링이 필요한 만한 곳에서 보내는 신호(악취)를 잡아내는 요령을 설명해준다.&lt;br /&gt;- &lt;b&gt;리팩터링을 실습하고 싶다면 1장부터 4장까지는 꼼꼼히 읽고, 나머지를 빠르게 훑어보자&lt;/b&gt; : 카탈로그(6~12장) 부분은 어떤 기법들이 있는지 정도만 대략 보면 되지, 세세한 부분까지 전부 이해할 필요는 없다. 리팩터링을 당장 해야 할 때 해당 기법 부분을 펼쳐 자세히 일고 따르면 된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;책에서 다루는 내용&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 절제되고 효율적인 방식으로 리팩터링하는 법을 알려주는 것이 목표다.&lt;br /&gt;- 코드에 버그가 생기지 않게 하면서 구조를 더 체계적으로 바꾸는 식으로 리팩터링 하는 방법을 설명한다.&lt;br /&gt;- 카탈로그 목록이 이 책의 햄시이다. 대부분의 개발자가 익혀야 할 필수 리팩터링들을 담고 있다. 이 내용은 1990년대 후반에&amp;nbsp;리팩터링을 처음 배운 이후로 계속 보강되었고, 지금도 다 기억하지 못해서 틈틈이 참고하고 있다. (저자인 마틴 파울러의 얘기)&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;누가 읽어야 하나&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 리팩터링을 배우려는 개발자&lt;br /&gt;- 리팩터링을 이미 이해하고 있는 사람에게도 교육용 자료로 가치가 있다. 숙련된 개발자가 동료들에게 멘토링해주는 데 활용할 수 있도록 다양한 리팩터링의 작동 원리를 설명하는데 공을 들였다.&lt;br /&gt;- 리팩터링은 코드에 집중하지만, &lt;u&gt;사실 시스템 설계에 미치는 영향이 크다. 그래서 선임개발자나 아키텍트라면 반드시 리팩터링의 원리를 이해하고 프로젝트에 활용해야 한다.&lt;/u&gt;&lt;br /&gt;- 정리된 용어는 설명을 대신할 수 있고 개발 도구가 제공하는 자동화된 리팩터링을 선택하는 데도 도움을 준다.&lt;/p&gt;</description>
      <category>소프트웨어공학, CS/리팩터링 2판</category>
      <category>Refactoring</category>
      <category>리팩터링이란</category>
      <category>리팩토링</category>
      <category>마틴파울러</category>
      <author>이재원님</author>
      <guid isPermaLink="true">https://slog2.tistory.com/39</guid>
      <comments>https://slog2.tistory.com/39#entry39comment</comments>
      <pubDate>Sun, 20 Mar 2022 14:01:45 +0900</pubDate>
    </item>
    <item>
      <title>그림으로 이해하는 AWS 구조와 기술 - 8장 알아 두면 좋은 AWS 서비스</title>
      <link>https://slog2.tistory.com/38</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8. 알아 두면 좋은 AWS 서비스&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS가 제공하는 서비스는 165종류 이상이다. 이 장에서는 그중 자주 사용하는 몇 가지 서비스를 알아보겠다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8.1 Amazon Route 53: AWS의 DNS 서비스&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon Route 53는 엔드포인트 한 개에 트래픽이 집중되지 않게 하거나, 서비스에 장애가 발생했을 때 신속하게 다른 네트워크로 전환해주는 기능이 있어 라우팅을 유연하게 관리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- DNS에 대한 용어는 DNS 설정과 요금 계산에 필요하기 때문에 꼭 알아 두어야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Resolver : 도메인 이름과 IP 주소를 상호 변환하는 것을 말한다. Amazon Route 53의 핵심 기능은 DNS 서버의 기능이다.&lt;/li&gt;
&lt;li&gt;라운드로빈 : 호스트명 하나에 IP 주소를 여러 개 할당하고, IP 반환을 요청하면 제일 앞쪽 IP부터 연결하려는 특성을 이용하여, 접속할 때마다 IP 주소를 반환하는 순서를 바꾸는 방식으로 IP 주소를 자의적으로 조정한다. 접속 대상의 IP 주소가 복수이기 때문에 서버 여러 대에 분산하는 것이 가능하다.&lt;/li&gt;
&lt;li&gt;트래픽 흐름 : 서버의 부하와 가장 효율이 좋은 서버의 IP 주소를 반환하도록 조정하는 것을 말한다. 지연이 적은 서버에 전송하는 지연 시간 기반 라우팅, 지리적으로 가까운 서버에 전송하는 Geo DNS, 서버의 가동 여부를 체크하여 가동되고 있지 않은 서버에 할당하지 않는 DNS 페일 오버(장애 극복 기능)를 조합하여 구성한다.&lt;/li&gt;
&lt;li&gt;호스트 영역 : DNS의 설정 단위로 도메인 전체 혹은 서브도메인을 말한다.&lt;/li&gt;
&lt;li&gt;레코드 : 도메인 및 서브도메인에 설정하는 항목으로, 설정 하나당 도메인과 IP 주소를 변환하기 위한 내용이 한 개씩 기록되어 있다.&lt;/li&gt;
&lt;li&gt;쿼리 : DNS에 대한 요청을 말한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요금 = 호스트 영역별 기본 요금 + 쿼리 건수에 대한 요금 + 상태 확인 요금&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;호스트 영역별 기본 요금
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;도메인이나 서브도메인 1개당 계산한다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;0.05 US달러/월(도메인 25개 이하의 경우)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;쿼리 건수에 대한 요금
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 도메인에 대한 쿼리 건수로 계산한다. 계산의 최저 단위는 100만 건이다.&lt;/li&gt;
&lt;li&gt;예를 들어 월별 표준 쿼리가 10만 개인 호스팅 영역에는 0.40 US달러이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;상태 확인 요금
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태 확인이란 서버의 리소스에 대한 상태나 성능을 감시하는 기능이다. 상태 체크는 50개까지 무료이며 50개를 넘으면 요금이 부가된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8.2 AWS Lambda: 서버리스 서비스이며 이벤트를 자동으로 실행한다&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS Lambda는 작은 프로그램을 실행하는 구조이며, 미리 등록해 두면 언제든 실행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 전용 서버를 구축하거나 따로 관리하지 않아도 필요한 이벤트가 자동으로 실행된다. 서버에 상주하는 프로그램과는 다르게 프로그램 실행 시에만 요금이 부과된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 새로운 프로그래밍 언어는 아니다. 잘 알려진 프로그래밍 언어로 작성한 코드를 바탕으로 'Lambda 콘솔'을 사용하여 GUI로 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Lambda를 호출하는 방법으로 세 가지가 있다. 대표적인 것이 S3나 SES, API Gateway와 조합하여 사용하는 방식이다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style6&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;Lambda가 이벤트를 &lt;/b&gt;&lt;br /&gt;&lt;b&gt;읽는 서비스&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;Lambda 함수를&lt;/b&gt;&lt;br /&gt;&lt;b&gt;동기적으로 호출하는 서비스&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;Lambda 함수를 &lt;br /&gt;비동기적으로 &lt;/b&gt;&lt;b&gt;호출하는 서비스&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;- Kinesis&lt;br /&gt;- DynamoDB&lt;br /&gt;- SQS&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;- ELB&lt;br /&gt;- ALB&lt;br /&gt;- Cognito&lt;br /&gt;- Lex&lt;br /&gt;- Alexa&lt;br /&gt;- API Gateway&lt;br /&gt;- CloudFront&lt;br /&gt;- Kinesis Data Firehose&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;- S3&lt;br /&gt;- SNS&lt;br /&gt;- SES&lt;br /&gt;- CloudFormation&lt;br /&gt;- CloudWatch Logs&lt;br /&gt;- CloudWatch Events&lt;br /&gt;- CodeCommit&lt;br /&gt;- Config&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;750&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mX5lr/btrh5YeAhAa/k3vajEDbKN459bGqSB4Qi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mX5lr/btrh5YeAhAa/k3vajEDbKN459bGqSB4Qi1/img.png&quot; data-alt=&quot;적용 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mX5lr/btrh5YeAhAa/k3vajEDbKN459bGqSB4Qi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmX5lr%2Fbtrh5YeAhAa%2Fk3vajEDbKN459bGqSB4Qi1%2Fimg.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;750&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;적용 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8.3 AWS 컨테이너 서비스: 애플리케이션 단위로 실행할 수 있는 가상 환경&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 컨테이너란 프로그램 실행 환경을 분리하는 방식이다. 도커는 유명한 컨테이너 형식 중 하나이다. AWS는 도커 형식의 컨테이너를 지원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일반적으로 컨테이너 서비스에는 컨테이너를 배치, 관리하기 위한 &lt;b&gt;'레지스트리 서비스'&lt;/b&gt;와 컨테이너로 분리된 애플리케이션의 실행과 컨테이너의 조정을 수행하는 &lt;b&gt;'오케스트레이션 서비스'&lt;/b&gt;가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS 의 레지스트리 서비스 : Amazon Elastic Container Registry(ECR)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS 의 오커스트레이션 서비스 : Amazon Elastic Container Service(ECS), Amazon ELastic Kubernetes Service(EKS)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 컨테이너의 개념을 이해하고 나면 AWS에서 컨테이너를 사용하기 쉬울 것이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨테이너 : 프로그램 전체를 분리하여 실행하는 시스템을 말한다.&lt;/li&gt;
&lt;li&gt;도커 이미지 : 컨테이너를 구성하는 프로그램이라 설정을 말한다.&lt;/li&gt;
&lt;li&gt;도커 허브 : 도커 이미지를 등록하는 서비스이다. AWS 도커 허브(Docker Hub)로 ECR을 사용한다.&lt;/li&gt;
&lt;li&gt;Amazon EC2 Container Registry(ECR) : 도커 이미지를 등록하는 서비스이다.&lt;/li&gt;
&lt;li&gt;Amazon ECS : 도커 이미지에서 EC2나 AWS Fargate에 컨테이너를 생성하여 실행하는 서비스이다.&lt;/li&gt;
&lt;li&gt;쿠버네티스 : 컨테이너를 종합 관리하는 방식이다.&lt;/li&gt;
&lt;li&gt;Amazon Elastic Container Service for Kubernetes(EKS) : AWS가 제공하는 쿠버네티스 서비스이다.&lt;/li&gt;
&lt;li&gt;AWS Fargate : 컨테이너를 실행하는 EC2를 자동으로 관리하기 위반 방식이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS Fargate는 필요에 따라 EC2 인스턴스를 가동하고 EC2 안에 컨테이너를 할당하고 실행하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- EC2 시작 유형의 경우는 'EC2 요금'만 발생하며 요금이 추가되지 않는다. Fargate 시작 유형의 경우는 &lt;b&gt;'(할당된 CPU당 실행 단가 x 가동 시간(분) x 컨테이너 수)&lt;/b&gt; + &lt;b&gt;(메모리 단가 x 가동 시간(분))&lt;/b&gt; + &lt;b&gt;(데이터 전송 요금)'&lt;/b&gt; 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;그 밖에 주목할 서비스&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Amazon SageMaker와 AWS Deep Learning AMI&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS에서 머신 러닝을 수행하려면 Amazon SageMaker를 사용하는 방법과 AWS Deep Learning AMI를 사용하는 방법이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon SageMaker는 머신 로닝 모델을 간단하고 빠르게 구축, 트레이닝, 호스트 환경에 배포하기 위한 완전 관리형 서비스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS Deep Learning AMI는 딥러닝 프레임워크와 인터페이스를 갖춘 Amazon EC2 인스턴스이다. 환경과 방법의 선택의 폭이 넓고 사용자 정의가 가능하며 머신 러닝에 대한 심층 연구에 적합하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AWS IoT Core&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS IoT Core 장치와 AWS 혹은 IoT 장치 사이의 인터넷 접속, 통신을 수행하기 위한 관리형 클라우드 서비스이다. 수십억 개의 IoT 장치와 수조 개의 메시지를 취급할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- IoT 장치에서 송신된 데이터를 처리할 수 있고, IoT 장치를 조작하는 애플리케이션을 개발하거나 실행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Amazon Lumberyard&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon Lumberyard는 게임 엔진이며 게임 편집기로 게임을 작성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 라이브 게임과 멀티플레이어 게임을 운영하거나 동적 콘텐츠를 이용할 때 AWS 클라우드와 통합된 Lumberyard의 특징을 잘 활용하면 편리하다.&lt;/p&gt;</description>
      <category>개발기타/그림으로 이해하는 AWS 구조와 기술</category>
      <category>aws fargate</category>
      <category>AWS Lambda</category>
      <category>ECR</category>
      <category>ECS</category>
      <category>eks</category>
      <category>route 53</category>
      <category>SageMaker</category>
      <author>이재원님</author>
      <guid isPermaLink="true">https://slog2.tistory.com/38</guid>
      <comments>https://slog2.tistory.com/38#entry38comment</comments>
      <pubDate>Tue, 19 Oct 2021 00:16:53 +0900</pubDate>
    </item>
    <item>
      <title>그림으로 이해하는 AWS 구조와 기술 - 7장 RDS</title>
      <link>https://slog2.tistory.com/37</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7장 데이터베이스 서비스 Amazon RDS&lt;/b&gt;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7.1 데이터베이스와 RDB: 데이터를 관리하는 시스템&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데이터베이스는 구조적으로 정리된 데이터의 집합체이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데이터베이스를 실제로 조작하는 것은 데이터베이스 관리 시스템(DBMS)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- DBMS의 종류로는 MySQL이나 PostgreSQL, Oracle Database가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 관계형 데이터베이스와 비관계형 데이터베이스가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7.2 Amazon RDS란: 주요 RDBMS를 제공하는 데이터베이스 서비스&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon Relational Database Service(Amazon RDS)는 관계형 데이터베이스 6종류의 제품을 클라우드에 최적화된 상태로 제공하는 서비스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데이터베이스의 제공 방식은 EC2와 비슷하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- EC2와 다른 점은 RDS는 '매니지드 서비스'이며 업데이트 등의 관리가 AWS에 의해 자동으로 이루어진다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 백업이 자동화되어 있으며 AWS Database Migration Server(DMS)를 사용하면 기존 데이터베이스를 이전하거나 복제하는 것도 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인스턴스 클래스는 표준, 메모리 최적화, 버스트 성능의 3종류가 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 99.8837%; height: 359px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;용도&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;인스턴스 클래스&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;내용&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;표준&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;db.m5 등&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;범용적인 인스턴스 클래스이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 80px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 180px;&quot; rowspan=&quot;3&quot;&gt;메모리 최적화&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 80px;&quot;&gt;db.x1e&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 80px;&quot;&gt;메모리를 많이 사용하는 애플리케이션에 최적화된 인스턴스 클래스로, 일부 리전에서만 제공된다. 한국 리전에서는 이용할 수 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 60px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 60px;&quot;&gt;db.x1&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 60px;&quot;&gt;메모리를 많이 사용하는 애플리케이션에 최적화된 인스턴스 클래스이다. 메모리 최대치가 db.x1e의 절반이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;db.r5 등&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;네트워크와 EBS의 성능을 강화한다. AWS Nitro System을 사용한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;버스트 성능&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;db.t3 등&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;CPU의 최대 사용률까지 버스트 성능으로 사용할 수 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RDS 요금 = 스토리지 요금 + 데이터베이스 인스턴스 요금 + 백업 스토리지 요금 + 통신료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스토리지 요금은 사용한 용량이 아닌 확보하고 있는 용량에 대해 과금되기 때문에 주의가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다중 AZ로 구성하여 이중화를 구축하면 단일 AZ 구성보다 약 2배의 요금이 부과된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 유료 DBMS의 경우에는 라이선스 요금까지 추가된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RDS 가 매니지드 서비스라는 점이 장점이자 단점이다. (쉬운 구축, 관리 vs 낮은 자유도, 한정적인 DBMS 종류 및 버전)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RDS의 자동 업데이트를 무시하는 옵션이 있다. 하지만 치명적인 취약점에 대한 업데이트를 무시하기 힘들고 오래된 버전은 AWS가 점점 지원을 종료하므로 어느 시점에는 업데이트를 해야한다. 즉, 업데이트를 하지 않는 선택은 문제를 미루는 것에 불과하다. 업데이트를 아예 하지 않는 선택지는 없다고 생각하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7.3 RDS에서 사용할 수 있는 DBMS: 데이터베이스 엔진을 선택한다&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RDS는 AWS가 만든 Amazon Aurora 외에도 PostgreSQL, MySQL, MariaDB, Oracle Database, SQL Server 등 데이터베이스 엔진 6종류를 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon Aurora는 MySQL이나 PostgreSQL과 호환할 수 있으며 AWS가 만든 관계형 데이터베이스이다. 요금이 비싼 편이지만 견고하고 성능이 뛰어나다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS에서 MySQL이나 PostgreSQL을 사용하는 방법은 3가지이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Amazon Aurora 를 사용하는 방법&lt;/li&gt;
&lt;li&gt;RDS를 사용하는 방법&lt;/li&gt;
&lt;li&gt;EC2에 설치하는 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7.4 RDS 사용 절차: 데이터베이스를 사용하기까지의 절차&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RDS 설치는 관리 콘솔의 대시보드에서 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데이터베이스 사용을 위한 조작은 관리 도구나 소프트웨어에서 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 어떤 데이터베이스 엔진을 사용할지 결정하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- EC2와 마찬가지로 데이터베이스 인스턴스의 종류도 다양하게 선택할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데이터베이스 인스턴스 설정 항목&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;인스턴스 클래스&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;데이터베이스 인스턴스의 사양이다. EC2와 같이 여러 인스턴스 클래스를 제공한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;다중 AZ 배포&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;두 개 이상의 AZ에 배포하여 이중화 구성 여부를 설정한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;스토리지 유형&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;스토리지의 종류이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;스토리지 할당&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;스토리지의 용량이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;자동 스케일링&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;스토리지가 부족할 때 자동으로 늘릴지 여부를 설정한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;스케일링 임계 값&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;자동 스케일링의 임계 값이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;데이터베이스 클러스터 식별자&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;AWS에서 데이터베이스 클러스터를 관리하기 위한 이름이다. 데이터베이스명이 아니므로 주의해야 한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;마스터 사용자명&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;데이터베이스 인스턴스의 관리자 권한을 가진 사용자명이다. 임의로 설정한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;마스터 사용자 암호&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;데이터베이스 인스턴스의 관리자의 암호이다. 임의로 설정한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 네트워크 설정 항목&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;VPC&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;RDS를 설치할 VPC이다. VPC의 생성은 VPC 대시보드에서 수행한다. 기본 VPC도 선택할 수 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;서브넷 그룹&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;RDS를 설치할 서브넷 그룹이다. EC2 인스턴스와 연동할 경우 동일한 곳에 설치하는 것이 일반적이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;퍼블릭 액세스 가능&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;데이터베이스 인스턴스에 공인 IP 주소를 할당할지 여부를 나타낸다. 같은 VPC 내의 서비스가 아닌 곳에서 데이터베이스에 직접 접속할 경우(회사 내 서버에서 직접 RDS에 접속해야 하는 경우를 말하지만 보안상으로 위험하므로 실제 사용 사례는 적을 것이다)에도 필요하다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;가용 영역&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;RDS를 설치할 가용 영역이다. EC2 인스턴스와 연동할 경우 동일한 곳에 설치하는 것이 일반적이다(사전에 정보를 알아 두어야 한다).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;보안 그룹&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;인스턴스 단위로 설정하는 방화벽이다. 사용할 포트를 열지 않으면 통신이 안 되므로 주의하자. 보안 그룹이 없으면 미리 만들어 두자. 설정하면서 생성도 가능하다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 관계형 데이터베이스는 구축하기 전에 설계를 먼저 해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7.5 키 밸류 데이터베이스: 키를 관리하는 데이터베이스 서비스&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 키 밸류 스토어(key value store) 데이터베이스란 데이터의 형식에 관계없이 어떤 데이터에 대해서 특정 '키'가 되는 값을 결합하여 저장하는 방식의 데이터베이스이다. 줄여서 KVS라고 표기한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 관계형 데이터베이스와 다르게 유연성이 높아서 형식에 구애받지 않고 데이터를 입력할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 반면, 어떤 것이든 데이터로 저장하므로 상세하게 검색할 수는 없다. 대신 데이터에 대한 액세스가 빠르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon DynamoDB : 키 밸류 스토어 데이터베이스이다. 범용적 데이터를 저장하는 데 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon ElastiCache : 인 메모리 데이터베이스이다. 메모리를 활용하여 처리 속도가 빠르며 Redis 용과 Memcached용이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7.6 그 외의 데이터베이스: 다양한 데이터베이스 서비스를 제공한다&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon DocumentDB는 문서 기반 데이터베이스를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon Neptune은 그래프 데이터베이스를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon Timestream은 시계열 데이터베이스를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon Quantum Ledger Database는 장부 데이터베이스를 제공한다.&lt;/p&gt;</description>
      <category>개발기타/그림으로 이해하는 AWS 구조와 기술</category>
      <category>amazon aurora</category>
      <category>Amazon RDS</category>
      <category>Dynamodb</category>
      <category>elasticache</category>
      <author>이재원님</author>
      <guid isPermaLink="true">https://slog2.tistory.com/37</guid>
      <comments>https://slog2.tistory.com/37#entry37comment</comments>
      <pubDate>Fri, 15 Oct 2021 00:31:19 +0900</pubDate>
    </item>
    <item>
      <title>그림으로 이해하는 AWS 구조와 기술 - 6장 VPC</title>
      <link>https://slog2.tistory.com/36</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6장 가상 네트워크 서비스 Amazon VPC&lt;/b&gt;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6.1 Amazon VPC란: AWS에 생성하는 가상 네트워크&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS 상에 네트워크를 구축하기 위해 사용되는 것이 Amazon VIrtual Private Cloud(Amazon VPC)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- EC2나 RDS의 경우 VPC를 선택하지 않으면 서버를 생성할 수 없기 때문에 리소스를 사용하기 위해서는 반드시 필요한 서비스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- VPC는 네트워크와 서브넷 범위, 라우팅 테이블, 네트워크 게이트웨이 등과 같은 가상 네트워킹 환경을 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- VPC의 주요 기능&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CIDR 블록&lt;/li&gt;
&lt;li&gt;서브넷 마스크&lt;/li&gt;
&lt;li&gt;가용 영역 (서브넷이 구축된 물리적 장소)&lt;/li&gt;
&lt;li&gt;인터넷 게이트웨이&lt;/li&gt;
&lt;li&gt;라우팅&lt;/li&gt;
&lt;li&gt;라우팅 테이블&lt;/li&gt;
&lt;li&gt;보안 그룹&lt;/li&gt;
&lt;li&gt;네트워크 ACL&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- VPC 네트워크의 특징&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소프트웨어가 라우팅한다. 라우터는 IP 주소를 갖지 않는다.&lt;/li&gt;
&lt;li&gt;라우팅 테이블 한 개에 서브넷 여러 개를 설정할 수 없다.&lt;/li&gt;
&lt;li&gt;VPC 한 개에 인터넷 게이트웨이는 한 개만 설정할 수 있고, IP 주소를 갖지 않는다.&lt;/li&gt;
&lt;li&gt;서브넷 사이의 통신은 라우터 없이 직접 통신할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요약&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스명 : Amazon VPC&lt;/li&gt;
&lt;li&gt;사용빈도 : &lt;span style=&quot;color: #666666;&quot;&gt;★★★★&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;요금 : AWS 사이트 간 VPC + Client VPC + 데이터 송신 + 옵션&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;매니지드 서비스 : X&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;서울 리전 : O&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;VPC : O&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6.2 VPC의 사용 절차: 가상 네트워크를 사용하자&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인터넷 연결 여부와 오토 스케일링이 설계의 중요 포인트이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인터넷에 연결해야 한다면 인터넷 게이트웨이를 설정해야 하고, 오토 스케일링을 설정해야 한다면 서버가 자동으로 늘어나기 때문에 IP 주소를 많이 확보해 두어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서브넷을 설정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 어떻게 해야 할지 잘 모를 때는 기본 VPC를 사용하기를 권장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6.3 기본 VPC: AWS가 제공하는 기본 VPC&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS는 네트워크 지식이 없어도 VPC를 사용할 수 있도록 리전별로 기본 VPC를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 특별한 요건이 없는 이상, 기본 VPC를 사용하는 편이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 기본 VPC는 서브넷과 인터넷 게이트웨이가 기본적으로 구성되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 기본 서브넷은 가용 영역별로 한 개씩 생성되어 있다. 서울 리전의 경우 총 4군데가 있다. (2021년 3월 기준)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인터넷 게이트웨이도 구성되어 있으므로 인터넷에 접속할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인터넷에 접속하고 싶지 않다면 별도의 VPC를 생성해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6.4 서브넷과 DHCP: 사용할 범위 선택&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서브넷이란 커다란 네트워크를 작게 나눈 네트워크를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 네트워크를 분할해 직접 통신할 수 있는 범위를 좁히고, 방화벽을 설정해 보안을 강화하는 것을 목적으로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 네트워크를 분할하려면 CIDR 표기를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 네트워크는 클래스를 가지고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1061&quot; data-origin-height=&quot;717&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QCpmC/btrhd7pVOu7/zLpEwzgpwQrX9V4uTnYk21/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QCpmC/btrhd7pVOu7/zLpEwzgpwQrX9V4uTnYk21/img.jpg&quot; data-alt=&quot;서브넷을 나눠서 서브넷별로 역할을 다르게 할 수 있다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QCpmC/btrhd7pVOu7/zLpEwzgpwQrX9V4uTnYk21/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQCpmC%2Fbtrhd7pVOu7%2FzLpEwzgpwQrX9V4uTnYk21%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;795&quot; height=&quot;537&quot; data-origin-width=&quot;1061&quot; data-origin-height=&quot;717&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;서브넷을 나눠서 서브넷별로 역할을 다르게 할 수 있다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6.5 라우팅과 NAT: 공인 IP 주소와 사설 IP 주소 변환&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 네트워크 간 데이터를 주고받으려면 라우팅이나 NAT(네트워크 주소 변환) 방식을 사용해야 한다. AWS를 사용할 때 이와 같은 네트워크 기초 지식이 부족하면 서비스를 구축하기 어려우므로 네트워크 기초 지식에 대한 공부가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 라우팅은 라우터에서 목적지까지 데이터를 송신하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- IP 주소는 목적지이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- LAN 내부의 출입구가 되는 것이 게이트웨이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- IP 마스커레이드는 일대다이며 공인 IP 주소와 사설 IP 주소를 변환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- NAT는 다대다이며 공인 IP 주소와 사설 IP 주소를 변환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- IP 마스커레이드는 포트를 변환할 수 있지만 NAT는 할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6.6 인터넷 게이트웨이와 NAT 게이트웨이: VPC에서 인터넷으로 접속&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인터넷 게이트웨이는 EC2 인스턴스와 인터넷을 연결한다.&amp;nbsp; (인터넷 -&amp;gt; EC2)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- NAT 게이트웨이는 EC2 인스턴스와 인터넷을 연결한다. 인터넷에서 서브넷으로 접속하지 못하게 할 수 있다.&amp;nbsp; (EC2-&amp;gt; 인터넷)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6.7 보안 그룹과 네트워크 ACL: 보안 설정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- VPC의 가상 방화벽으로 보안 그룹과 네트워크 ACL이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 보안 그룹은 인스턴스에 네트워크 ACL은 서브넷에 설정하는 가상 방화벽이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인바운드 트래픽(데이터가 유입되는 것)과 아웃바운드 트래픽(데이터가 유출되는 것)을 제어하는데 반드시 양쪽 모두 설정해야 하며 명시적으로 설정하지 않으면 기본 설정이 적용된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 100px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;보안 그룹&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;네트워크 ACL&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;설정 범위&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;인스턴스에 대해 설정한다(보안 그룹을 최대 5개 할당할 수 있다)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;서브넷에 설정한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;규칙&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;규칙 허용만 가능하다.&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;규칙 허용과 거부가 가능하다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;설정&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;스테이트풀(stateful)&lt;br /&gt;(규칙과 상관없이 반환된 트래픽을 자동으로 허용한다)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;스테이트리스(stateless)&lt;br /&gt;(반환된 트래픽을 규칙에 따라 명시적으로 허용한다)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;규칙의 적용 순서&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;모든 규칙을 확인하여 트래픽의 허가 여부를 정한다.&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;순서대로 규칙을 처리하면서 트래픽의 허가 여부를 결정한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6.8 VPC 엔드포인트: 다른 AWS 서비스 및 엔드포인트 서비스와 연결&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- VPC 엔드포인트란 VPC 내부에서 VPC 외부로 접속하기 위한 연결점을 제공하는 서비스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS의 모든 서비스가 VPC 내에 설치되어 있는 건 아니다. VPC를 사용하지 않는 대표적인 서비스로 S3와 DynamoDB가 있다. AWS 안에서는 전부 통신할 수 있을 거라 생각하는데, 일부러 인터넷 회선을 통해서 외부로 연결해야 한다면 작업도 번거롭고 보안 면에서도 불안할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이러한 단점을 보완하기 위해 인터넷 게이트웨이를 통하지 않고, S3와 같은 VPC 외부에 있는 서비스와 VPC를 직접 연결해주는 것이 엔드포인트 서비스이다. VPC의 출입구로 엔드포인트를 설정하면 S3와 직접 연결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인터페이스 엔드포인트 : 네트워크 인터페이스(ENI)로 구축하는 유형 (AWS PrivateLink 방식)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 게이트웨이 엔드포인트 : 라우팅 테이블에 설정된 내용을 라우팅하는 유형&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6.9 VPC 연결: VPC와 VPC의 연결과 VPC와 VPN의 연결&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS Direct Connect는 AWS 네트워크에 전용선을 물리적으로 연결하는 방법이다. (전용선 회선 공사, 라우터 설치가 필요하며 월 비용도 많이 발생한다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS VPN은 AWS 네트워크에 가상으로 전용선을 연결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 전송 게이트웨이는 VPC나 온프레미스 네트워크를 하나로 묶어서 서로 연결하는 연결점을 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발기타/그림으로 이해하는 AWS 구조와 기술</category>
      <category>amazon vpc</category>
      <category>VPC</category>
      <author>이재원님</author>
      <guid isPermaLink="true">https://slog2.tistory.com/36</guid>
      <comments>https://slog2.tistory.com/36#entry36comment</comments>
      <pubDate>Tue, 12 Oct 2021 00:07:28 +0900</pubDate>
    </item>
    <item>
      <title>그림으로 이해하는 AWS 구조와 기술 - 5장 S3</title>
      <link>https://slog2.tistory.com/35</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5장 스토리지 서비스 Amazon S3&lt;/b&gt;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.1 Amazon S3란: 사용하기 쉬우며 기능이 강력한 스토리지 서비스&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon S3(Amazon Simple Storage Service)는 스마트한 객체 스토리지 서비스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S3의 특징&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;확장성 : EC2와 마찬가지로 확장, 축소가 쉽다. 사용 목적에 맞게 다양한 스토리지 클래스가 준비되어 있고 수명주기 정책을 사용하여 자동으로 이동이 가능하다.&lt;/li&gt;
&lt;li&gt;가용성, 내구성 : 99.999999999%의 데이터 내구성을 가지고 있어 장애나 오류, 위협에 강하다. S3 객체는 최소 4개의 가용 영역에 자동으로 복제되어 보존되기 때문에 어느 한쪽에 장애가 발생하더라도 계속 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;신뢰성 : 암호화 기능과 접근 관리 도구가 있어 공격으로부터 지키기 쉽다. 각종 규정을 준수하며 감사 기능을 갖추고 있다.&lt;/li&gt;
&lt;li&gt;다양한 관리 기능 : 스토리지 클래스 분석, 수명 주기 정책등을 시작으로 각종 관리 기능이 있다.&lt;/li&gt;
&lt;li&gt;스마트한 기능 : S3 Select라는 데이터에 쿼리를 실행하는 기능과 서비스가 있다. 그 외에 Amazon Athena, Amazon Redshift Spectrum 등의 분석 서비스와 호환되고, AWS Lambda와 연동할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요약&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스명 : Amazon S3(S4)&lt;/li&gt;
&lt;li&gt;사용빈도 : ★★★★&lt;/li&gt;
&lt;li&gt;요금 : 저장 용량 + 전송량&lt;/li&gt;
&lt;li&gt;매니지드 서비스 : O&lt;/li&gt;
&lt;li&gt;서울 리전 : O&lt;/li&gt;
&lt;li&gt;VPC : X&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.2 스토리지 클래스: 다양한 종류의 스토리지&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S3 스토리지의 종류를 스토리지 클래스라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 버킷 단위가 아니고 객체(파일) 단위로 클래스를 서택할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스토리지 클래스 별 특징&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style7&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;Standard&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;Standard - Infrequent Access&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;Reduced Redundancy Storage&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;내구성이 높다&lt;br /&gt;(99.999999999%)&lt;br /&gt;가용성이 높다(99.99%)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;내구성이 높다&lt;br /&gt;&lt;span style=&quot;background-color: #f6f8fb;&quot;&gt;(99.999999999%)&lt;br /&gt;&lt;/span&gt;가용성이 조금 낮다(99.9%)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;내구성이 낮다(99.99%)&lt;br /&gt;가용성이 높다(99.99%)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S3 Glacier/S3 Glacier Deep Archive : 데이터 아카이브와 장기간 백업을 고려하여 만든 스토리지 클래스이다. 저렴한 가격으로 보관할 수 있지만 데이터는 '볼트'라고 하는 컨테이너에 저장된다. 따라서 저장된 데이터를 읽는 경우 다른 S3 버킷으로 옮겨야 하는 작업이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스토리지 클래스 요약&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스명 : 스토리지 클래스&lt;/li&gt;
&lt;li&gt;사용빈도 : ★★&lt;/li&gt;
&lt;li&gt;요금 : 스토리지 클래스의 종류에 따라 다르다.&lt;/li&gt;
&lt;li&gt;매니지드 서비스 : O&lt;/li&gt;
&lt;li&gt;서울 리전 : O&lt;/li&gt;
&lt;li&gt;VPC : X&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Glacier 요약&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스명 : S3 Glacier&lt;/li&gt;
&lt;li&gt;사용빈도 : ★★&lt;/li&gt;
&lt;li&gt;요금 : 스토리지 사용량 + 데이터 검색량 + 데이터 검색 요청 + 데이터 전송 + Glacier Select&lt;/li&gt;
&lt;li&gt;매니지드 서비스 : O&lt;/li&gt;
&lt;li&gt;서울 리전 : O&lt;/li&gt;
&lt;li&gt;VPC : X&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.3 S3의 사용 절차: 스토리지 서비스를 사용하기까지&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S3의 조작은 관리 콘솔의 대시보드에서 수행한다. 또한, API와 SDK를 사용하여 업로드할 수 있어 편리하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S3의 구성 요소로 버킷, 객체 키 등이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S3는 생성한 후에는 이름과 리전을 변경할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.4 객체와 버킷: 파일과 파일을 저장하는 장소&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S3에서는 드라이브를 버킷이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S3에서는 파일을 객체라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 버킷을 생성하면 리전과 버킷명을 변경할 수 없기 때문에 신중하게 결졍해야 한다. 특히 버킷명은 S3 안에서 유일한 이름이어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 버킷에는 명명 규칙이 있다. (처음과 마지막에 알파벳이나 숫자를 사용해야 한다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.5 버킷 정책과 사용자 정책: 액세스 제한 설정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S3 버킷에 대한 액세스 제한을 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 제한을 설정하는 방법은 3가지가 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;버킷 정책 : 해당 버킷에 접속할 수 있는 사용자를 지정한다. (사용자가 많은 경우 유리)&lt;/li&gt;
&lt;li&gt;사용자 정책 : 사용자가 접속 가능한 버킷을 지정한다. (버킷이 많은 경우 유리)&lt;/li&gt;
&lt;li&gt;ACL(액세스 제어 목록)에 의한 관리 정책 : 다른 AWS 계정의 읽기/쓰기에 대해서 허가 혹은 거부를 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 액세스 제한은 리소스, 작업, 효과, 보안 주체에 대해 설정할 수 있다. (누가, 무엇을, 어떤 것에 대해)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리소스 : 제한 대상이 되는 버킷 및 객체이다. 아마존 리소스 이름을 사용하여 대상을 식별한다.&lt;/li&gt;
&lt;li&gt;작업 : 실제로 가능한 작업을 말하며, GET(취득), PUT(배치), DELETE(삭제)가 있다. 작업 키워드를 사용하여 지정한다.&lt;/li&gt;
&lt;li&gt;효과 : 설졍 여부를 말한다. 허가(allow), 거부(deny)를 설정한다.&lt;/li&gt;
&lt;li&gt;보안 주체 : 허가 혹은 거부할 사용자 및 계정, 서비스 등을 말한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요약&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스명 : 버킷 정책&lt;/li&gt;
&lt;li&gt;사용빈도 : ★★★&lt;/li&gt;
&lt;li&gt;요금 : 무료&lt;/li&gt;
&lt;li&gt;매니지드 서비스 : O&lt;/li&gt;
&lt;li&gt;서울 리전 : O&lt;/li&gt;
&lt;li&gt;VPC : X&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.6 웹 사이트 호스팅: 웹 사이트 공개&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 웹 사이트 호스팅은 S3 버킷을 정적 웹 사이트로 공개하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon Lightsail은 필요한 기능을 선택하면 웹 사이트에 필요한 서비스 전체를 정가제로 구축할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS Amplify는 모바일 앱이나 웹 앱을 개발하기 위한 프레임워크이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.7 파일 업로드와 다운로드: 다양한 파일 업로드 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 멀티 파트 업로드는 객체를 여러 개로 분해하여 S3에 데이터를 업로드하는 기능이다. 100MB 이상의 파일은 이 기능을 사용할 것을 추천한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS Transfer for SFTP는 SFTP 서버를 제공하는 서비스이다. 서드 파티 도구(API, SDK)를 사용해서 파일을 전송할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS DataSync는 온프레미스 스토리지와 AWS 스토리지 서비스 간의 대용량 데이터를 이동할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.8 액세스 관리 및 변조 방지: 부정한 액세스 감시&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 액세스 로그는 서버에 어떤 요청이 있었는지를 기록하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스토리지 클래스 분석은 객체의 액세스 빈도를 분석하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 객체 잠금은 객체를 변경하지 못 하게 하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S3 인벤토리는 객체의 메타데이터의 목록을 생성하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S3 배치 작업은 객체에 대한 복사, 복원 등 다양한 작업을 실행할 수 있는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.9 버전 관리, 수명 주기, 복제: 저장된 객체 관리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 버전 관리는 객체를 여러 버전으로 저장하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 수명 주기 정책은 객체에 정기적으로 수행할 작업을 설정하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 교차 리전 복제는 객체를 다른 리전에 비동기로 복사하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.10 데이터 분석과 연계: 저장된 데이터의 분석&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S3 Select는 CSV와 같이 구조화된 텍스트 형식의 데이터에 대해 SELECT와 같은 SQL 문을 실행하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Athena는 CSV와 같이 구조화된 텍스트 형식의 데이터에 대해 SQL 문을 실행하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Redshifts는 S3의 데이터에 대해 SQL 문을 실행하는 기능이다. 대용량 데이터를 처리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.11 Amazon CloudFront: 콘텐츠 배포 서비스&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon CloudFront란 고속 콘텐츠 전송 네트워크(CDN, Content Delivery Network) 서비스이다. 웹 콘텐츠를 빠르게 전송한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이러한 고속화는 웹 서버의 내용을 캐시하는 엣지 서버를 사용하여 이루어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 엣지 서버는 그 이름처럼 각 리전의 네트워크 말단에 위치해 있다. 클라이언트가 접속하는 네트워크의 거리가 가깝기 때문에 이에 따른 반응 속도도 빨라진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요금 계층에 따라 사용할 수 있는 엣지 서버가 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요약&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스명 : Amazon CloudFront&lt;/li&gt;
&lt;li&gt;사용빈도 : ★★★&lt;/li&gt;
&lt;li&gt;요금 : 데이터 전송량 + 요청 + 옵션&lt;/li&gt;
&lt;li&gt;매니지드 서비스 : O&lt;/li&gt;
&lt;li&gt;서울 리전 : O&lt;/li&gt;
&lt;li&gt;VPC : X&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발기타/그림으로 이해하는 AWS 구조와 기술</category>
      <category>Amazon S3</category>
      <category>S3</category>
      <author>이재원님</author>
      <guid isPermaLink="true">https://slog2.tistory.com/35</guid>
      <comments>https://slog2.tistory.com/35#entry35comment</comments>
      <pubDate>Wed, 6 Oct 2021 02:08:21 +0900</pubDate>
    </item>
    <item>
      <title>그림으로 이해하는 AWS 구조와 기술 - 4장 EC2</title>
      <link>https://slog2.tistory.com/34</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4장 서버 서비스 Amazon EC2&lt;/b&gt;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.1 Amazon EC2란: 짧은 시간에 실행 환경을 구출할 수 있는 가상 서버&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon EC2는 서버와 서버에 필요한 것 전부를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 클릭 한 번으로 최적의 서버를 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 바로 생성할 수 있고 바로 삭제할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인스턴스 유형 및 OS를 선택한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요약&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스명 : Amazon EC2&lt;/li&gt;
&lt;li&gt;사용빈도 : ★★★★&lt;/li&gt;
&lt;li&gt;요금 : 인스턴스 사용량 + EBS 요금 + 통신료 + 그 외 옵션&lt;/li&gt;
&lt;li&gt;매니지드 서비스 : X&lt;/li&gt;
&lt;li&gt;서울리전 : O&lt;/li&gt;
&lt;li&gt;VPC : O&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.2 EC2의 사용 절차: 가상 서버를 사용하기까지&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- EC2는 관리 콘솔 대시보드에서 작업할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- EC2의 주요 기능에 대해서는 단어, 개념을 잘 알아 두자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인스턴스 : AWS 클라우드에 생성한 가상 서버를 의미한다.&lt;/li&gt;
&lt;li&gt;AMI : 가상 이미지를 말한다. 인스턴스를 생성하는 기준이 되는 금형과 같은 것이다.&lt;/li&gt;
&lt;li&gt;키 페어 : 인스턴스에 접속할 때 인증을 위해 사용하는 키이다.&lt;/li&gt;
&lt;li&gt;EBS : AWS 클라우드에서 사용할 수 있는 스토리지이다. 인스턴스 스토리지로 사용한다.&lt;/li&gt;
&lt;li&gt;보안 그룹 : 가상 방화벽으로, 1개 이상의 인스턴스 트래픽을 제한한다.&lt;/li&gt;
&lt;li&gt;Elastic IP : 정적(고정) IPv4 주소이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- EC2의 사용 절차 : 관리 콘솔 로그인 &amp;gt; EC2 인스턴스 생성 &amp;gt; EC2 접속 &amp;gt; 소프트웨어 설치/설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인스턴스 설정 항목&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AMI&lt;/li&gt;
&lt;li&gt;인스턴스 유형 : EC2 인스턴스의 장비 사양이다.&lt;/li&gt;
&lt;li&gt;리전 : 서버를 설치할 지역이다.&lt;/li&gt;
&lt;li&gt;네트워크 : EC2 인스턴스를 배치할 네트워크이다. AWS의 VPC에서 선택한다. VPC가 없으면 새로 생성하거나 기본 VPC를 사용한다.&lt;/li&gt;
&lt;li&gt;서브넷 : 설치할 네트워크의 범위이다. VPC 내에 어떤 서브넷을 설치할지 선택한다.&lt;/li&gt;
&lt;li&gt;IAM 역할 : 인스턴스의 접속 권한 정책을 설정한다.&lt;/li&gt;
&lt;li&gt;스토리지의 용량과 종류 : 서버 장비의 스토리지이다. OS가 설치된 장소에 있다. 기본적으로 EBS를 선택하고 사용할 디스크 용량과 스토리지의 종류를 선택한다.&lt;/li&gt;
&lt;li&gt;태그(EC2 인스턴스의 레이블) : 인스턴스에 임의의 태그를 부여할 수 있다. Name 태그를 사용하여 인스턴스 이름에 부여할 수 있으므로 사용하면 편리하다.&lt;/li&gt;
&lt;li&gt;보안 그룹 : 프로토콜별로 포트 혹은 IP 주소, 아니면 양쪽 모두 필터링을 설정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.3 인스턴스 생성과 요금: 가상 서버 생성 예시&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인스턴스의 이용 요금은 다음 4가지 항목의 비용을 합한 것이다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;비용 항목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;인스턴스 사용량 (가동 시간 X 단가)&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;인스턴스가&amp;nbsp;가동&amp;nbsp;시간(초)&amp;nbsp;단위로&amp;nbsp;과금된다.&amp;nbsp;정지하고&amp;nbsp;있는&amp;nbsp;동안은&amp;nbsp;과금되지&amp;nbsp;않는다.&amp;nbsp;원래&amp;nbsp;과금은&amp;nbsp;한&amp;nbsp;시간&amp;nbsp;단위였는데&amp;nbsp;2017년&amp;nbsp;9월부터&amp;nbsp;초&amp;nbsp;단위&amp;nbsp;과금으로&amp;nbsp;바뀌었다.&amp;nbsp;단위는&amp;nbsp;인스턴스&amp;nbsp;유형에&amp;nbsp;따라&amp;nbsp;다르고&amp;nbsp;고기능을&amp;nbsp;사용할&amp;nbsp;경우&amp;nbsp;비싸진다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 100px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 100px;&quot;&gt;EBS(스토리지) 요금 (용량 X 단가)&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 100px;&quot;&gt;인스턴스가&amp;nbsp;사용하는&amp;nbsp;EBS&amp;nbsp;요금이다.&amp;nbsp;보유한&amp;nbsp;용량&amp;nbsp;단위로&amp;nbsp;과금되며&amp;nbsp;스토리지&amp;nbsp;성능(SSD인지,&amp;nbsp;HDD인지,&amp;nbsp;IOPS&amp;nbsp;담보를&amp;nbsp;할지&amp;nbsp;여부&amp;nbsp;등)에&amp;nbsp;따라&amp;nbsp;단가가&amp;nbsp;달라진다.&amp;nbsp;보유한&amp;nbsp;용량&amp;nbsp;단위이며&amp;nbsp;저장&amp;nbsp;용량&amp;nbsp;단위가&amp;nbsp;아니므로&amp;nbsp;주의하자.&amp;nbsp;인스턴스와는&amp;nbsp;달리&amp;nbsp;정지하고&amp;nbsp;있는&amp;nbsp;동안에도&amp;nbsp;요금이&amp;nbsp;부과된다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 80px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 80px;&quot;&gt;통신 요금 (아웃바운드 통신 요금)&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 80px;&quot;&gt;인스턴스의&amp;nbsp;통신&amp;nbsp;요금이다.&amp;nbsp;인터넷에서&amp;nbsp;인스턴스로&amp;nbsp;들어오는(인바운드)&amp;nbsp;통신료는&amp;nbsp;무료이며&amp;nbsp;인스턴스에서&amp;nbsp;인터넷으로&amp;nbsp;나가는&amp;nbsp;통신(아웃바운드)만&amp;nbsp;요금이&amp;nbsp;부과된다.&amp;nbsp;요금은&amp;nbsp;리전에&amp;nbsp;따라서&amp;nbsp;조금&amp;nbsp;다르다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 40px;&quot;&gt;그 외 옵션&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 40px;&quot;&gt;Elastic&amp;nbsp;IP&amp;nbsp;서비스&amp;nbsp;등&amp;nbsp;옵션을&amp;nbsp;사용할&amp;nbsp;경우&amp;nbsp;해당&amp;nbsp;요금이&amp;nbsp;추가된다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.4 AMI: OS 및 소프트웨어가 설치된 디스크 이미지&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AMI(Amazon Machine Image)는 OS와 소프트웨어의 구성을 기록한 템플릿이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AMI를 사용하면 동일한 서버를 얼마든지 생성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AMI는 AWS 공식 AMI만 있는 것이 아니라 OS나 소프트웨어의 커뮤니티판, 기업이 생성한 AMI도 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AMI는 경우에 따라서 무료와 유료가 있다. 예를 들어 윈도 서버와 같이 원래 유료인 소프트웨어는 AMI에서도 유료이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AMI를 개인이 만들어서 마켓플레이스에 배포할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.5 인스턴스 유형: 용도에 맞게 머신을 선택하자&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인스턴스 유형이란 머신의 성능이며 용도에 따라 선택할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인스턴스에는 유형과 크기가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 표기 예시 : t2.micro (t2=인스턴스 유형, micro=인스턴스 크기)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 주요 인스턴스 유형&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 220px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.9147%; height: 20px;&quot;&gt;&lt;b&gt;용도&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 32.7519%; height: 20px;&quot;&gt;&lt;b&gt;인스턴스 유형&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;내용&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 60px;&quot;&gt;
&lt;td style=&quot;width: 33.9147%; height: 60px;&quot;&gt;범용&lt;/td&gt;
&lt;td style=&quot;width: 32.7519%; height: 60px;&quot;&gt;T2, T3, T5, M4 등&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 60px;&quot;&gt;일반적인 서버이다. 부하가 일정한 서버의 경우 사용하며, 버스트 기능을 지원하는 유형도 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.9147%; height: 20px;&quot;&gt;컴퓨팅 최적화&lt;/td&gt;
&lt;td style=&quot;width: 32.7519%; height: 20px;&quot;&gt;C5, C4 등&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;연산 능력이 높은 서버이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.9147%; height: 40px;&quot; rowspan=&quot;2&quot;&gt;메모리 최적화&lt;/td&gt;
&lt;td style=&quot;width: 32.7519%; height: 20px;&quot;&gt;X1e, X1 등&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;메모레 액세스 속도를 높인 서버이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 32.7519%; height: 20px;&quot;&gt;R4&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;대용량 메모리를 탑재한 서버이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 33.9147%; height: 40px;&quot;&gt;가속화된 컴퓨팅 최적화&lt;/td&gt;
&lt;td style=&quot;width: 32.7519%; height: 40px;&quot;&gt;P3, P2, G3, F1&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;머신 러닝 등에 사용되는 GPU를 탑재한 유형 및 그래픽 기능이 높은 유형이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 33.9147%; height: 40px;&quot;&gt;스토리지 최적화&lt;/td&gt;
&lt;td style=&quot;width: 32.7519%; height: 40px;&quot;&gt;H1, I3, D2 등&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;스토리지를 최적화한 유형이다. I3는 SSD 기반이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;730&quot; height=&quot;420&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;563&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cngcME/btrgGrO1zcI/OiKyDeusZKMlu9tyfRTKPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cngcME/btrgGrO1zcI/OiKyDeusZKMlu9tyfRTKPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cngcME/btrgGrO1zcI/OiKyDeusZKMlu9tyfRTKPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcngcME%2FbtrgGrO1zcI%2FOiKyDeusZKMlu9tyfRTKPK%2Fimg.png&quot; width=&quot;730&quot; height=&quot;420&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;563&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.6 Amazon EBS: Amazon EC2의 스토리지 볼륨&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Amazon EBS(Amazon Elastic Block Store)는 영구적인 블록 스토리지 볼륨으로 EC2와 조합하여 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- EBS는 HDD와 SSD를 선택할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- EBS에는 여러 가지 편리한 기능이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;탄력적 볼륨 : 볼륨 크기를 간단히 조정할 수 있는 기능이다.&lt;/li&gt;
&lt;li&gt;스냅샷 : 어떤 시점의 데이터를 통쨰로 저장하는 기능이다.&lt;/li&gt;
&lt;li&gt;데이터 라이프 사이클 매니저 : 일정에 따라서 스냅샷을 생성, 삭제하는 기능이다.&lt;/li&gt;
&lt;li&gt;최적화 인스턴스 : 특정 인스턴스 유형을 최적화 인스턴스로써 읽기 쓰기를 고속화하는 기능이다.&lt;/li&gt;
&lt;li&gt;암호화 : 데이터 볼륨, 부팅 볼륨 및 스냅샷을 암호화하는 기능이다. KMS를 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요약&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스명 : Amazon EBS&lt;/li&gt;
&lt;li&gt;사용빈도 : ★★★★&lt;/li&gt;
&lt;li&gt;요금 : 저장한 용량 X 시간&lt;/li&gt;
&lt;li&gt;매니지드 서비스 : X&lt;/li&gt;
&lt;li&gt;서울 리전 : O&lt;/li&gt;
&lt;li&gt;VPC : O&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.7 SSH를 사용한 접속과 키 페어: 공개키 암호 방식을 이용한 접근 관리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SSH는 서버에 설치된 소프트웨어를 조작할 때 사용하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 키 페어는 SSH 접속에 관한 접근 관리를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.8 Elastic IP 주소: 고정 공인 IP 주소를 부여&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Elastic IP 주소는 AWS가 제공하는 정적인 공인(public) IPv4 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- EC2 인스턴스는 정지 후 다시 시작하면 공인 IP 주소가 바뀌게 된다. 그래서 고정 IP 주소를 인스턴스와 연결하기 위해 사용되는 것이 Elastic IP 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Elastic IP 주소는 AWS 계정에 연결되어 있다. 인스턴스를 삭제해도 확보한 IP 주소는 그대로 AWS 계정에서 소유한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 소유한 IP가 중지된 인스턴스나 분리된 네트워크에 연결된 경우에도 시간당 요금이 부과된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요약&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스명 : Elastic IP&lt;/li&gt;
&lt;li&gt;사용빈도 : ★★★&lt;/li&gt;
&lt;li&gt;요금 : 추가 주소 + 미사용 주소 + 주소 매핑&lt;/li&gt;
&lt;li&gt;매니지드 서비스 : X&lt;/li&gt;
&lt;li&gt;서울 리전 : O&lt;/li&gt;
&lt;li&gt;VPC : O&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.9 Elastic Load Balancing: 트래픽을 분배하는 분산 장치&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ELB는 AWS가 제공하는 로드 밸런서이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 로드 밸런서는 서버 한 대에 집중되는 부하를 분산시키기 때문에 부하 분산 장치라고도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ELB의 종류&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ALB(Application Load Balancer) : HTTP 및 HTTPS에 가장 적합한 로드 밸런서이다. (HTTP, HTTPS)&lt;/li&gt;
&lt;li&gt;NLB(Network Load Balancer) : OSI 모형의 전송 계층에서 동작한다. (TCP, TLS)&lt;/li&gt;
&lt;li&gt;CLB(Classic Load Balancer) : 오래된 유형의 로드 밸런서이다. 앞으로 구축할 시스템에는 사용하지 않는 것을 권장한다. (TCP, SSL/TLS, HTTP, HTTPS)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ELB의 요금 : 사용 요금 + LCU 요금&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용 요금(사용 단가 X 시간) : 사용 요금은 ELB의 종류별로 단가가 결정되면 여기에 시간을 곱한 금액이다.&lt;/li&gt;
&lt;li&gt;LCU 요금(LCU 사용량 X LCU 단가 X 시간) : 측정 항목 4가지에 대해서 LCU 사용량이 가장 큰 항목만 과금 대상으로 한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;새 연결 수 : 1LCU = 초당 25개의 새로운 연결&lt;/li&gt;
&lt;li&gt;활성 연결 수 : 1LCU = 분당 3,000개의 활성 연결&lt;/li&gt;
&lt;li&gt;처리된 바이트 : 1LCU = 시간당 1GB&lt;/li&gt;
&lt;li&gt;규칙 평가 : 1LCU = 초당 1,000개의 규칙 평가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 단, CLB의 경우는 요금 계산이 간단하다. (사용 단가 X 시간 + 처리 단가 X 처리량)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요약&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스명 : Amazon ELB&lt;/li&gt;
&lt;li&gt;사용빈도 : ★★★&lt;/li&gt;
&lt;li&gt;요금 : 사용 요금 + LCU 요금&lt;/li&gt;
&lt;li&gt;매니지드 서비스 : X&lt;/li&gt;
&lt;li&gt;서울 리전 : O&lt;/li&gt;
&lt;li&gt;VPC : O&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.10 스냅샷: 서버 데이터 백업&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스냅샷은 특정 시점의 서버 디스크 상태를 보존하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AMI를 작성하고 싶을 떄도 스냅샷으로 작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스냅샷의 데이터 보존 장소는 Amazon S3이지만 스냅샷의 파일은 사용자가 자유롭게 다운로드할 수 없다. (S3 요금은 발생하지 않는다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요약&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스명 : 스냅샷&lt;/li&gt;
&lt;li&gt;사용빈도 : ★★★&lt;/li&gt;
&lt;li&gt;요금 : 스냅샷의 용량&lt;/li&gt;
&lt;li&gt;매니지드 서비스 : X&lt;/li&gt;
&lt;li&gt;서울 리전 : O&lt;/li&gt;
&lt;li&gt;VPC : O&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.11 오토 스케일링: 수요에 맞춰 EC2 대수를 증감&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 오토 스케일링이란 서버의 액세스 상태에 따라 서버 대수를 조절하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 오토 스케일링을 시작하려면 'Auto Scaling 그룹'(인스턴스의 집합)을 생성하고 그룹에 인스턴스(서버)의 최소 대수와 최대 대수를 설정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인스턴스의 증감에는 3가지 방법이 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;EC2 인스턴스가 정지한 경우에 분리하고 새로운 EC2 인스턴스를 생성하는 방법&lt;/li&gt;
&lt;li&gt;일정에 맞춰 스케일링하는 방법&lt;/li&gt;
&lt;li&gt;CPU와 네트워크의 부하를 참고하여 특정 임계 값을 넘을 때 인스턴스 수를 자동적으로 증감하는 방법 (CloudWatch 모니터링 연계)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 오토 스케일링의 요금은 무료이다. 하지만 CloudWatch를 사용할 경우 모니터링에 관련된 요금이 부과된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요금&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스명 : Auto Scaling&lt;/li&gt;
&lt;li&gt;사용빈도 : ★★★&lt;/li&gt;
&lt;li&gt;요금 : 오토 스케일링 자체는 무료이다. 스케일 업에 의한 Amazon EC2나 Amazon CloudWatch 등의 서비스 증가분의 요금이 부과된다.&lt;/li&gt;
&lt;li&gt;매니지드 서비스 : X&lt;/li&gt;
&lt;li&gt;서울 리전 : O&lt;/li&gt;
&lt;li&gt;VPC : O&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발기타/그림으로 이해하는 AWS 구조와 기술</category>
      <category>ALB</category>
      <category>Ami</category>
      <category>Auto Scaling</category>
      <category>CLB</category>
      <category>CloudWatch</category>
      <category>EBS</category>
      <category>EC2</category>
      <category>elasticIP</category>
      <category>elb</category>
      <author>이재원님</author>
      <guid isPermaLink="true">https://slog2.tistory.com/34</guid>
      <comments>https://slog2.tistory.com/34#entry34comment</comments>
      <pubDate>Mon, 4 Oct 2021 23:41:16 +0900</pubDate>
    </item>
    <item>
      <title>그림으로 이해하는 AWS 구조와 기술 - 1, 2장 AWS/클라우드/네트워크 기초</title>
      <link>https://slog2.tistory.com/33</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1장 아마존 웹 서비스 기초 지식&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.1 아마존 웹 서비스란: 아마존이 제공하는 클라우드 서비스&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS에서 시스템 운영에 필요한 서비스 전체를 빌릴 수 있다. (소프트웨어까지 포함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS에는 다수의 서비스가 있으며, 조합하여 이용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요금은 종량제이므로 사용한 만큼 지불한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS는 기술을 잘 모르는 사람도 운영할 수 있는 구조를 갖추고 있어 전문가가 아니어도 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.2 AWS의 서비스: 165개 이상의 서비스 제공&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS에는 서비스가 165개 이상 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS는 목적에 따라 다양한 서비스를 제공한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 140px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style7&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;웹 서버를 구축하고 싶을 때&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;모바일 시스템을 구축하고 싶을 떄&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;서버(EC2)&lt;br /&gt;서버 OS(AMI)&lt;br /&gt;IP 주소(Elastic IP)&lt;br /&gt;스토리지(S3)&lt;br /&gt;도메인(Route 53)&lt;br /&gt;DB 서버(RDS)&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;애플리케이션 서버(EC2)&lt;br /&gt;DB 서버(RDS)&lt;br /&gt;통지 시스템(SNS)&lt;br /&gt;스토리지(S3)&lt;br /&gt;IP 주소(Elastic IP)&lt;br /&gt;인증 서버(Cognito)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;콘텐츠를&amp;nbsp;배포하고&amp;nbsp;싶을&amp;nbsp;때&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;IoT를&amp;nbsp;구축하고&amp;nbsp;싶을&amp;nbsp;때&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 80px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 80px;&quot;&gt;&lt;span style=&quot;background-color: #f5f7f5;&quot;&gt;서버(EC2)&lt;br /&gt;&lt;/span&gt;캐시 서버(CloudFront)&lt;br /&gt;IP 주소(Elastic IP)&lt;br /&gt;도메인(Route 53)&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 80px;&quot;&gt;API 서버(IoT Core)&lt;br /&gt;DB 서버(DynamoDB/RDS)&lt;br /&gt;분석 도구(ElasticSearch)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;b&gt;머신 러닝을 개발하고 싶을 때&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;b&gt;로봇을 만들고 싶을 때&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;머신 러닝 모델(Machine Learning, SageMaker)&lt;br /&gt;이미지 동영상 인식(Rekognition)&lt;br /&gt;음성 인식(Transcribe, Lex)&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;로봇 프레임워크(RoboMaker)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 중에서도 특히 대표적인 서비스 몇가지&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 200px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style7&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;&lt;b&gt;Amazon EC2&lt;/b&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;Amazon S3&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;Amazon Elastic Compute Cloud는 컴퓨팅 용량을 제공하는 서비스이다.&lt;br /&gt;한마디로 말하면 서버, OS, 소프트웨어 등을 세트로 사용할 수 있다. 다양한 사양이 준비되어 있고 자유롭게 소프트웨어를 설치하고 시스템을 구축할 수 있으며 이미 세팅된 서버를 사용하는 것도 가능하다.&lt;br /&gt;성능은 가변적이며 일시 정지 중에는 언제든 성능을 높이거나 낮출 수 있다.&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;Amazon Simple Storage Service는 오브젝트 스토리지 서비스이다. 웹 서버 및 파일 서버용 파일을 보관하는 장소(스토리지)로 사용할 수 있다.&lt;br /&gt;S3는 강력하고 다양한 기능이 있어 장애 및 에러에 강할 뿐만 아니라 강력한 관리 기능이나 다른 서비스와 연동하는 기능도 갖추고 있다.&lt;br /&gt;파일 크기는 최대 5TB이며, 전체 용량의 제한은 없다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;Amazon VPN&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;Amazon RDS&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;Amazon VPN은 AWS 계정 전용의 가상 네트워크이다. 네트워크 및 서브넷의 범위, 라우팅 테이블 및 네트워크 게이트웨이 등을 설정하고, 가상 네트워크 환경을 구성한다.&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;Amazon RDS는 관계형 데이터베이스의 대표라고 할 수 있는 6종류(Amazon Aurora, PostgreSQL, MySQL, MariaDB, Oracle Database, SQL Server)를 클라우드에서 이용할 수 있는 서비스이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;Amazon Route 53&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;Elastic IP 주소&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;Amazon Route 53는 DNS(도메인 네입 서버)이다. 웹 서버에 필수인 DNS 기능을 제공한다.&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;Elastic IP 주소는 서버에 필수인 정적 공인 IP 주소를 제공한다. EC2 및 ELB와 조합하여 사용한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;Amazon Managed Blockchain&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;Amazon SageMaker&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;Amazon Managed Blockchain은 블록체인 네트워크를 생성, 관리할 수 있는 도구이다. 데이터 위조 및 변조를 확인하는 기반으로 이용할 수 있다.&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;Amazon SageMaker는 머신 러닝 모델을 구축, 트레이닝, 배포할 수 있다. 머신 러닝에서 자주 사용되는 주피터 노트북(Jupyter Notebook)을 클라우드로 제공한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;AWS Cloud9&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;b&gt;Amazon GameLift&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;AWS Cloud9은 웹 브라우저로 조작이 가능한 통합 개발 도구이다. 각종 언어에 대응하고 컴퓨터에 개발 도구를 설치하지 않고 시스템을 개발할 수 있다.&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&amp;nbsp;Amazon GameLift는 게임 호스팅 서비스이다. 멀티플레이어 대전 등 실시간 데이터 통신을 짧은 대기 시간으로 제공한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.3 AWS의 비용: 초기 비용은 저렴하지만 운영 비용이 조금 비싸다&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS 요금은 사용한 만큼 지불하는 종량제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 경우에 따라서는 자사에서 준비하는 것이 저렴할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 돌발적으로 접속 수가 늘어나는 경우에는 AWS를 사용하는 게 더 이득이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.4 AWS의 사용 방법: 누구라도 쉽게 서비스를 이용할 수 있다&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 관리 콘솔로 AWS를 웹 브라우저에서 운영할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 매니지드 서비스로 각 서비스를 자동으로 관리할 수 있기 때문에 보안적으로도 안심할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.5 AWS의 도입 사례: 대기업이나 정부기관에서 도입하는 경우도 다수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 국내도 많은 기업이 AWS를 도입하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS를 어떻게 도입해야 할지 잘 검토하는 것이 중요하다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2장 AWS를 이해가기 위한 클라우드 &amp;amp; 네트워크의 구조&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.1 클라우드와 온프레미스: 클라우드 컴퓨팅의 구조&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 클라우드란 인터넷으로 접속할 수 있는 환경이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS, 마이크로소프트 애저(Azure), 구글 클라우드 플랫폼(Google Cloud Platform)은 클라우드 컴퓨팅을 제공하는 서비스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 클라우드 컴퓨팅은 가상화 기술을 사용하여 언제 어디서든 마음대로 서버나 인프라를 구축하여 운영할 수 있도록 구축되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 온프레미스(on-premises)란 자사에서 서버 등을 구축하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 온프레미스는 자사에서 자유롭게 설계, 운영할 수 있지만 그만큼 서버 구성을 빈번하게 변경해야 할 수도 있고, 이를 대비한 숙련된 기술자도 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2 가상화와 분산 처리: 클라우드를 지탱하는 2대 기술&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 가상화와 분산 처리는 클라우드를 지탱하는 큰 기술이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 가상화는 소프트웨어처럼 구축하는 기술이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 서버를 예로 들어 가상 서버는 물리 서버 1대 위에 게스트가 되는 서벌 여러 대를 가상으로 생성한다. 본래 서버에 필요한 물리적인 부품을 가상으로 생성하여 가상 서버로 만드는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 가상화는 소프트웨어처럼 구축하기 때문에 서버 복제가 쉽고 대수를 늘리거나 줄이기도 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 분산 처리는 서버 여러 대에 분산하여 처리하는 기술이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 가상화나 분산 처리는 이중화에도 사용된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;348&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9Pizs/btrgHE7VKya/7TOywNvvKyp7yVM3y7P4Zk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9Pizs/btrgHE7VKya/7TOywNvvKyp7yVM3y7P4Zk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9Pizs/btrgHE7VKya/7TOywNvvKyp7yVM3y7P4Zk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9Pizs%2FbtrgHE7VKya%2F7TOywNvvKyp7yVM3y7P4Zk%2Fimg.jpg&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;348&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.3 SasS, PaaS, IaaS&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어느 수준까지 서비스가 제공되는지에 따라서 클라우드 서비스는 SaaS, PaaS, IaaS 3가지로 구분된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SaaS는 애플리케이션까지 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- PaaS는 플랫폼까지 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- IaaS는 인프라만 제공한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;450&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhpxcJ/btrgB2vh5lD/SeMagnSiaFQEtaVWce3ghk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhpxcJ/btrgB2vh5lD/SeMagnSiaFQEtaVWce3ghk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhpxcJ/btrgB2vh5lD/SeMagnSiaFQEtaVWce3ghk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhpxcJ%2FbtrgB2vh5lD%2FSeMagnSiaFQEtaVWce3ghk%2Fimg.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;450&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3가지 서비스는 각각의 특징이 있다. 인프라나 애플리케이션이 제공되는 것이 편리한 반면 자유도가 낮아진다. 반대로 자유도가 높을수록 작업이 어렵다. 이러한 특징을 잘 이해하고 선택하자.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style5&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;SaaS (편리하다)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;PaaS&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;IaaS (자유도가 높다)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;- 편리한 반면 자유도가 낮다.&lt;br /&gt;- 바로 사용할 수 있기 때문에 작업량이 적다.&lt;br /&gt;- 특별한 지식이 필요 없다.&lt;br /&gt;- 단말기 외에 준비할 것이 없다.&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;- 애플리케이션을 마음대로설치 할 수 있지만 대응하지 않는 애플리케이션도 있다.&lt;br /&gt;- 서버 관리에 대한 지식이 필요하다.&lt;br /&gt;- 경우에 따라서는 애플리케이션을 준비해야 할 필요가 있다.&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;- 사용하려면 세팅이 필요하다.&lt;br /&gt;- 서버 관리에 대한 지식이 필요하다.&lt;br /&gt;- 경우에 따라서는 애플리케이션을 준비해야 할 필요가 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.4 서버와 인스턴스: 네트워크상에 만들어진 가상 서버&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서버란 어떠한 서비스를 제공하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 제공하는 서비스의 종류에 따라서 서버 이름이 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서버는 머신 1대에 여러 개를 같이 설치할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서버에도 OS는 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS에서는 서버가 인스턴스로 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.5 LAN: LAN을 구성하는 기술&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- PC 등을 연결한 네트워크를 LAN이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- LAN에는 유선과 무선이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 폐쇄된 네트워크를 인트라넷이라 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.6 IP 주소와 DNS: 네트워크의 장소를 특정하는 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- IP 주소는 인터넷에서 호스트를 식별하는 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사설 IP 주소와 공인 IP 주소가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 공인 IP 주소는 인터넷에서 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사설 IP 주소는 사내 LAN 이나 가정 LAN에서 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- DNS에서 도메인명과 IP 주소는 연결되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.7 웹의 구조: 웹 사이트와 관련된 기술&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 웹 사이트의 콘텐츠는 HTML 이라는 형식으로 작성되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 웹 사이트의 파일이 저장되어 있는 곳이 웹 서버이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대표적인 웹 서버용 소프트웨어는 Apache, Nginx가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SSH란 서버를 설정할 때 접속하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SSL 증명서를 설치하면 통신을 암호활 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- PHP나 자바스크립트는 프로그래밍 언어의 한 종류이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 웹 사이트에 대한 공격에는 주의가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발기타/그림으로 이해하는 AWS 구조와 기술</category>
      <category>Amazon</category>
      <category>AWS</category>
      <category>cloud</category>
      <category>IaaS</category>
      <category>PaaS</category>
      <category>SaaS</category>
      <author>이재원님</author>
      <guid isPermaLink="true">https://slog2.tistory.com/33</guid>
      <comments>https://slog2.tistory.com/33#entry33comment</comments>
      <pubDate>Sun, 3 Oct 2021 12:14:59 +0900</pubDate>
    </item>
    <item>
      <title>비전공자를 위한 이해할 수 있는 IT 지식</title>
      <link>https://slog2.tistory.com/32</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;책 내용 요약 - 신입 개발자에게도 추천하고 싶은 책, 실무에 유용한 내용, 적절한 비유를 통한 개념 설명&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본적으로 클라/서버, 프론트/백, API/JSON/SDK 와 같은 기본적인 개념을 알아야 개발자의 대화를 이해할 수 있다.&lt;/li&gt;
&lt;li&gt;API 문서가 제일 중요하다. 이걸 볼 수 있어야 개발자와 협업이 가능하다. (문서 작성 서비스는 gitbook 추천)&lt;/li&gt;
&lt;li&gt;앱 출시를 하려면 마켓과 심사가 무엇인지, 웹/앱이 무엇인지, 앱의 종류에는 무엇이 있는지는 알아야 한다.&lt;/li&gt;
&lt;li&gt;기존에 모든 산업들은 IT 산업으로 대체되고 있다. 어떤 일을 하든 IT 지식을 알아두는게 유용하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;클라이언트와 서버&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;식당 고객 = 클라이언트 = 무언가를 달라고 하는 컴퓨터, 스마트폰 (서비스를 사용하는 사용자의 컴퓨터)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;종업원 = 서버 = 무언가를 주는 24시간 동작하는 컴퓨터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 클라이언트는 서버에게 계속 무언가(파일)를 달라고 한다. '일을 맡긴 사람'을 뜻한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 개발자의 세상에서 클라이언트는 대부분 컴퓨터이다. 즉, 서비스를 사용하는 사용자들이 소유한 컴퓨터, 스마트폰이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고객의 바로 앞에 있는 이 컴퓨터를 다른 말로 '프론트 엔드'라고 표현한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면, 서버는 고객이 볼 수 없는 곳(뒤)에 있다. 그래서 서버를 다른 말로 '백 엔드' 라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- '클라이언트', '클라', '프론트 엔드', '프론트' 모두 같은 말로 고객의 컴퓨터를 뜻 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- '서버', '백 엔드', '백' 이 또한 모두 주는 컴퓨터라는 뜻으로 쓰임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;API 와 JSON&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- API : 소프트웨어가 다른 소프트웨어를 쓰기 위한 체계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- JSON : 클라이언트가 서버 API 를 요청하고 응답을 주고받을 때 사용하는 데이터 형식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SDK(Software Development Kit) : API를 제공해주는 다른 소프트웨어(도구)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- API 문서를 볼 수 있어야 개발자와 커뮤니케이션이 가능함. API 문서 작성 서비스는 GItBook 을 추천&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;어플리케이션과 웹&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 136px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;어플리케이션(앱)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;웹&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;사용자 설치 방법&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;서버에서 설치 파일을 받아서 설치&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;설치 필요 없음 (브라우저만 필요)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;사용자 업데이트 방법&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;1) 새로 코딩한 앱을 마켓 업로드 (심사 필요)&lt;br /&gt;2) 사용자들이 각각 버전 업데이트&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;원본 파일을 수정된 파일로 서버에서 교체&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;인터넷 필요 여부&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;필요 없거나 부분적으로 필요&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;필수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 60px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 60px;&quot;&gt;동작하는 환경&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 60px;&quot;&gt;운영체제 (OS)&lt;br /&gt;- PC : 윈도우, macOS, 리눅스&lt;br /&gt;- 모바일 : 안드로이드, iOS&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 60px;&quot;&gt;브라우저&lt;br /&gt;- IE, 크롬, 파이어폭스, 사파리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;반응협웹 : 모바일 크기에 맞는 웹 페이지를 따로 만드는 불편함을 해결하기 위해 등장한 기술로 브라우저의 가로 넓이에 '반응'하여 화면 구성 요소가 변하는 기술 (CSS, bootstrap)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션의 종류&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 네이티브 애플리케이션 : 운영체제가 원래 정해놓은 언어들을 사용해 개발 된 애플리케이션 (카카오톡)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 모바일 웹 앱 : 애플리케이션의 특정 부분에 '브라우저'를 올리는 방식으로 실제 웹을 보여줌 (은행앱)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 하이브리드 애플리케이션 : 네이티브와 브라우저가 혼합된 애플리케이션 (네이버)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;데이터베이스와 이미지 처리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데이터란 쇼핑몰의 회원명, 아이디, 상품명, 가격 등을 의미함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데이터가 조금 망가지는게 무슨 문제가 될까? 1,000,000명 중 한명의 돈이 없어지는 은행은 존재할 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이런 속성을 데이터의 '무결성' 이라고 하며 데이터는 1%의 결점도 없어야 하기 때문에 데이터를 다루는 건 까다롭고 어려운 일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 그래서 등장한게 관계형 데이터베이스 관리 시스템(RDBMS)으로 가장 많이 사용됨 (MS SQL, Oracle DB, MySql 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지는 클라가 들고 있다?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 클라이언트도 자체적인 데이터베이스를 가지고 있어 데이터를 저장할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이미지를 교체하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 앱 로컬에 있는 이미지 : 이미지가 변경된 앱을 마켓에 업로드 (그 데이터는 로컬/내부 DB/네이티브에 있어요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 서버에서 실시간으로 받아오는 이미지 : 서버의 이미지를 교체&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이런 구분은 API 문서를 보면 알 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;프레임워크와 라이브러리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프레임워크는 던킨도너츠이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 도넛 가게를 직접 창업하는 것보다 프렌차이즈로 들어가는 것이 훨씬 빠름&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 도넛은 물론 포스 단말기, 디자인, 브랜드, 가구 등을 모두 제공받을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 즉, 프레임워크를 사용하면 프로젝트를 쉽고 빠르게 개발할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 애플은 앱스토어에 좋은 앱들이 올라오길 바라기 때문에 프레임워크를 제공함 (좋은 앱들이 많으면 이를 사용하기 위해 아이폰을 구매할테니)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프레임워크와 라이브러리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다른 사람들이 만들어놓은 코드를 이용한다는 측면에서 프레임워크와 같음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 프레임워크가 더 큰 개념으로 각종 라이브러리와 코드들이 모여 프레임워크가 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 한 프로젝트에서 프레임워크는 하나만 쓸 수 있음 (한 자동차를 운전하면서 동시에 다른 자동차를 운전할 수 없는 것과 같음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 라이브러리는 더 작은 개념으로 망치나 가위 같은 도구들이기 때문에 한 프로젝트에서 함께 사용이 가능함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;아웃트로 (어디서 일을 해도 IT 지식은 필요합니다)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유선전화는 휴대폰으로 시작해서 컬러폰에서 스마트폰까지 등장했고 카메라 화소가 좋아지더니 디지털 카메라, 심지어 캠코더 시장까지 잠식하기 시작했습니다. 이후 게임기, 계산기, 알람시계 등 다양한 영역을 흡수해 나갑니다. 이제 스마트폰으로 못할 일이 없습니다. 이것이 20년만에 생긴 변화입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IT는 상어 같습니다. 다른 산업군을 가만히 두지 않습니다. 과거에 시계는 시계 회사들의 전유물이었습니다. 허나 이제는 삼성과 애플, 샤오미에서 시계가 나옵니다. 또한 택시 업계로 금융과 유통 업계로 계속 뻗어나가고 있습니다. 앞으로는 무슨 변화가 있을까요? 어떤 혁신이 있을까요? 누군가는 드론이라고 얘기하고, 누군가는 블록체인, 누군가는 AR이나 VR, 누군가는 AI 라고 얘기합니다. 어떤 기술일지는 모르지만 그 모든 기술은 기존 산업들을 가만히 두지 않을 것이라는 점은 분명합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;a href=&quot;http://www.yes24.com/Product/Goods/91165789&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://www.yes24.com/Product/Goods/91165789&lt;/a&gt;&lt;/span&gt;&lt;/blockquote&gt;</description>
      <category>개발기타</category>
      <category>IT지식</category>
      <category>비전공자</category>
      <category>비전공자를 위한 이해할 수 있는 IT 지식</category>
      <author>이재원님</author>
      <guid isPermaLink="true">https://slog2.tistory.com/32</guid>
      <comments>https://slog2.tistory.com/32#entry32comment</comments>
      <pubDate>Wed, 8 Sep 2021 23:45:37 +0900</pubDate>
    </item>
    <item>
      <title>[리팩터링 2판] 3장 코드에서 나는 악취</title>
      <link>https://slog2.tistory.com/31</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;리팩터링 적용 방법을 아는 것과 제때 적용할 줄 아는 것은 다르다. 리팩터링을 언제 시작하고 언제 그만할지를 판단하는 일은 리팩터링의 작동 원리를 아는 것 만큼 중요하다. 그리고 우리는 리팩터링이 필요한 코드들에 일정한 패턴이 있다는 사실을 발견했다. 이를 설명하는데 냄새(악취)란 표현을 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 리팩터링을 언제 멈춰야 하는지를 판단하는 정확한 기준을 제시하지 않을 것이다. &lt;u&gt;우리 경험에 따르면 숙련된 사람의 직관만큼 정확한 기준은 없다&lt;/u&gt;. 종료 기준보다는 리팩터링하면 해결할 수 있는 &lt;u&gt;문제의 징후를 제시&lt;/u&gt;하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.1 기이한 이름 (Mysterious Name)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 명료하게 표현하는데 가장 중요한 요소 하나는 바로 '이름'이다. 함수, 모듈, 변수, 클래스 등은 그 &lt;u&gt;이름만 보고도 각각이 무슨 일을 하고 어떻게 사용해야 하는지 명확히 알 수 있도록 엄청나게 신경 써서 이름을 지어야 한다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 아쉽게도 이름 짓기는 프로그래밍에서 가장 어렵기로 손꼽히는 두 가지 중 하나다. 그 때문에 우리가 가장 많이 사용하는 리팩터링도 이름을 바꾸는 리팩터링들이다. 이름만 잘 지어도 나중에 문맥을 파악하느라 헤매는 시간을 크게 절약할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;마땅한 이름이 떠오르지 않는다면 설계에 근본적인 문제가 숨어 있을 가능성이 높다.&lt;/u&gt; 그래서 혼란스러운 이름을 잘 정리하다 보면 코드가 훨씬 간결해질 때가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;함수 선언 바꾸기(6.5), 변수 이름 바꾸기(6.7), 필드 이름 바꾸기(9.2)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.2 중복 코드 (Duplicated Code)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;코드가 중복되면 각각을 볼 때마다 서로 차이점은 없는지 주의 깊게 살펴봐야 하는 부담이 생긴다. &lt;/u&gt;그중 하나를 변경할 때는 다른 비슷한 코드들도 모두 살펴보고 수정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 간단한 예로, 한 클래스에 딸린 두 메서드가 똑같은 표현식을 사용하는 경우가 함수 추출하기를 써서 양쪽 모두 추출된 메서드를 호출하게 바꾸면 된다. 코드가 비슷하긴 한데 완전히 똑같지 않다면, 먼저 문장 슬라이드하기로 비슷한 부분을 한곳에 모아 함수 추출하기를 더 쉽게 적용할 수 있는지 살펴본다. 같은 부모로부터 파생된 서브클래스들에 코드가 중복되어 있다면, 각자 따로 호출되지 않도록 메서드 올리기를 적용해 부모로 옮긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;함수 추출하기(6.1), 문장 슬라이드하기(8.6), 메서드 올리기(12.1)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.3 긴 함수 (Long Function)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3HBBI/btrd2xKGbDt/AaDl24RJG1HqlYrN0oth21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3HBBI/btrd2xKGbDt/AaDl24RJG1HqlYrN0oth21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3HBBI/btrd2xKGbDt/AaDl24RJG1HqlYrN0oth21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3HBBI%2Fbtrd2xKGbDt%2FAaDl24RJG1HqlYrN0oth21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;417&quot; height=&quot;250&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;코드를 이해하고, 공유하고, 선택하기 쉬워진다는 장점은 함수를 짧게 구성할 때 나오는 것이다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예전 언어는 서브루틴을 호출하는 비용이 컸기 때문에 짧은 함수를 꺼렸다. 하지만 요즘 언어는 프로세스 안에서의 함수 호출 비용을 거의 없애버렸다. 물론 코드를 읽는 사람 입장에서는 함수가 하는 일을 파악하기 위해 왔다 갔다 해야 하므로 여전히 부담이 된다. 다행히 함수 호출부와 선언부 사이를 빠르게 이동하거나 호출과 선언을 동시에 보여주는 개발 환경을 활용하면 이 부담이 줄어들지만, 짧은 함수로 구성된 코드를 이해하기 쉽게 만드는 가장 확실한 방법은 좋은 이름이다. &lt;u&gt;함수 이름을 잘 지어두면 본문 코드를 볼 이유가 사라진다. 그러기 위해서는 훨씬 적극적으로 함수를 쪼개야 한다.&lt;/u&gt;&lt;u&gt;&lt;/u&gt;&lt;u&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주석을 달아야 할 만한 부분은 무조건 함수로 만든다. 그 함수 본문에는 원래 주석으로 설명하려던 코드가 담기고 함수 이름은 동작 방식이 아닌 '의도'가 드러나게 짓는다. 이렇게 함수로 묶는 코드는 여러 줄일 수도 있고 단 한 줄일 수도 있다. 심지어 원래 코드보다 길어지더라도 함수로 뽑는다. 단, 함수 이름에 코드의 목적을 드러내야 한다. 여기서 핵심은 함수의 길이가 아닌, 함수의 목적(의도)과 구현 코드의 괴리가 얼마나 큰가다. 즉, '무엇을 하는지'를 코드가 잘 설명해주지 못할수록 함수로 만드는 게 유리하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 함수를 짧게 만드는 작업의 99%는 함수 추출하기가 차지한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;함수 추출하기(6.1), 임시 변수를 질의 함수로 바꾸기(7.4), 매개변수 객체 만들기(6.8), 객체 통째로 넘기기(11.4), 함수를 명령으로 바꾸기(11.9), 조건문 분해하기(10.1), 조건문을 다형성으로 바꾸기(10.4)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.4 긴 매개변수 목록 (Long Parameter List)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/03mHZ/btrd5CYY6Bp/rP25oXtyCVsff48QIV73uk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/03mHZ/btrd5CYY6Bp/rP25oXtyCVsff48QIV73uk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/03mHZ/btrd5CYY6Bp/rP25oXtyCVsff48QIV73uk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F03mHZ%2Fbtrd5CYY6Bp%2FrP25oXtyCVsff48QIV73uk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;465&quot; height=&quot;279&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 프로그래밍을 시작하던 시절에는 함수에 필요한 것들을 모조리 매개변수로 전달하라고 배웠다. 그래야 암적 존재인 전역 데이터가 늘어나는 사태를 막을 수 있기 때문에 그 시절에는 합리적인 방식이있다. 하지만 &lt;u&gt;매개변수 목록이 길어지면 그 자체로 이해하기 어려울 때가 많다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;매개변수를 질의 함수로 바꾸기(11.5), 객체 통째로 넘기기(11.4), 매개변수 객체 만들기(6.8), 플래그 인수 제거하기(11.3), 여러 함수를 클래스로 묶기(6.9)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.5 전역 데이터 (Global Data)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전역 데이터를 주의해야 한다는 말은 우리가 소프트웨어 개발을 시작한 초창기부터 귀가 따갑게 들었다. 이는 우리가 겪을 수 있는 악취 중 가장 지독한 축에 속한다. 전역 데이터는 코드베이스 어디에서든 건드릴 수 있고 값을 누가 바꿨는지 찾아낼 매커니즘이 없다는 게 문제다. 그래서 &lt;u&gt;버그는 끊임없이 발생하는데 그 원인이 되는 코드를 찾아내기가 굉장히 어렵다.&lt;/u&gt; 전역 데이터의 대표적인 형태는 전역 변수지만 클래스 변수와 싱글톤에서도 같은 문제가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;이를 방지하기 위해 우리가 사용하는 대표적인 리팩터링은 변수 캡슐화하기다&lt;/u&gt;. 다른 코드에서 오염시킬 가능성이 있는 데이터를 함수로 감싸는 것만으로도 데이터를 수정하는 부분을 쉽게 찾을 수 있고 접근을 통제할 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;변수 캡슐화하기(6.6)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.6 가변 데이터 (Mutable Data)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;데이터를 변경했더니 예상치 못한 결과나 골치 아픈 버그로 이어지는 경우가 종종 있다&lt;/u&gt;. 코드의 다른 곳에서는 다른 값을 기대한다는 사실을 인식하지 못한 채 수정해버리면 프로그램이 오작동한다. 특히 이 문제가 아주 드문 조건에서만 발생한다면 원인을 알아내기가 매우 어렵다. 이런 이유로 함수명 프로그래밍에서는 데이터는 절대 변하지 않고, 데이터를 변경하려면 반드시 복사본을 만들어서 반환한다는 개념을 기본으로 삼고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 함수형 언어가 프로그래밍에서 차지하는 비중은 여전히 적고 변수 값을 바꿀 수 있는 언어를 사용하는 프로그래머가 더 많다. 그렇다고 해서 불변성이 주는 장점을 포기할 필요는 없다. &lt;u&gt;무분별한 데이터 수정에 따른 위험을 줄이는 방법은 얼마든지 있다. (유효범위를 줄이고 가변성을 최소화 하는 방법)&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;변수 캡슐화하기(6.6), 변수 쪼개기(9.1), 문장 슬라이드하기(8.6), 함수 추출하기(6.1), 질의 함수와 변경 함수 분리하기(11.1), 세터 제거하기(11.7), 파생 변수를 질의 함수로 바꾸기(9.3), 여러 함수를 클래스로 묶기(6.9), 여러 함수를 변환 함수로 묶기(6.10), 참조를 값으로 바꾸기(9.4)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.7 뒤엉킨 변경 (Divergent Change)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pB3eO/btrdXxevoJA/CrkPDcW1MBzkT6vhAEzGpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pB3eO/btrdXxevoJA/CrkPDcW1MBzkT6vhAEzGpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pB3eO/btrdXxevoJA/CrkPDcW1MBzkT6vhAEzGpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpB3eO%2FbtrdXxevoJA%2FCrkPDcW1MBzkT6vhAEzGpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;410&quot; height=&quot;246&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 수정할 때는 시스템에서 고쳐야 할 딱 한 군데를 찾아서 그 부분만 수정할 수 있기를 바란다. 이렇게 할 수 없다면 뒤엉킨 변경과 산탄총 수술 중 하나가 풍긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뒤엉킨 변경은 단일 책임 원칙(SRP)이 제대로 지켜지지 않을때 나타난다. 즉, 하나의 모듈이 서로 다른 이유들로 인해 여러가지 방식으로 변경되는 일이 많을 때 발생한다. &lt;u&gt;서로 다른 맥락에서 이뤄지는 동작은 독립된 모듈로 분리해야 프로그래밍이 편하다&lt;/u&gt;. 그래야 무언가를 수정할 때 해당 맥락의 코드만 이해해도 진행할 수 있다. 나이를 먹어 두뇌 회전이 느려지는 요즘에는 더더욱 중요한 일이 돼버렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #252525;&quot;&gt;맥락에 맞게 단계를 분리한 후 클래스 추출을 통해 클래스의 동작을 분할한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;br /&gt;&lt;/b&gt;단계 쪼개기(6.11), 함수 옮기기(8.1), 함수 추출하기(6.1), 클래스 추출하기(7.5)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.8 산탄총 수술 (Shotgun Surgery)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7ZvsU/btrd0lkhvXq/oyIL1S1Qm61QQHTBvI9h9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7ZvsU/btrd0lkhvXq/oyIL1S1Qm61QQHTBvI9h9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7ZvsU/btrd0lkhvXq/oyIL1S1Qm61QQHTBvI9h9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7ZvsU%2Fbtrd0lkhvXq%2FoyIL1S1Qm61QQHTBvI9h9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;415&quot; height=&quot;249&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;산탄총 수술은 뒤엉킨 변경과 비슷하면서도 정반대다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 냄새는 코드를 변경할 때마다 자잘하게 수정해야 하는 클래스가 많을 때 풍긴다. &lt;u&gt;변경할 부분이 코드 전반에 퍼져 있다면 찾기도 어렵고 꼭 수정해야 할 곳을 지나치기 쉽다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴 때는 함께 변경되는 대상들을 모두 한 모듈에 묶어두면 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 66.3776%; height: 100px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;뒤엉킨 변경&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;산탄총 수술&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;원인&lt;/td&gt;
&lt;td style=&quot;width: 66.6666%; text-align: center; height: 20px;&quot; colspan=&quot;2&quot;&gt;맥락을 잘 구분하지 못함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;해법(원리)&lt;/td&gt;
&lt;td style=&quot;width: 66.6666%; text-align: center; height: 20px;&quot; colspan=&quot;2&quot;&gt;맥락을 명확히 구분&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;발생 과정(현상)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;한 코드에 섞여 들어감&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;여러 코드에 흩뿌려짐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;해법(실제 행동)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;맥락별로 분리&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;맥락별로 모음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;함수 옮기기(8.1), 필드 옮기기(8.2), 여러 함수를 클래스로 묶기(6.9), 여러 함수를 변환 함수를 묶기(6.10), 단계 쪼개기(6.11), 함수 인라인하기(6.2), 클래스 인라인하기(7.6)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.9 기능 편애 (Feature Envy)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSCoN9/btrd5kRA8T7/kUxeuWJwbpzpO8HvMtYHuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSCoN9/btrd5kRA8T7/kUxeuWJwbpzpO8HvMtYHuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSCoN9/btrd5kRA8T7/kUxeuWJwbpzpO8HvMtYHuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSCoN9%2Fbtrd5kRA8T7%2FkUxeuWJwbpzpO8HvMtYHuk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;436&quot; height=&quot;262&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램을 모듈화할 때는 코드를 여러 영역으로 나눈 뒤 영역 안에서 이뤄지는 상호작용은 최대한 늘리고 영역 사이에서 이뤄지는 상호작용은 최소로 줄이는 데 주력한다. 기능 편애는 흔히 어떤 함수가 자기가 속한 모듈의 함수나 데이터보다 다른 모듈의 함수나 데이터와 상호작용할 일이 더 많을 때 풍기는 냄새다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다행히 해결하기는 쉽다. 이 함수가 데이터와 가까이 있고 싶어 한다는 의중이 뚜렷이 드러나므로 &lt;u&gt;소원대로 데이터 근처로 옮겨주면 된다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;함수 옮기기(8.1), 함수 추출하기(6.1), 함수 옮기기(8.1)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.10 데이터 뭉치 (Data Clumps)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AY7dV/btrd05akfCp/VBj8iaKD6BStdMh2bH71dK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AY7dV/btrd05akfCp/VBj8iaKD6BStdMh2bH71dK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AY7dV/btrd05akfCp/VBj8iaKD6BStdMh2bH71dK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAY7dV%2Fbtrd05akfCp%2FVBj8iaKD6BStdMh2bH71dK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;465&quot; height=&quot;279&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 항목들은 어린아이 같은 면이 있다. 서로 어울려 노는 걸 좋아한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 데이터 항목들이 여러 곳에서 항상 함께 뭉쳐 다니는 모습을 흔히 목격할 수 있다. 클래스 두어 개의 필드에서, 혹은 여러 메서드의 시그니처에서 함께 발견되기도 한다. 이렇게 &lt;u&gt;몰려다니는 데이터 뭉치는 보금자리를 따로 마련해줘야 마땅하다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;클래스 추출하기(7.5), 매개변수 객체 만들기(6.8), 객체 통째로 넘기기(11.4)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.11 기본형 집착 (Primitive Obsession)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래머 중에는 자신에게 주어진 문제에 딱 맞는 기초 타입을 직접 정의하기를 몹시 꺼리는 사람이 많다. 그래서 금액을 그냥 숫자형으로 계산하거나, 물리량을 계산할때도 밀리미터나 인치 같은 단위를 무시하고, 범위도 if (a &amp;lt; upper &amp;amp;&amp;amp; a &amp;gt; lower) 처럼 처리하는 코드를 수없이 봤다. 이 냄새는 문자열을 다루는 코드에서 특히 흔하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;기본형을 객체로 바꾸기(7.3), 타입 코드를 서브클래스를 바꾸기(12.6), 조건부 로직을 다형성으로 바꾸기(10.4), 클래스 추출하기(7.5), 매개변수 객체 만들기(6.8)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.12 반복되는 switch문 (Repeated Switches)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AuqvR/btrd3bm7XJJ/NCEoHo2k9EaPbEEMOhyjs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AuqvR/btrd3bm7XJJ/NCEoHo2k9EaPbEEMOhyjs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AuqvR/btrd3bm7XJJ/NCEoHo2k9EaPbEEMOhyjs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAuqvR%2Fbtrd3bm7XJJ%2FNCEoHo2k9EaPbEEMOhyjs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;473&quot; height=&quot;284&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중복된 switch문이 문제가 되는 이유는 조건절을 하나 추가할 때마다 다른 switch문들도 모두 찾아서 함께 수정해야 하기 때문이다. 이럴 때 다형성은 반복된 switch 문이 내뿜는 사악한 기운을 제압하여 코드베이스를 최신 스타일로 바꿔주는 세련된 무기인 셈이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;조건부 로직을 다형성으로 바꾸기(10.4)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.13 반복문 (Loops)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금은 일급 함수(first-class function)를 지원하는 언어가 많아졌기 때문에 시대에 걸맞지 않은 반복문을 제거할 수 있게 됐다. 필터나 맵 같은 파이프라인 연산을 사용하면 코드에서 각 원소들이 어떻게 처리되는지 쉽게 파악할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;반복문을 파이프라인으로 바꾸기(8.8)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.14 성의 없는 요소 (Lazy Element)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AEUYl/btrd1QXZwyB/eLhogXegCX8KiAVEFzmFsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AEUYl/btrd1QXZwyB/eLhogXegCX8KiAVEFzmFsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AEUYl/btrd1QXZwyB/eLhogXegCX8KiAVEFzmFsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAEUYl%2Fbtrd1QXZwyB%2FeLhogXegCX8KiAVEFzmFsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;436&quot; height=&quot;262&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 프로그램 요소(클래스, 메서드 등)를 이용하는 걸 좋아한다. 그렇지만 그 구조가 필요 없을 때도 있다. 본문 코드를 그대로 쓰는 것과 진배없는 함수도 있고, 실질적으로 메서드가 하나뿐인 클래스도 있다. &lt;u&gt;나중을 위해 고려했겠지만 사정이 어떠하든 이런 프로그램 요소는 고이 보내드리는게 좋다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;함수 인라인하기(6.2), 클래스 인라인하기(7.6), 계층 합치기(12.9)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.15 추측성 일반화 (Speculative Generailty)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ueb0y/btrd5kcXzKQ/DBlDRWyd4dHKvuttP5zh50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ueb0y/btrd5kcXzKQ/DBlDRWyd4dHKvuttP5zh50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ueb0y/btrd5kcXzKQ/DBlDRWyd4dHKvuttP5zh50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fueb0y%2Fbtrd5kcXzKQ%2FDBlDRWyd4dHKvuttP5zh50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;445&quot; height=&quot;267&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추측성 일반화는 우리가 민감하게 반응하는 냄새로, '나중에 필요할 거야'라는 생각으로 당장은 필요 없는 모든 종류의 후킹 포인트와 특이 케이스 처리 로직을 작성해둔 코드에서 풍긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 결과는 물론 이해하거나 관리하기 어려워진 코드다. 미래를 대비해 작성한 부분을 실제로 사용하게 되면 다행이지만, 그렇지 않는다면 쓸데없는 낭비일 뿐이다. &lt;u&gt;당장 걸리적거리는 코드는 눈앞에서 치워버리자.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;계층 합치기(12.9), 함수 인라인하기(6.2), 클래스 인라인하기(7.6), 함수 선언 바꾸기(6.5), 죽은 코드 제거하기(8.9)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.16 임시 필드 (Temporary Field)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 상황에서만 사용되는 필드를 가진 클래스도 있다. 하지만 객체를 가져올 때는 당연히 모든 필드가 채워져 있으리라 기대하는게 보통이다. 이렇게 &lt;u&gt;임시 필드를 갖도록 작성하면 코드를 이해하기 어렵다&lt;/u&gt;. 그래서 사용자는 쓰이지 않는 것처럼 보이는 필드가 존재하는 이유를 파악하느라 머리를 싸매게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 필드들을 클래스로 추출하거나 Null 처리 대안 클래스를 만들어서 제거하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;클래스 추출하기(7.5), 함수 옮기기(8.1), 특이 케이스 추가하기(10.5)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.17 메시지 체인 (Message Chains)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/u51MW/btrd16s2U6o/3fJ1nEASvKXMnE15zvSAY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/u51MW/btrd16s2U6o/3fJ1nEASvKXMnE15zvSAY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/u51MW/btrd16s2U6o/3fJ1nEASvKXMnE15zvSAY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu51MW%2Fbtrd16s2U6o%2F3fJ1nEASvKXMnE15zvSAY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;437&quot; height=&quot;262&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지 체인은 클라이언트가 한 객체를 통해 다른 객체를 얻은 뒤 방금 얻은 객체에 또 다른 객체를 요청하는 식으로, 다른 객체를 요청하는 작업이 연쇄적으로 이어지는 코드를 말한다. 이는 &lt;u&gt;클라이언트(객체 사용자)가 객체 내비게이션 구조에 종속됐음을 의미한다.&lt;/u&gt; 그래서 내비게이션 중간 단계를 수정하면 클라이언트 코드도 수정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 위임 숨기기로 해결한다. &lt;span style=&quot;color: #252525;&quot;&gt;때로는 최종 개체가 사용되는 이유를 생각해보면 기능을 추출하여 체인의 시작 부분으로 이동하는 것이 합리적일 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;위임 숨기기(7.7), 함수 추출하기(6.1), 함수 옮기기(8.1)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.18 중개자 (Middle Man)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XN3Bt/btrd0XQPSh0/Yy7eJy25x0zTstgNP88c6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XN3Bt/btrd0XQPSh0/Yy7eJy25x0zTstgNP88c6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XN3Bt/btrd0XQPSh0/Yy7eJy25x0zTstgNP88c6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXN3Bt%2Fbtrd0XQPSh0%2FYy7eJy25x0zTstgNP88c6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;470&quot; height=&quot;282&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캡슐화하는 과정에서는 위임이 자주 활용된다. 예를 들어 여러분이 팀장에게 미팅을 요청한다고 해보자. 팀장은 자신의 일저을 확인 후 답을 준다. 이러면 끝이다. 팀장이 종이 다이어를 쓰든, 일정 서비스를 쓰든, 따로 비서를 두든 우리는 알 바 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 지나치면 문제가 된다. &lt;u&gt;클래스가 다른 클래스에 작업을 위임하는 역할만 한다면 과연 필요할까?&lt;/u&gt; 이럴 때는 중개자 제거하기를 활용하여 실제로 일을 하는 객체와 직접 소통하게 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;중개자 제거하기(7.8), 함수 인라인하기(6.2)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.19 내부자 거래 (Insider Trading)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소프트웨어 개발자는 모듈 사이에 벽을 두껍게 세우기를 좋아하며, 그래서 모듈 사이의 데이터 거래가 많으면 결합도가 높아진다고 투덜댄다. 일이 돌아가게 하려면 데이터 거래가 이뤄질 수 밖에 없지만, 그 양을 최소로 줄이고 모두 투명하게 처리해야 한다. 은밀히 데이터를 주고받는 모듈들이 있다면 떼어놓아서 사적으로 처리하는 부분을 줄인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;함수 옮기기(8.1), 필드 옮기기(8.2), 위임 숨기기(7.7), 서브클래스를 위임으로 바꾸기(12.10), 슈퍼클래스를 위임으로 바꾸기(12.11)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.20 거대한 클래스 (Large Class)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VI9DS/btrd0GohrZ0/eB8jSyx0M7pkLUUdqVcCXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VI9DS/btrd0GohrZ0/eB8jSyx0M7pkLUUdqVcCXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VI9DS/btrd0GohrZ0/eB8jSyx0M7pkLUUdqVcCXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVI9DS%2Fbtrd0GohrZ0%2FeB8jSyx0M7pkLUUdqVcCXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;460&quot; height=&quot;276&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 클래스가 너무 많을 일을 하려다 보면 필드 수가 상당히 늘어난다. 그리고 클래스에 필드가 너무 많으면 중복 코드가 생기기 쉽다. 이럴 때는 한 컴퍼넌트에 모아두는 것이 합당에 보이는 필드들을 묶어 슈퍼클래스로 추출할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드량이 너무 많은 클래스도 중복 코드와 혼동을 일으킬 여지가 크다. 가장 간단한 해법은 그 클래스 안에서 자체적으로 중복을 제거하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;클라이언트들이 거대 클래스를&amp;nbsp; 어떻게 이용하는지 패턴을 파악하여 그 클래스를 어떻게 쪼갤지 단서를 얻을 수 있다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;클래스 추출하기(7.5), 슈퍼클래스 추출하기(12.8), 타입 코드를 서브클래스를 바꾸기(12.6)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.21 서로 다른 인터페이스의 대안 클래스들 (Alternative Classes with Different Interfaces)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스를 사용할 때의큰 장점은 필요에 따라 언제든 다른 클래스로 교체할 수 있다는 것이다. 교체하려면 인터페이스가 같아야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;클래스 추출하기(7.5), 슈퍼클래스 추출하기(12.8), 타입 코드를 서브클래스를 바꾸기(12.6)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.22 데이터 클래스 (Data Class)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kzb1r/btrd04iaWQG/b1kV9eOK4kz1hgtDKBYzd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kzb1r/btrd04iaWQG/b1kV9eOK4kz1hgtDKBYzd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kzb1r/btrd04iaWQG/b1kV9eOK4kz1hgtDKBYzd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fkzb1r%2Fbtrd04iaWQG%2Fb1kV9eOK4kz1hgtDKBYzd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;458&quot; height=&quot;275&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 클래스란 데이터 필드와 게터/세터 메서드로만 구성된 클래스를 말한다. &lt;u&gt;그저 데이터 저장 용도로만 쓰이다 보니 다른 클래스가 너무 깊이까지 함부로 다룰 때가 많다.&lt;/u&gt; 이런 클래스에 public 필드가 있다면 누가 보기 전에 얼른 레코드 캡슐화하기로 숨기자. 변경하면 안되는 필드는 세터 제거하기로 접근을 원천 봉쇄한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한편, 데이터 클래스는 필요한 동작이 엉뚱한 곳에 정의돼 있다는 신호일 수 있다. 이런 경우라면 클라이언트 코드를 데이터 클래스로 옮기기만 해도 대폭 개선된다. 예외적으로 다른 함수에서 리턴한 데이터 구조는 불변이므로 굳이 캡슐화할 필요가 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;레코드 캡슐화하기(7.1), 세터 제거하기(11.7), 함수 옮기기(8.1), 함수 추출하기(6.1), 단계 쪼개기(6.11)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.23 상속 포기 (Refused Bequest)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서브클래스는 부모로부터 메서드와 데이터를 물려받는다. 하지만 부모의 유산을 원치 않거나 필요 없다면 어떻게 해야 할까? 수많은 유산 중에서 관심 있는 몇 개만 받고 끝내려는 경우는 얼마든지 일을 수 있다. 상속 포기 냄새는 &lt;u&gt;서브클래스가 부모의 동작은 필요로하지만 인터페이스는 따르고 싶지 않을 때&lt;/u&gt; 특히 심하게 난다. 이럴 때는 위임을 활용해서 아예 상속 메커니즘에서 벗어나보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;서브클래스를 위임으로 바꾸기(12.10), 슈퍼클래스를 위임으로 바꾸기(12.11)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.24 주석 (Comments)&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDZU9E/btrd0FCVbHW/4zJchI1gY7HzKWC6v3ZPn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDZU9E/btrd0FCVbHW/4zJchI1gY7HzKWC6v3ZPn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDZU9E/btrd0FCVbHW/4zJchI1gY7HzKWC6v3ZPn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDZU9E%2Fbtrd0FCVbHW%2F4zJchI1gY7HzKWC6v3ZPn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;440&quot; height=&quot;264&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주석을 달면 안 된다고 말라려는 건 아니니 걱정하지 말자. 주석은 악취가 아닌 향기를 입힌다. 문제는 주석을 탈취제처럼 사용하는 데 있다. 주석이 장황하게 달린 원인이 코드를 잘못 작성했기 때문인 경우가 의외로 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;주석을 남겨야겠다는 생각이 들면, 가장 먼저 주석이 필요 없는 코드로 리팩터링해본다&lt;/u&gt;. 뭘 할지 모른 떄라면 주석을 달아두면 좋다. 이런 정보는 나중에 코드를 수정해야 할 프로그래머에게, 특히 건망증이 심한 프로그래머에게 도움될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;리팩터링 기법&lt;/b&gt;&lt;br /&gt;함수 추출하기(6.1), 함수 선언 바꾸기(6.5), 어서션 추가하기(10.6)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림 출처 : &lt;a href=&quot;https://refactoring.guru/smells&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://refactoring.guru/smells&lt;/a&gt;&lt;/p&gt;</description>
      <category>소프트웨어공학, CS/리팩터링 2판</category>
      <category>Refactoring</category>
      <category>리팩토링</category>
      <category>마틴파울러</category>
      <category>코드스멜</category>
      <category>코드악취</category>
      <author>이재원님</author>
      <guid isPermaLink="true">https://slog2.tistory.com/31</guid>
      <comments>https://slog2.tistory.com/31#entry31comment</comments>
      <pubDate>Sat, 4 Sep 2021 14:53:46 +0900</pubDate>
    </item>
  </channel>
</rss>