<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Become a better programmer</title>
    <link>https://dev-punxism.tistory.com/</link>
    <description>유지보수하기 쉬운 시스템 및 코드 설계를 좋아하는 시니어 개발자입니다.</description>
    <language>ko</language>
    <pubDate>Fri, 17 Apr 2026 02:47:22 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>아빠악어.</managingEditor>
    <image>
      <title>Become a better programmer</title>
      <url>https://t1.daumcdn.net/cfile/tistory/235373355891EF9834</url>
      <link>https://dev-punxism.tistory.com</link>
    </image>
    <item>
      <title>AI와 엔지니어의 역할 확장</title>
      <link>https://dev-punxism.tistory.com/entry/AI%EC%99%80-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EC%9D%98-%EC%97%AD%ED%95%A0-%ED%99%95%EC%9E%A5</link>
      <description>&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FE, BE가 full stack이나 앱 개발까지 확장되는,&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;PM 영역까지 포함해 full stack으로 일하게 하는 방식.&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;그리고 FE, BE, ML과 같은 전문 영역은 유지하면서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 안에서 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;이러한 변화는 각 조직이 처한 상황에 따라 다르게 나타난다.&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;특정 조건에서 더 잘 맞는 모델이라고 생각된다.&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;대부분의 서비스에서는&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;&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;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;다만,&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;그리고 AI를 활용하는 측면에서는&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;그래서 AI를 기반으로 한 새로운 역할에서도&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;&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;</description>
      <category>생각</category>
      <category>AI</category>
      <category>개발자</category>
      <category>소프트웨어</category>
      <category>엔지니어</category>
      <author>아빠악어.</author>
      <guid isPermaLink="true">https://dev-punxism.tistory.com/63</guid>
      <comments>https://dev-punxism.tistory.com/entry/AI%EC%99%80-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EC%9D%98-%EC%97%AD%ED%95%A0-%ED%99%95%EC%9E%A5#entry63comment</comments>
      <pubDate>Sat, 28 Mar 2026 20:27:04 +0900</pubDate>
    </item>
    <item>
      <title>비개발자의 AI Native 전환을 도우며 느낀 것들</title>
      <link>https://dev-punxism.tistory.com/entry/%EB%B9%84%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%9D%98-AI-Native-%EC%A0%84%ED%99%98%EC%9D%84-%EB%8F%84%EC%9A%B0%EB%A9%B0-%EB%8A%90%EB%82%80-%EA%B2%83%EB%93%A4</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;팀의 리드 엔지니어로 일하다 보면,&lt;br /&gt;이제는 비개발자분들로부터도 AI를 활용한 제품 개발에 대한 도움 요청을 자주 받게 된다.&lt;br /&gt;&lt;br /&gt;요청을 해결해 주면서 느낀 점들이 있다.&lt;br /&gt;&lt;br /&gt;⸻&lt;br /&gt;&lt;br /&gt;1. 잘하는 사람은, 결국 잘 만들어낸다&lt;br /&gt;&lt;br /&gt;문제를 정의하는 방식,&lt;br /&gt;구조를 나누는 감각,&lt;br /&gt;결과를 검증하는 태도.&lt;br /&gt;&lt;br /&gt;이건 도구의 문제가 아니다.&lt;br /&gt;&lt;br /&gt;AI를 활용하는 비개발자 중에서도&lt;br /&gt;이미 꽤 높은 완성도의 결과물을 만들어내는 사람들이 있다.&lt;br /&gt;그 분들은 개발을 했어도 잘했을 것 같다.&lt;br /&gt;&lt;br /&gt;AI는 능력을 대체하기보다&lt;br /&gt;이미 있는 역량을 잘 활용 할 수 있게 증폭 시켜 준다.&lt;br /&gt;&lt;br /&gt;⸻&lt;br /&gt;&lt;br /&gt;2. 사람은 쉽게 변하지 않는다&lt;br /&gt;&lt;br /&gt;많이들 기대하는 것과는 다르게,&lt;br /&gt;도구가 바뀐다고 사람이 바뀌지는 않는다.&lt;br /&gt;&lt;br /&gt;아무리 좋은 사례를 보여주고,&lt;br /&gt;생산성이 올라가는 경험을 하게 해도&lt;br /&gt;변할 동기가 없는 사람은 거의 변하지 않는다.&lt;br /&gt;&lt;br /&gt;이런 분들은 늘 비슷한 패턴을 보인다.&lt;br /&gt;&lt;br /&gt;익숙한 방식으로만 일하려 하고,&lt;br /&gt;새로운 시도는 부담으로 느끼며,&lt;br /&gt;결과보다 과정의 안정감을 더 중요하게 여긴다.&lt;br /&gt;&lt;br /&gt;결국 AI 전환은 기술 문제가 아니라&lt;br /&gt;태도의 문제에 더 가깝다.&lt;br /&gt;&lt;br /&gt;⸻&lt;br /&gt;&lt;br /&gt;3. 엔지니어링이 필요한 순간들&lt;br /&gt;&lt;br /&gt;AI를 활용하면 많은 것을 빠르게 만들 수 있다.&lt;br /&gt;하지만 어느 순간 막히는 지점이 온다.&lt;br /&gt;&lt;br /&gt;그 지점들은 비슷하다.&lt;br /&gt;&lt;br /&gt;1) 데이터와 책임의 문제 (개인정보 포함)&lt;br /&gt;어떤 데이터가 민감한지,&lt;br /&gt;외부 서비스나 AI에 넘겨도 되는지에 대한 감각이 없다.&lt;br /&gt;&lt;br /&gt;편하다는 이유로 데이터를 그대로 사용하다 보면&lt;br /&gt;나중에 되돌릴 수 없는 문제가 된다.&lt;br /&gt;&lt;br /&gt;2) 성능 문제가 터지는 순간&lt;br /&gt;서비스가 느려지거나, 응답이 불안정해지는 시점이 온다.&lt;br /&gt;&lt;br /&gt;그런데 대부분은&lt;br /&gt;&amp;ldquo;어디가 문제인지&amp;rdquo;를 알지 못한다.&lt;br /&gt;&lt;br /&gt;무엇을 측정해야 하는지 모르고,&lt;br /&gt;그래서 감으로 고치게 된다.&lt;br /&gt;문제가 해결된 것처럼 보여도 반복된다.&lt;br /&gt;&lt;br /&gt;이 두 가지는&amp;nbsp;&amp;nbsp;보이지 않는 것을 다루는 영역이라는 공통점이 있다.&lt;br /&gt;&lt;br /&gt;데이터는 눈에 보이지 않고,&lt;br /&gt;성능 병목도 눈에 보이지 않는다.&lt;br /&gt;&lt;br /&gt;그래서 이 영역에서는&lt;br /&gt;직관이나 경험만으로는 한계가 온다.&lt;br /&gt;&lt;br /&gt;최소한의 관측과 기준이 필요하다.&lt;br /&gt;&lt;br /&gt;AI 시대에도 여전히&lt;br /&gt;엔지니어링이 필요하다.&lt;br /&gt;&lt;br /&gt;⸻&lt;br /&gt;&lt;br /&gt;4. 버그와 마주하는 순간이 온다&lt;br /&gt;&lt;br /&gt;처음에는 빠르게 만들어진다.&lt;br /&gt;AI 덕분에 놀랄 정도로 속도가 나온다.&lt;br /&gt;&lt;br /&gt;그런데 어느 시점이 되면&lt;br /&gt;버그가 밀려오는 순간이 온다.&lt;br /&gt;&lt;br /&gt;그때부터가 시작이다.&lt;br /&gt;&lt;br /&gt;문제를 좁혀가는 능력,&lt;br /&gt;하나씩 해결하면서 구조를 정리하는 힘,&lt;br /&gt;끝까지 밀고 가는 태도.&lt;br /&gt;&lt;br /&gt;이걸 할 수 있는 사람이&lt;br /&gt;계속해서 프로덕트를 만들어간다.&lt;br /&gt;&lt;br /&gt;그리고 이 지점에서 차이가 크게 벌어진다.&lt;br /&gt;&lt;br /&gt;많은 분들이 여기서 포기한다.&lt;br /&gt;속도가 나오던 초반의 경험과 달리&lt;br /&gt;문제 해결은 훨씬 더 느리고 답답하기 때문이다.&lt;br /&gt;&lt;br /&gt;조금만 더 버티면,&lt;br /&gt;그 다음부터는 완전히 다른 단계로 넘어갈 수 있는데 아쉬움이 있다.&lt;br /&gt;&lt;br /&gt;AI는 시작을 쉽게 만들어주지만,&lt;br /&gt;지속하는 힘까지 대신해주지는 않는다.&lt;br /&gt;&lt;br /&gt;⸻&lt;br /&gt;&lt;br /&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;AI 덕분에 구현은 많이 쉬워졌지만,&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;&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;&amp;ldquo;얼마나 많이 만들 수 있는가&amp;rdquo;보다는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;어떤 문제를 끝까지 해결할 수 있는가&amp;rdquo;가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조금 더 중요한 기준이 되지 않을까 생각하게 된다.&lt;/p&gt;</description>
      <category>생각</category>
      <category>AI</category>
      <category>개발자</category>
      <author>아빠악어.</author>
      <guid isPermaLink="true">https://dev-punxism.tistory.com/62</guid>
      <comments>https://dev-punxism.tistory.com/entry/%EB%B9%84%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%9D%98-AI-Native-%EC%A0%84%ED%99%98%EC%9D%84-%EB%8F%84%EC%9A%B0%EB%A9%B0-%EB%8A%90%EB%82%80-%EA%B2%83%EB%93%A4#entry62comment</comments>
      <pubDate>Sat, 28 Mar 2026 11:58:56 +0900</pubDate>
    </item>
    <item>
      <title>AI 시대의 주니어 개발자에게 해주고 싶은 말</title>
      <link>https://dev-punxism.tistory.com/entry/AI-%EC%8B%9C%EB%8C%80%EC%9D%98-%EC%A3%BC%EB%8B%88%EC%96%B4-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%97%90%EA%B2%8C-%ED%95%B4%EC%A3%BC%EA%B3%A0-%EC%8B%B6%EC%9D%80-%EB%A7%90</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 AI에 대한 이야기가 정말 많다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 솔직히 말하면 이런 주장들도 &lt;/span&gt;&lt;b&gt;6개월 뒤에 어떻게 바뀔지 아무도 모른다.&lt;/b&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;지금까지 AI의 발전 속도를 보면, 우리가 확신할 수 있는 것은 하나뿐이다.&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;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;나는 개인적으로 &lt;/span&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;p data-ke-size=&quot;size16&quot;&gt;적어도 우리가 알고 있는 형태의 개발자는 사라질 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;아마 &lt;/span&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;p data-ke-size=&quot;size16&quot;&gt;나 역시 AI를 적극적으로 사용하면서 생산성이 크게 늘었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘은 IDE를 세 개 띄워 두고 서로 다른 컨텍스트의 작업을 동시에 진행하기도 한다.&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;&amp;nbsp;&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;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 우리 조직에서는 개발자가 아닌 직군의 사람들도 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;ldquo;정말 가능할까?&amp;rdquo;라는 의문을 가졌지만, 지금 상황을 보면 중요한 것은 가능 여부가 아니다.&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;도구는 이미 모두의 손에 쥐어졌다.&lt;/b&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;물론 엔지니어링 지식이나 AI 활용 경험이 많은 사람일수록 더 빠르게 접근한다.&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;b&gt;결국 엉덩이가 무거운 사람이 이기는 게임이라는 점이다.&lt;/b&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;그렇게 집요하게 반복하는 사람이 결국 품질 좋은 프로덕트를 만들어낸다.&lt;/p&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 제품이 &lt;span&gt;&lt;b&gt;왜 필요한지에 대한 절실함&lt;/b&gt;&lt;/span&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;hr data-ke-style=&quot;style1&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;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;주니어 개발자에게 해주고 싶은 말이 있나요?&amp;rdquo;&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;span&gt;&lt;b&gt;주니어와 함께 성장해야 한다&lt;/b&gt;&lt;/span&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;b&gt;주니어를 성장시키는 것보다 프롬프트를 성장시키는 것이 더 빠른 결과를 만든다.&lt;/b&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차라리 시니어에게 서버 몇 대와 충분한 AI 비용을 주고&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;span&gt;그만큼 &lt;/span&gt;&lt;b&gt;시니어의 영향력이 크게 확대되는 시대&lt;/b&gt;&lt;span&gt;이기도 하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;앞으로 &lt;/span&gt;&lt;b&gt;엔지니어라는 직업 자체가 사라질 수도 있다.&lt;/b&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;span&gt;적어도 &lt;/span&gt;&lt;b&gt;코딩을 할 줄 안다는 이유만으로 엔지니어라 불리는 시대는 끝날 것&lt;/b&gt;&lt;span&gt;이다.&lt;/span&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;Biz도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PM도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PD도&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;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그렇다면 이 시대에 &lt;/span&gt;&lt;b&gt;주니어 엔지니어에게 정말 필요한 것은 무엇일까.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 &lt;span&gt;&lt;b&gt;지식이 아니라 태도&lt;/b&gt;&lt;/span&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;span&gt;하지만 지금처럼 &lt;/span&gt;&lt;b&gt;변화의 속도가 빠른 시기는 처음이다.&lt;/b&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;b&gt;어떤 태도를 가지고 있느냐가 더 중요하다.&lt;/b&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;&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;긍정적인 마음&lt;/li&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;&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;span&gt;&lt;b&gt;먼저 시도해야 한다.&lt;/b&gt;&lt;/span&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;Biz, PM, PD의 ai 전환을 돕고 필요 하다면 엔지니어도 타 직군의 업무를 경험 해봐야 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&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;p data-ke-size=&quot;size16&quot;&gt;그래서 더 중요한 것이 &lt;span&gt;&lt;b&gt;마음의 상태&lt;/b&gt;&lt;/span&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;&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;b&gt;변화를 즐길 수 있는 사람&lt;/b&gt;&lt;span&gt;일 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;I에게 점점 살기 힘든 세상이 되어가는 것 같다.&lt;/b&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;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;교육도 &lt;/span&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;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;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;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;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;</description>
      <category>생각</category>
      <category>AI</category>
      <category>개발자</category>
      <author>아빠악어.</author>
      <guid isPermaLink="true">https://dev-punxism.tistory.com/61</guid>
      <comments>https://dev-punxism.tistory.com/entry/AI-%EC%8B%9C%EB%8C%80%EC%9D%98-%EC%A3%BC%EB%8B%88%EC%96%B4-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%97%90%EA%B2%8C-%ED%95%B4%EC%A3%BC%EA%B3%A0-%EC%8B%B6%EC%9D%80-%EB%A7%90#entry61comment</comments>
      <pubDate>Fri, 6 Mar 2026 10:37:24 +0900</pubDate>
    </item>
    <item>
      <title>돈은 동기도 목적도 아니다</title>
      <link>https://dev-punxism.tistory.com/entry/%EB%8F%88%EC%9D%80-%EB%8F%99%EA%B8%B0%EB%8F%84-%EB%AA%A9%EC%A0%81%EB%8F%84-%EC%95%84%EB%8B%88%EB%8B%A4</link>
      <description>&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;blockquote data-ke-style=&quot;style2&quot;&gt;1. 도전과 책임&lt;br /&gt;2. 유연성&lt;br /&gt;3. 안정적인 작업 환경&lt;br /&gt;4. 돈&lt;br /&gt;5. 직업적 발전&lt;br /&gt;6. 같은 일을 하는 사람들 사이에서 인정받는 것&lt;br /&gt;7. 의욕을 자극하는 동료와 상사&lt;br /&gt;8. 일 자체의 재미&lt;br /&gt;9. 조직 문화&lt;br /&gt;10. 자신이 속한 지역과 공동체&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;출처가 모호하긴 하지만 세스 고딘은 동기의 요인으로 위 10가지를 설명합니다. 이 중 외부 요인은 단 하나, 돈 뿐이라고 합니다. 다른 요인은 모두 나 스스로를 위하기 때문에, 나를 나답게 만들어주기 때문에 우리가 소중하게 여기는 것이라 설명합니다.&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;&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;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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 주니어 개발자일 때 &lt;a href=&quot;https://web.archive.org/web/20060904102741/http://jowchung.oolim.net/data/7/top_k.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;프로그래머의 도&lt;/a&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;최근의 개발 스타일은 다르다고 생각합니다. 클린 코드가 규칙이고 서킷 브레이커를 붙여야 하고 예술 작품을 만들기 보다는 주어진 문제에 정답을 찾는 느낌입니다. s/w를 전달은 하지만 내부 요인이 아닌 외부 요인으로 동기를 얻는 느낌입니다.&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 외부 요인 뿐이였던 것 같습니다. 동기에 대한 다른 이론이 있는지 찾아 보았습니다. GTP가 다니엘 핑크(Daniel Pink) 의 《드라이브(Drive)》와 프레더릭 허즈버그(Frederick Herzberg) 의 동기-위생 이론을 알려주네요. 드라이브는 사람들이 외적 보상(돈, 상 등) 보다 내적 동기(Autonomy, Mastery, Purpose) 에 의해 더 효과적으로 동기부여된다고 주장한다고 합니다. 동기-위생 이론은 만족을 높이는 동기 요소 - 내부 요인, 불만을 줄이는 요소 - 외부 요인으로 정의 합니다. 위생 요인이 충족 된다고 하더라도 동기가 부여 되지는 않는다고 합니다. 개인적으로는 동기-위생 이론이 더 와닿는군요.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 올 한 해는 내부 동기를 목표로 일해보려합니다.&lt;/p&gt;</description>
      <category>생각</category>
      <author>아빠악어.</author>
      <guid isPermaLink="true">https://dev-punxism.tistory.com/56</guid>
      <comments>https://dev-punxism.tistory.com/entry/%EB%8F%88%EC%9D%80-%EB%8F%99%EA%B8%B0%EB%8F%84-%EB%AA%A9%EC%A0%81%EB%8F%84-%EC%95%84%EB%8B%88%EB%8B%A4#entry56comment</comments>
      <pubDate>Wed, 19 Mar 2025 09:49:03 +0900</pubDate>
    </item>
    <item>
      <title>Intermodule Coupling</title>
      <link>https://dev-punxism.tistory.com/entry/Intermodule-Coupling</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.cs.unc.edu/~stotts/COMP145/coupling.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.cs.unc.edu/~stotts/COMP145/coupling.html&lt;/a&gt;&amp;nbsp;요약&lt;/p&gt;
&lt;figure id=&quot;og_1738984756424&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;COMP 145: Module Coupling&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.cs.unc.edu&quot; data-og-source-url=&quot;https://www.cs.unc.edu/~stotts/COMP145/coupling.html&quot; data-og-url=&quot;https://www.cs.unc.edu/~stotts/COMP145/coupling.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.cs.unc.edu/~stotts/COMP145/coupling.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.cs.unc.edu/~stotts/COMP145/coupling.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;COMP 145: Module Coupling&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.cs.unc.edu&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;a&gt;Stamp Coupling&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;952&quot; data-origin-height=&quot;1028&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxdDYR/btsMbEDeo1K/7SRkTmzcCQlqulo8vzSiJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxdDYR/btsMbEDeo1K/7SRkTmzcCQlqulo8vzSiJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxdDYR/btsMbEDeo1K/7SRkTmzcCQlqulo8vzSiJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxdDYR%2FbtsMbEDeo1K%2F7SRkTmzcCQlqulo8vzSiJ0%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;495&quot; data-origin-width=&quot;952&quot; data-origin-height=&quot;1028&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;a&gt;Control Coupling&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;982&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L7iVJ/btsMcJwRRjh/fd942ufBaeijj6KFk0u7pk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L7iVJ/btsMcJwRRjh/fd942ufBaeijj6KFk0u7pk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L7iVJ/btsMcJwRRjh/fd942ufBaeijj6KFk0u7pk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL7iVJ%2FbtsMcJwRRjh%2Ffd942ufBaeijj6KFk0u7pk%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;459&quot; height=&quot;449&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;982&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 모듈간 control flag를 전달하여 B 모듈의 액션을 제어 하는 것, 외부에서 내부를 제어하는 것으로 내부 정보를 알고 있다는 것은 결합도가 높다는 것, 캡슐화 위반&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;a&gt;Common Coupling&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;1234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r8jRd/btsMaRiZ7FO/LoEwWTkAGArrrroSjr3ie1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r8jRd/btsMaRiZ7FO/LoEwWTkAGArrrroSjr3ie1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r8jRd/btsMaRiZ7FO/LoEwWTkAGArrrroSjr3ie1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr8jRd%2FbtsMaRiZ7FO%2FLoEwWTkAGArrrroSjr3ie1%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;487&quot; height=&quot;649&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;1234&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;a&gt;Content Coupling&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1148&quot; data-origin-height=&quot;224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cD0qPi/btsMb1ZdPGy/BOhI3OhO6csRzi8ODprkAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cD0qPi/btsMb1ZdPGy/BOhI3OhO6csRzi8ODprkAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cD0qPi/btsMb1ZdPGy/BOhI3OhO6csRzi8ODprkAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcD0qPi%2FbtsMb1ZdPGy%2FBOhI3OhO6csRzi8ODprkAK%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;461&quot; height=&quot;90&quot; data-origin-width=&quot;1148&quot; data-origin-height=&quot;224&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;1번은 functional programming인가 생각했는데 문장의 변경은 아니므로 Lisp이나 pascal에서 지원되는 다른 기능으로 보임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3번은 잘 이해가 안됨..&lt;/p&gt;</description>
      <author>아빠악어.</author>
      <guid isPermaLink="true">https://dev-punxism.tistory.com/55</guid>
      <comments>https://dev-punxism.tistory.com/entry/Intermodule-Coupling#entry55comment</comments>
      <pubDate>Sat, 8 Feb 2025 12:31:59 +0900</pubDate>
    </item>
    <item>
      <title>Event Driven Microservices and Data Consistency, Example</title>
      <link>https://dev-punxism.tistory.com/entry/Event-Driven-Microservices-and-Data-Consistency</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;a href=&quot;https://dev-punxism.tistory.com/entry/Event-Driven-Microservices&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dev-punxism.tistory.com/entry/Event-Driven-Microservices&lt;/a&gt; 의 연속본, Data Consistency가 핵심인듯하여 따로 정리한다.&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Data is a precious thing and will last longer than the systems themselves. by Tim Berners-Lee&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Software에서 중요한 것은 데이터이다. 결국 우리가 Software를 개발하는 이유가 데이터를 헨들링하기 위해서가 아닐까 생각된다.&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;MSA에서 데이터를 다루는 것은 어렵다. 특히 트랜잭션이 필요한 환경에서는 더 어렵다. 여러가지 방법들이 있지만 전반적으로 대세는 Event Souring으로 보여진다. 개인적으로는 local transaction을 이용한 ebay에서 사용한다는 BASE 모델이 마음에 들긴한다. Ordering이나 Loss에 대한 걱정을 많이 하지 않아도 될 것 같아서이다.&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;Event Sourcing은 서비스들과 통신하는 Client가 결국 비동기 방식으로 작성되어야 완성 될 수 있지 않을까 생각한다. Event Sourcing에서는 soft weak가 되면서 CQRS가 필수적으로 적용되어야 한다고 생각된다. 예를 들어 Order를 했으면 Order를 확인 하는 것은 폴링을 하거나 푸시를 하거나 비동기로 처리될 수 있어야 하며 결국 정통적인 서버, 클라이언트 구조에서 많은 부분들의 변경이 필요하지 않을까 생각된다.&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;아래는 강의 중 소개된 nginx에서 MSA를 설명하는 링크이다. 대략적으로 비슷한 내용이라 아래 링크를 참조하는 것도 좋을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.nginx.com/blog/event-driven-data-management-microservices/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.nginx.com/blog/event-driven-data-management-microservices/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644883045282&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Event-Driven Data Management for Microservices - NGINX&quot; data-og-description=&quot;Learn how an event-driven microservices architecture solves the distributed data management challenges caused by separate per-service datastores.&quot; data-og-host=&quot;www.nginx.com&quot; data-og-source-url=&quot;https://www.nginx.com/blog/event-driven-data-management-microservices/&quot; data-og-url=&quot;https://www.nginx.com/blog/event-driven-data-management-microservices/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bUywfc/hyNplQbZ2A/5gEAobkbVPxx5dTa3aJKXk/img.png?width=1500&amp;amp;height=1123&amp;amp;face=0_0_1500_1123,https://scrap.kakaocdn.net/dn/lGVJm/hyNqzeXHx2/okK7kr6RJ7onfCWFKzXcdK/img.png?width=1500&amp;amp;height=1025&amp;amp;face=0_0_1500_1025&quot;&gt;&lt;a href=&quot;https://www.nginx.com/blog/event-driven-data-management-microservices/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.nginx.com/blog/event-driven-data-management-microservices/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bUywfc/hyNplQbZ2A/5gEAobkbVPxx5dTa3aJKXk/img.png?width=1500&amp;amp;height=1123&amp;amp;face=0_0_1500_1123,https://scrap.kakaocdn.net/dn/lGVJm/hyNqzeXHx2/okK7kr6RJ7onfCWFKzXcdK/img.png?width=1500&amp;amp;height=1025&amp;amp;face=0_0_1500_1025');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Event-Driven Data Management for Microservices - NGINX&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Learn how an event-driven microservices architecture solves the distributed data management challenges caused by separate per-service datastores.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.nginx.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;Forces
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Some businees trasancions must update data owned by multiple services&lt;/li&gt;
&lt;li&gt;Some queries must join data that is owned by multiple servies&lt;/li&gt;
&lt;li&gt;Different have different data storage requirements&lt;/li&gt;
&lt;li&gt;Databases must sometimes be replicated and sharded for scalavility&lt;/li&gt;
&lt;li&gt;Services must be lossely coupled so that they can be developed, deployed and scaled independently&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Shared database
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;benefits&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;easier operationally&lt;/li&gt;
&lt;li&gt;local trasactions only&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;drawbacks&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;lack of encapsulation/tight coupling&lt;/li&gt;
&lt;li&gt;Single database might not satifsy the data access requirements of&lt;/li&gt;
&lt;li&gt;many connections&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Database per service
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;variations
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;private tables&lt;/li&gt;
&lt;li&gt;private schema&lt;/li&gt;
&lt;li&gt;private database server&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Escapes the constraints of relational databases
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;Multi data center, distributed database&lt;/li&gt;
&lt;li&gt;Schema updates&lt;/li&gt;
&lt;li&gt;O/R impedance mismatch
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;mismatch rich object vs shcema (maping object to database table)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Handling semi structured data&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;How does each service access data
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Velocity and Volume&lt;/li&gt;
&lt;li&gt;Variety of Data&lt;/li&gt;
&lt;li&gt;Fixed or ad hoc queries&lt;/li&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Access Patterns&lt;/li&gt;
&lt;li&gt;Distrubution&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;benefits&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;service are loosely coupled&lt;/li&gt;
&lt;li&gt;Each service can use the data that is&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;drawbacks&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Implementaing transactions and queries theat span multiple service&lt;/li&gt;
&lt;li&gt;more complex to operate&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;problem
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ACID broken&lt;/li&gt;
&lt;li&gt;2 phase commit&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;how to maintain invariants
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;event driven approach&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Using Events to Maintain Data Consistency
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Use an event driven ar
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;publish&lt;/li&gt;
&lt;li&gt;subscribe
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Maintain eventual consistency across multiple aggregates&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ACID vs Eventual Consistency&lt;/li&gt;
&lt;li&gt;problem
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;How to design eventually consistency business logic&lt;/li&gt;
&lt;li&gt;How atomically update database and publish an event&lt;/li&gt;
&lt;li&gt;Failure = inconsistent system&lt;/li&gt;
&lt;li&gt;Update and publish using 2PC
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Guaranteed atomicity BUT&lt;/li&gt;
&lt;li&gt;need a distributed trsasaction manager&lt;/li&gt;
&lt;li&gt;Databse and message broker must support 2pc&lt;/li&gt;
&lt;li&gt;impacts reliability&lt;/li&gt;
&lt;li&gt;Not fashionable&lt;/li&gt;
&lt;li&gt;2PC is best avoided (2pc는 피하는 것이 가장 좋습니다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Transaction log tailing
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;linkedin : databus&lt;/li&gt;
&lt;li&gt;AWS DynamoDB Streams&lt;/li&gt;
&lt;li&gt;benefits&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;No 2PC&lt;/li&gt;
&lt;li&gt;NO application changes required&lt;/li&gt;
&lt;li&gt;Guaranteed to be accurate&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;drawbacks&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;immature&lt;/li&gt;
&lt;li&gt;database specific&lt;/li&gt;
&lt;li&gt;low level db changes rather business level event = need to reverse engineer domain events&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Application created events
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Local Transaction with acid - db table&lt;/li&gt;
&lt;li&gt;Event publisher query to publish&lt;/li&gt;
&lt;li&gt;See BASE (&lt;a href=&quot;https://queue.acm.org/detail.cfm?id=1394128)&quot;&gt;https://queue.acm.org/detail.cfm?id=1394128)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;benefits&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;high level domain events&lt;/li&gt;
&lt;li&gt;No 2PC&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;drawbacks&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;requries changes to the appliation&lt;/li&gt;
&lt;li&gt;only works for sql and some nosql databses&lt;/li&gt;
&lt;li&gt;error prone&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Overview of Event Sourcing
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Event Sourcing
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;For each aggregate (Business entity)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Identify (state changing) domin events&lt;/li&gt;
&lt;li&gt;Define Event classes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Persistes events NOT current state&lt;/li&gt;
&lt;li&gt;Replay events to recreate state
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Periodically snapshot to avoid lodaing all events&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Request Handling in an event sourced application (event-centric way)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;pastEvents = findEvent(entityId) to event store&lt;/li&gt;
&lt;li&gt;new() to service&lt;/li&gt;
&lt;li&gt;applicaEvents(pastEvents) to service&lt;/li&gt;
&lt;li&gt;newEvents = processCmd(SomeCmd) to service&lt;/li&gt;
&lt;li&gt;apply(newEvents) to service&lt;/li&gt;
&lt;li&gt;saveEvents(newEvents) to event store with optimistic locking&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Event store = database + message broker
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Hybrid database and messge broker&lt;/li&gt;
&lt;li&gt;Implementations:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Home grown/DIY&lt;/li&gt;
&lt;li&gt;geteventstore.com by greg young&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://eventuate.io&quot;&gt;http://eventuate.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Benefis of Event sourcing
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Solves data consistency issues in a microservice/NoSql based architecture&lt;/li&gt;
&lt;li&gt;Reliable event publishing: publishes events neede by predictive analytics etc, user notifications..&lt;/li&gt;
&lt;li&gt;Eliminates O/R mapping problem (mostly)&lt;/li&gt;
&lt;li&gt;Reifies stat changes:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Bulit in, reliable audit log,&lt;/li&gt;
&lt;li&gt;temporal queries&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Preserved history =&amp;gt; More easily implement future requirements&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Drawbacks of
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Requires application rewrite&lt;/li&gt;
&lt;li&gt;Weird and unfamiliar style of programming&lt;/li&gt;
&lt;li&gt;Events = a historical record of your bad design decisions&lt;/li&gt;
&lt;li&gt;Must detect and ignore duplicate events
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Idempotent event handlers&lt;/li&gt;
&lt;li&gt;Tarack most recent event and ignore older ones&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Querying the event store can be challenging
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Some queries might be complex/inefficient e.g.accounts with a balance &amp;gt; X&lt;/li&gt;
&lt;li&gt;Event store might only support lookup of events by entify id&lt;/li&gt;
&lt;li&gt;Must use Command QUery Responseisbility Segregation(CQRS) to handle queries =&amp;gt; application must handle eventually consisten data&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Desining a Domain Model Based on Event Sourcing
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Use the familiar building blocks of DDD
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Entity&lt;/li&gt;
&lt;li&gt;Value obejct&lt;/li&gt;
&lt;li&gt;Service&lt;/li&gt;
&lt;li&gt;Repositories&lt;/li&gt;
&lt;li&gt;Aggregates &amp;lt;= essential&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Abot Aggregates
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Graph Consistin of a root entity and one or more other entities and value objects&lt;/li&gt;
&lt;li&gt;Each core business entity = Aggregate: e.g. customer, Account, Order, Product,...&lt;/li&gt;
&lt;li&gt;Reference other aggregate roots via primary key&lt;/li&gt;
&lt;li&gt;Often contains parial copy of other aggregates, data&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Domain model = collection of loosely connected aggregates&lt;/li&gt;
&lt;li&gt;Easily partition intto microservices&lt;/li&gt;
&lt;li&gt;Transaction = processing one command by one aggregate
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;No opportunity to update multiple aggregates within a transaction =&amp;gt; event driven eventual consistency between aggregates&lt;/li&gt;
&lt;li&gt;If an update must be atomic then it must be hanndled by a single aggregate&lt;/li&gt;
&lt;li&gt;Therefore, aggregate granularity is important&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Aggregate granularity
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;consistency &amp;lt;-&amp;gt; scalability / User experience&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Designing domain events
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Record state changes(and other notable things) for an aggregate&lt;/li&gt;
&lt;li&gt;Part of the public API of the domain model&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Designing commands
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Created by a service from incoming request&lt;/li&gt;
&lt;li&gt;Processed by an aggregate&lt;/li&gt;
&lt;li&gt;Immutable&lt;/li&gt;
&lt;li&gt;Contains value objects for
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Validating request&lt;/li&gt;
&lt;li&gt;Createing event&lt;/li&gt;
&lt;li&gt;Audit user&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Various programming models
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Traditional java mutable object-oriented domain object&lt;/li&gt;
&lt;li&gt;Functional scala with immutable domain objects&lt;/li&gt;
&lt;li&gt;Hydrid OO/Functional Scala with immutable domain object&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Event Sourcing Domain Model
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/cer/event-sourcing-examples.git&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/cer/event-sourcing-examples.git&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>아빠악어.</author>
      <guid isPermaLink="true">https://dev-punxism.tistory.com/54</guid>
      <comments>https://dev-punxism.tistory.com/entry/Event-Driven-Microservices-and-Data-Consistency#entry54comment</comments>
      <pubDate>Mon, 14 Feb 2022 20:38:00 +0900</pubDate>
    </item>
    <item>
      <title>Event Driven Microservices</title>
      <link>https://dev-punxism.tistory.com/entry/Event-Driven-Microservices</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learning.oreilly.com/videos/event-driven-microservices/9781491944165/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learning.oreilly.com/videos/event-driven-microservices/9781491944165/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644825615968&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;video.episode&quot; data-og-title=&quot;Event-Driven Microservices&quot; data-og-description=&quot;Software developers and architects increasingly turn to microservices as a framework for improving the agility and velocity of their development efforts. But is it the right approach? This video presents &amp;hellip; - Selection from Event-Driven Microservices [Vid&quot; data-og-host=&quot;www.oreilly.com&quot; data-og-source-url=&quot;https://learning.oreilly.com/videos/event-driven-microservices/9781491944165/&quot; data-og-url=&quot;https://www.oreilly.com/library/view/event-driven-microservices/9781491944165/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ddnHxL/hyNqGdLJbB/rgGj1ZAVDtx39t2C9hGrsK/img.jpg?width=327&amp;amp;height=184&amp;amp;face=139_34_177_75&quot;&gt;&lt;a href=&quot;https://learning.oreilly.com/videos/event-driven-microservices/9781491944165/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learning.oreilly.com/videos/event-driven-microservices/9781491944165/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ddnHxL/hyNqGdLJbB/rgGj1ZAVDtx39t2C9hGrsK/img.jpg?width=327&amp;amp;height=184&amp;amp;face=139_34_177_75');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Event-Driven Microservices&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Software developers and architects increasingly turn to microservices as a framework for improving the agility and velocity of their development efforts. But is it the right approach? This video presents &amp;hellip; - Selection from Event-Driven Microservices [Vid&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.oreilly.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 위 링크의 강의를 보고 요약/정리, 개인적인 생각을 첨가했다. 약파는 이야기(?)가 좀 있으나 전반적으로 들을만했다. 몇몇 중요하지 않다는 주제에 대해서 여러가지 view에서 설명하는 것이 흥미로웠다.&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;몇 년전 MSA로 프로젝트를 진행하다 큰 코 다쳤다. DDD용어로 이야기하면 Domain Aggregates가 요구사항에 따라 변경되어 발생한 문제였는데 그 이후 MSA라하면 치를 떨었다. 하지만 많은 시간이 지났고 DDD와 MSA를 함께 이야기하는 것을 보거나 Event Driven, Event Sourcing등의 설계가 분산처리 시스템에서 중요하게 자리잡는 것을 보고 다시 한 번 알아볼 마음이 생겨 코스를 수강했다.&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;예제 소스 보다 강사의 repository를 보게 되었는데 아직도 왕성하게 commit이 올라온다. 보고 배울만한 점이다.&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;소프트웨어 아키텍쳐에 대해서 은탄환은 없다. MSA에 대한 강의이지만 Monolitic이나 다른 architecture도 충분히 사용 가능하다는 것을 인지해야한다. 요즘 읽는 책에서 본 인상 깊었던 문장이 떠오른다.&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;Don&amp;rsquo;t try to find the best design in software architecture; instead, strive for the least worst combination of trade-offs.&lt;br /&gt;&lt;br /&gt;소프트웨어 아키텍처에서 최상의 디자인을 찾으려고 하지 마십시오. 대신, 최소 최악의 절충안 조합을 위해 노력하십시오.&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Monolitic architecture&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;easy / past, simple&lt;/li&gt;
&lt;li&gt;slow start application
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오픈소스 소프트웨어 최적화 보고서에서 느리게 시작하는 프로젝트의 경우 개발자들의 참가율이 떨어진다는 글을 본적이 있다.&amp;nbsp; 간과 할 수 있는 부분이지만 개발자의 만족감을 주거나 수십번의 Test를 수행한다 생각하면 어떻게든 줄이는게 좋다고 생각한다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;more coordinator
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;관계자가 많기 때문에 더 많은 커뮤니케이션이 발생한다. 현 부서가 이렇게 일하고 있는데 참 공감가는 부분이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;cpu, io, memory intensive&lt;/li&gt;
&lt;li&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;MicroService Architecure&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;The Scale Cube - &lt;a href=&quot;https://microservices.io/articles/scalecube.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://microservices.io/articles/scalecube.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1644826779297&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;The Scale Cube&quot; data-og-description=&quot;Microservices.io is brought to you by Chris Richardson. Experienced software architect, author of POJOs in Action, the creator of the original CloudFoundry.com, and the author of Microservices patterns. Chris helps clients around the world adopt the micros&quot; data-og-host=&quot;microservices.io&quot; data-og-source-url=&quot;https://microservices.io/articles/scalecube.html&quot; data-og-url=&quot;https://microservices.io/articles/scalecube.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://microservices.io/articles/scalecube.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://microservices.io/articles/scalecube.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;The Scale Cube&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Microservices.io is brought to you by Chris Richardson. Experienced software architect, author of POJOs in Action, the creator of the original CloudFoundry.com, and the author of Microservices patterns. Chris helps clients around the world adopt the micros&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;microservices.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Scale에 대해 Cube로 설명한다. X축은 instance를 늘리는 것이다. 가장 보편적으로 하고 있는 scale 방식이지만 원천적인 복잡한 문제를 해결해 주진 않는다. Y축의 확장은 서비스를 분리 확장하는 MSA의 개념이다 Z축은 data paritioning 또는 그와 비슷한 확장 방식이라 한다. X의 확장과 비슷하나 다른 점은 각 서버가 subset의 data만의 책임을 가지는 개념이다.&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;benefits
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;easy understand&lt;/li&gt;
&lt;li&gt;less jar, classpath hell = who needs osgi?&lt;/li&gt;
&lt;li&gt;faster to build and deploy&lt;/li&gt;
&lt;li&gt;reduce start up time &amp;amp; test time&lt;/li&gt;
&lt;li&gt;scales development&lt;/li&gt;
&lt;li&gt;fault isolation - impact toe one small service&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;drawbacks
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;complexity of developing a distrubuted system&lt;/li&gt;
&lt;li&gt;vs complexity of monolitic architecture&lt;/li&gt;
&lt;li&gt;multiple databases &amp;amp; transaction management
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;fun with eventual consistency&lt;/li&gt;
&lt;li&gt;can`t use ACD, CAP&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;complexity of test, deploying, operating&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;need a lot of automation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;developing features that span multiple services requires careful coordination&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Conway Law
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;software의 구조는 조직의 모양을 미러한다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://thecustomizewindows.com/2021/01/what-is-conways-law/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://thecustomizewindows.com/2021/01/what-is-conways-law/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1644833611293&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;What is Conway's Law?&quot; data-og-description=&quot;Conway&amp;rsquo;s law is an observation, which states that the structures of systems are predetermined by the communication structures of the organizations that implement them. Conway&amp;rsquo;s law is based on the idea that interpersonal communication is necessary to d&quot; data-og-host=&quot;thecustomizewindows.com&quot; data-og-source-url=&quot;https://thecustomizewindows.com/2021/01/what-is-conways-law/&quot; data-og-url=&quot;https://thecustomizewindows.com/2021/01/what-is-conways-law/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/F5fOf/hyNpagyUDP/OpRH6atyY8UNvHHjFvUAm1/img.jpg?width=1280&amp;amp;height=1085&amp;amp;face=0_0_1280_1085,https://scrap.kakaocdn.net/dn/3xOlr/hyNppEM8je/NKJbd3TJlTG85bt7EEL0dK/img.jpg?width=1280&amp;amp;height=1085&amp;amp;face=0_0_1280_1085&quot;&gt;&lt;a href=&quot;https://thecustomizewindows.com/2021/01/what-is-conways-law/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://thecustomizewindows.com/2021/01/what-is-conways-law/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/F5fOf/hyNpagyUDP/OpRH6atyY8UNvHHjFvUAm1/img.jpg?width=1280&amp;amp;height=1085&amp;amp;face=0_0_1280_1085,https://scrap.kakaocdn.net/dn/3xOlr/hyNppEM8je/NKJbd3TJlTG85bt7EEL0dK/img.jpg?width=1280&amp;amp;height=1085&amp;amp;face=0_0_1280_1085');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;What is Conway's Law?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Conway&amp;rsquo;s law is an observation, which states that the structures of systems are predetermined by the communication structures of the organizations that implement them. Conway&amp;rsquo;s law is based on the idea that interpersonal communication is necessary to d&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;thecustomizewindows.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Partitioning Strategies&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;partition by noun (service), verb(checkout ui), subdomain&lt;/li&gt;
&lt;li&gt;Single Responsibility Principle&lt;/li&gt;
&lt;li&gt;Major Challeange
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;How to enforce invariants across paritioned service without 2PC&lt;/li&gt;
&lt;li&gt;Partitioning requires you understand the design
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Existing Monolith
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;You understand the dependencies but decomposion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Greenfield Development - No code -&amp;gt; No tangled dependencies, but no design either Therefore do some upfront design / prototyping to understand what you are partitioning&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Greenfield development refers to developing a system for a totally new environment and requires development from a clean slate &amp;ndash; no legacy code around. It is an approach used when you&amp;rsquo;re starting fresh and with no restrictions or dependencies.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://synoptek.com/insights/it-blogs/greenfield-vs-brownfield-software-development/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://synoptek.com/insights/it-blogs/greenfield-vs-brownfield-software-development/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1644834079122&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Brownfield vs. Greenfield Development: What&amp;rsquo;s the Difference in Software? | Synoptek&quot; data-og-description=&quot;Greenfield and Brownfield are two major categories in software development. Explore their benefits, challenges, and how to choose between a Brownfield or Greenfield project.&quot; data-og-host=&quot;synoptek.com&quot; data-og-source-url=&quot;https://synoptek.com/insights/it-blogs/greenfield-vs-brownfield-software-development/&quot; data-og-url=&quot;https://synoptek.com/insights/it-blogs/greenfield-vs-brownfield-software-development/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eFaIfs/hyNqxgTCKU/pPo9njrMQlVpY9wylw3tq0/img.png?width=300&amp;amp;height=194&amp;amp;face=0_0_300_194,https://scrap.kakaocdn.net/dn/ep7qmz/hyNpgHQiNL/Vl23UTiI7KIeKIkkYQLfkk/img.png?width=635&amp;amp;height=411&amp;amp;face=0_0_635_411,https://scrap.kakaocdn.net/dn/davQn4/hyNqIbEVhN/RkVIvHeH0OymVQhPmfvRXK/img.png?width=655&amp;amp;height=235&amp;amp;face=0_0_655_235&quot;&gt;&lt;a href=&quot;https://synoptek.com/insights/it-blogs/greenfield-vs-brownfield-software-development/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://synoptek.com/insights/it-blogs/greenfield-vs-brownfield-software-development/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eFaIfs/hyNqxgTCKU/pPo9njrMQlVpY9wylw3tq0/img.png?width=300&amp;amp;height=194&amp;amp;face=0_0_300_194,https://scrap.kakaocdn.net/dn/ep7qmz/hyNpgHQiNL/Vl23UTiI7KIeKIkkYQLfkk/img.png?width=635&amp;amp;height=411&amp;amp;face=0_0_635_411,https://scrap.kakaocdn.net/dn/davQn4/hyNqIbEVhN/RkVIvHeH0OymVQhPmfvRXK/img.png?width=655&amp;amp;height=235&amp;amp;face=0_0_655_235');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Brownfield vs. Greenfield Development: What&amp;rsquo;s the Difference in Software? | Synoptek&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Greenfield and Brownfield are two major categories in software development. Explore their benefits, challenges, and how to choose between a Brownfield or Greenfield project.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;synoptek.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;How many services
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Too few
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Drawbacks of the monolithic architecture&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Too many - a.k.a Nano-service anti-pattern
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Runtime overhead&lt;/li&gt;
&lt;li&gt;Potential risk of excessive ntework hops&lt;/li&gt;
&lt;li&gt;Potentially difficult to understans system&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Anti-pattern : Distributed Monolith
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Remember the goal : Partition you application so that most chanes only impact a single service&lt;/li&gt;
&lt;li&gt;But if you get it wrong : Each change reqquires you to update and deploy all services&lt;/li&gt;
&lt;li&gt;Therefore : Common Closure Principle
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Components that change for the same reason should be packaged together&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Partitioning is something of an art
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;nginx introducion-to-microservice : &lt;a href=&quot;https://www.nginx.com/blog/introduction-to-microservices/?_bt=576183938381&amp;amp;_bk=&amp;amp;_bm=&amp;amp;_bn=g&amp;amp;_bg=136047553361&amp;amp;gclid=Cj0KCQiAjJOQBhCkARIsAEKMtO3_ldPBdSDBTKipGKcBnr8Q9cipfObRmWCNI1qyztITSi3SOwQxAeoaAg7SEALw_wcB&quot;&gt;https://www.nginx.com/blog/introduction-to-microservices/?_bt=576183938381&amp;amp;_bk=&amp;amp;_bm=&amp;amp;_bn=g&amp;amp;_bg=136047553361&amp;amp;gclid=Cj0KCQiAjJOQBhCkARIsAEKMtO3_ldPBdSDBTKipGKcBnr8Q9cipfObRmWCNI1qyztITSi3SOwQxAeoaAg7SEALw_wcB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1644882525212&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Introduction to Microservices | NGINX&quot; data-og-description=&quot;Microservices are currently getting a lot of attention. This blog post is the first in a 7-part series about designing, building, &amp;amp; deploying microservices.&quot; data-og-host=&quot;www.nginx.com&quot; data-og-source-url=&quot;https://www.nginx.com/blog/introduction-to-microservices/?_bt=576183938381&amp;amp;_bk=&amp;amp;_bm=&amp;amp;_bn=g&amp;amp;_bg=136047553361&amp;amp;gclid=Cj0KCQiAjJOQBhCkARIsAEKMtO3_ldPBdSDBTKipGKcBnr8Q9cipfObRmWCNI1qyztITSi3SOwQxAeoaAg7SEALw_wcB&quot; data-og-url=&quot;https://www.nginx.com/blog/introduction-to-microservices/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/oTaxm/hyNpj5SK9l/0GP0DHHfNn5CNETKzMmalk/img.png?width=500&amp;amp;height=301&amp;amp;face=0_0_500_301,https://scrap.kakaocdn.net/dn/bANGF8/hyNpeQ3Ng6/7YKCnEiNYs1ORu1CEn3BB0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000,https://scrap.kakaocdn.net/dn/haOBC/hyNqICZgvN/AQGrN6NW70OXVwVVyfSErk/img.png?width=815&amp;amp;height=832&amp;amp;face=0_0_815_832&quot;&gt;&lt;a href=&quot;https://www.nginx.com/blog/introduction-to-microservices/?_bt=576183938381&amp;amp;_bk=&amp;amp;_bm=&amp;amp;_bn=g&amp;amp;_bg=136047553361&amp;amp;gclid=Cj0KCQiAjJOQBhCkARIsAEKMtO3_ldPBdSDBTKipGKcBnr8Q9cipfObRmWCNI1qyztITSi3SOwQxAeoaAg7SEALw_wcB&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.nginx.com/blog/introduction-to-microservices/?_bt=576183938381&amp;amp;_bk=&amp;amp;_bm=&amp;amp;_bn=g&amp;amp;_bg=136047553361&amp;amp;gclid=Cj0KCQiAjJOQBhCkARIsAEKMtO3_ldPBdSDBTKipGKcBnr8Q9cipfObRmWCNI1qyztITSi3SOwQxAeoaAg7SEALw_wcB&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/oTaxm/hyNpj5SK9l/0GP0DHHfNn5CNETKzMmalk/img.png?width=500&amp;amp;height=301&amp;amp;face=0_0_500_301,https://scrap.kakaocdn.net/dn/bANGF8/hyNpeQ3Ng6/7YKCnEiNYs1ORu1CEn3BB0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000,https://scrap.kakaocdn.net/dn/haOBC/hyNqICZgvN/AQGrN6NW70OXVwVVyfSErk/img.png?width=815&amp;amp;height=832&amp;amp;face=0_0_815_832');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Introduction to Microservices | NGINX&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Microservices are currently getting a lot of attention. This blog post is the first in a 7-part series about designing, building, &amp;amp; deploying microservices.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.nginx.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 MSA에 필요한 피처들의 나열이다. 일반적으로 많이 알려진 내용이라 생각되어 별도의 코멘트는 하지 않았다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Deployment Patterns&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;multiple service per host
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Benefits
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Efficient resource utilization&lt;/li&gt;
&lt;li&gt;fast deployment&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Drawbacks
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Poor/Terrible isolation&lt;/li&gt;
&lt;li&gt;poor visibility&lt;/li&gt;
&lt;li&gt;difficult to limit resource utilization&lt;/li&gt;
&lt;li&gt;risk of dependency version conflicts&lt;/li&gt;
&lt;li&gt;poor encapsulation of implementation technology&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;service per vm
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Benefits
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Greate isolation&lt;/li&gt;
&lt;li&gt;Greate manageability&lt;/li&gt;
&lt;li&gt;Vm encapsulates&lt;/li&gt;
&lt;li&gt;Leverage Cloud infrastructure for Autoscaling&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Drawbacks
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Less efficient resource utilization&lt;/li&gt;
&lt;li&gt;slow deploymnet&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;service per container
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Benefits
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Greate isolation&lt;/li&gt;
&lt;li&gt;Greate manageability&lt;/li&gt;
&lt;li&gt;Container encapsulate implementation technology&lt;/li&gt;
&lt;li&gt;Efficient resource utilization&lt;/li&gt;
&lt;li&gt;Fast deployment&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;drawbacks
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;immature infrastructure for deploying containers&lt;/li&gt;
&lt;li&gt;Containers are not as secure as VMs&lt;/li&gt;
&lt;/ul&gt;
&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;Communication Patterns&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API Gateway
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MIsmatch between the fine-grained microservices and needs of the clients&lt;/li&gt;
&lt;li&gt;Different clients need different data&lt;/li&gt;
&lt;li&gt;LAN vs WAN vs Mobile network performance&lt;/li&gt;
&lt;li&gt;The number of service instances and their locations (host _ port) changes dynamically&lt;/li&gt;
&lt;li&gt;Partitioning into services can change over time and should be hidden from clients&lt;/li&gt;
&lt;li&gt;API
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SIngle entry point&lt;/li&gt;
&lt;li&gt;protocol trasnlate&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Benefits
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Insulates the clients from the partitioning&lt;/li&gt;
&lt;li&gt;Insulates the clients from the problem of discovery&lt;/li&gt;
&lt;li&gt;Provides the optimal api for each client&lt;/li&gt;
&lt;li&gt;Reduces the number of requests/roundtrips&lt;/li&gt;
&lt;li&gt;simplefies the client by moving logic for calling mulple services from the client to API gateway&lt;/li&gt;
&lt;li&gt;Gateway translates between we-unfriendly protocols&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Drawbacks
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Increased complexity&lt;/li&gt;
&lt;li&gt;Increased response time due to the additional network hop&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IPC
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;The need for IPC
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Monolith application
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Single process&lt;/li&gt;
&lt;li&gt;all invocations are local, language level calls&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Microservices
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Almost always separate processes&lt;/li&gt;
&lt;li&gt;Usually on separate machines&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;There&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Interaction styles
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;one to one
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;synchronous&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;one to many
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;synchronous
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;one way notification&lt;/li&gt;
&lt;li&gt;request/async response&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;asynchronous
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;publish/subscribe&lt;/li&gt;
&lt;li&gt;publish/async responses&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Messger formats
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Text
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;bulky slow to parse&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Bianry
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;protocol buffers, avro&lt;/li&gt;
&lt;li&gt;Compact, fast to parse&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Envolving APis
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Chagnes is inevitable&lt;/li&gt;
&lt;li&gt;minor, backwards compatible chagnes
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Robustness principle&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;major changes
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Verson number in url and mime types&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Messaging
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;benefits
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;decouples&lt;/li&gt;
&lt;li&gt;broker buffers messages&lt;/li&gt;
&lt;li&gt;variety of communcation patterns&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Drawbacks&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;additional complexity of message broker&lt;/li&gt;
&lt;li&gt;request/reply - style communication is more complex&lt;/li&gt;
&lt;li&gt;Client needs to discover location of message broker&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RPI(Rest, Thrift)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;benefits&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;simple and familar&lt;/li&gt;
&lt;li&gt;easy&lt;/li&gt;
&lt;li&gt;no need broker&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Drawbacks&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;only supports request/reply&lt;/li&gt;
&lt;li&gt;service must be available&lt;/li&gt;
&lt;li&gt;client needs to discover locations of service instances&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Rest
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://martinfowler.com/articles/richardsonMaturityModel.html&quot;&gt;https://martinfowler.com/articles/richardsonMaturityModel.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1644838441958&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Richardson Maturity Model&quot; data-og-description=&quot;Leonard Richardson's model for understanding a RESTful architecture as steps in a maturity model. Levels are (1) resources, (2) HTTP verbs and return codes, and (3) hypertext controls.&quot; data-og-host=&quot;martinfowler.com&quot; data-og-source-url=&quot;https://martinfowler.com/articles/richardsonMaturityModel.html&quot; data-og-url=&quot;https://martinfowler.com/articles/richardsonMaturityModel.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/boOBzT/hyNqCWRv5u/aYVPpmbU2BlwPLPBKqxnak/img.png?width=673&amp;amp;height=398&amp;amp;face=0_0_673_398&quot;&gt;&lt;a href=&quot;https://martinfowler.com/articles/richardsonMaturityModel.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://martinfowler.com/articles/richardsonMaturityModel.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/boOBzT/hyNqCWRv5u/aYVPpmbU2BlwPLPBKqxnak/img.png?width=673&amp;amp;height=398&amp;amp;face=0_0_673_398');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Richardson Maturity Model&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Leonard Richardson's model for understanding a RESTful architecture as steps in a maturity model. Levels are (1) resources, (2) HTTP verbs and return codes, and (3) hypertext controls.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;martinfowler.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Servie Discovery&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;client - side discovery by service registry
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;netflix eureka and ribbon&lt;/li&gt;
&lt;li&gt;b
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;flexible, application specific load balancing&lt;/li&gt;
&lt;li&gt;fewer network hos and moving parts compared to server-side discovery&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;d
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;couples the client to the service registry&lt;/li&gt;
&lt;li&gt;need implement client side discovery and load balancing&lt;/li&gt;
&lt;li&gt;service registry is yet another moving part to setup and operate - highly avaliable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;service-dise discovery with router by service registry&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;k8s ingress, aws elb&lt;/li&gt;
&lt;li&gt;b
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;simper client code&lt;/li&gt;
&lt;li&gt;buildt-in some cloud&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;d
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;limited to load banlcing algorithms&lt;/li&gt;
&lt;li&gt;more network hop&lt;/li&gt;
&lt;li&gt;router and servbice registry is yet another moving part to setup and operate highly avalable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Service Registry
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;EUreka&lt;/li&gt;
&lt;li&gt;zookeeper&lt;/li&gt;
&lt;li&gt;Consul&lt;/li&gt;
&lt;li&gt;Etcd&lt;/li&gt;
&lt;li&gt;Must be highly-avaliable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Service Registration
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;who does?&lt;/li&gt;
&lt;li&gt;Self registration
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;b
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;simple&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;d
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;couples the service to service registry&lt;/li&gt;
&lt;li&gt;implement registration logic&lt;/li&gt;
&lt;li&gt;servic emight lack the self awareness to unregister&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;3rd party registration&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;registar health check sergvice instance&lt;/li&gt;
&lt;li&gt;register heart-beat unregister&lt;/li&gt;
&lt;li&gt;example
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;aws autoscaling&lt;/li&gt;
&lt;li&gt;registrator&lt;/li&gt;
&lt;li&gt;container buddy&lt;/li&gt;
&lt;li&gt;Consul or Etcd&lt;/li&gt;
&lt;li&gt;k8s, eureka prana&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;b
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;simpler service&lt;/li&gt;
&lt;li&gt;registar can&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;d
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;registrar is often yet another hightly avaliable components&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>아빠악어.</author>
      <guid isPermaLink="true">https://dev-punxism.tistory.com/53</guid>
      <comments>https://dev-punxism.tistory.com/entry/Event-Driven-Microservices#entry53comment</comments>
      <pubDate>Mon, 14 Feb 2022 17:16:36 +0900</pubDate>
    </item>
    <item>
      <title>Constructors Must Be Code-Free</title>
      <link>https://dev-punxism.tistory.com/entry/Constructors-Must-Be-Code-Free</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;a href=&quot;https://www.yegor256.com/2015/05/07/ctors-must-be-code-free.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.yegor256.com/2015/05/07/ctors-must-be-code-free.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644732775531&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Constructors Must Be Code-Free&quot; data-og-description=&quot;It is a bad idea to put executing statements into class constructors because that leads to side effects and uncontrollable behavior.&quot; data-og-host=&quot;www.yegor256.com&quot; data-og-source-url=&quot;https://www.yegor256.com/2015/05/07/ctors-must-be-code-free.html&quot; data-og-url=&quot;https://www.yegor256.com/2015/05/07/ctors-must-be-code-free.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pByMj/hyNnW39yHb/m32aYzhtW0r69FwpaOktFk/img.jpg?width=1694&amp;amp;height=718&amp;amp;face=0_0_1694_718&quot;&gt;&lt;a href=&quot;https://www.yegor256.com/2015/05/07/ctors-must-be-code-free.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.yegor256.com/2015/05/07/ctors-must-be-code-free.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pByMj/hyNnW39yHb/m32aYzhtW0r69FwpaOktFk/img.jpg?width=1694&amp;amp;height=718&amp;amp;face=0_0_1694_718');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Constructors Must Be Code-Free&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;It is a bad idea to put executing statements into class constructors because that leads to side effects and uncontrollable behavior.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.yegor256.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자는 반드시 코드가 없어야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1644732815735&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public final class EnglishName implements Name {
  private final String name;
  public EnglishName(final CharSequence text) {
    this.name = text.toString().split(&quot; &quot;, 2)[0];
  }
  @Override
  public String first() {
    return this.name;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 문제는 무엇일까? 한번만 name이 가공되고 encapsulates 되어 있으니 좋지 않은가? first()가 여러 번 호출된다고 하여도 성능상의 문제도 없다&lt;/p&gt;
&lt;pre id=&quot;code_1644732898960&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public final class EnglishName implements Name {
  private final CharSequence text;
  public EnglishName(final CharSequence txt) {
    this.text = txt;
  }
  @Override
  public String first() {
    return this.text.toString().split(&quot;&quot;, 2)[0];
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 위 처럼 생성자의 코드를 없에고 first()에서 처리하는 것이 좋은 디자인이다.&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;하지만 선언적 프로그래밍에서는 모든 연산을 될 수 있는한 delay해야 한다.&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;pre id=&quot;code_1644733205835&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;final Name name = new EnglishName(
  new NameInPostgreSQL(/*...*/)
);
if (/* something goes wrong */) {
  throw new IllegalStateException(
    String.format(
      &quot;Hi, %s, we can't proceed with your application&quot;,
      name.first()
    )
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫번째 라인에서 우리는 단지 객체를 만들고 싶을 뿐인데 데이터베이스가 연결되고 fetch된다. 이것은 사이드 이펙트로 볼수 있다. 이 경우 어플리케이션은 더 느려질 것이다.&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;생성자에서 어떠한 연산을 가져가는 것은 bad practives이고 이것은 사이드이펙트 떄문에 피해야한다.&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;성능관점에서는 어떤가? name.first()가 다섯번 호출되면 String.split()가 다섯번 호출 될 것이다.&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;pre id=&quot;code_1644733476695&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public final class CachedName implements Name {
  private final Name origin;
  public CachedName(final Name name) {
    this.origin = name;
  }
  @Override
  @Cacheable(forever = true)
  public String first() {
    return this.origin.first();
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cacheable annotation을 사용했다. Guava Cache나 다른 캐시를 사용 할 수 있을 것이다. 하지만 CachedName을 mutable하게 만들지는 말라. 이것은 Objects Should Be Immutable에서 설명했다.&lt;/p&gt;
&lt;pre id=&quot;code_1644733581167&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;final Name name = new CachedName(
  new EnglishName(
    new NameInPostgreSQL(/*...*/)
  )
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것은 primitive한 예지만 아이디어를 얻길 바란다.&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;</description>
      <category>DESIGN</category>
      <category>OOP</category>
      <author>아빠악어.</author>
      <guid isPermaLink="true">https://dev-punxism.tistory.com/52</guid>
      <comments>https://dev-punxism.tistory.com/entry/Constructors-Must-Be-Code-Free#entry52comment</comments>
      <pubDate>Sun, 13 Feb 2022 15:29:08 +0900</pubDate>
    </item>
    <item>
      <title>Composable Decorators vs. Imperative Utility Methods</title>
      <link>https://dev-punxism.tistory.com/entry/Composable-Decorators-vs-Imperative-Utility-Methods</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.yegor256.com/2015/02/26/composable-decorators.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.yegor256.com/2015/02/26/composable-decorators.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644730487831&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Composable Decorators vs. Imperative Utility Methods&quot; data-og-description=&quot;A decorator pattern, while being the best instrument to keep objects highly cohesive, solid, and loosely coupled, is unfortunately not very popular in traditional Java programming.&quot; data-og-host=&quot;www.yegor256.com&quot; data-og-source-url=&quot;https://www.yegor256.com/2015/02/26/composable-decorators.html&quot; data-og-url=&quot;https://www.yegor256.com/2015/02/26/composable-decorators.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/yHplo/hyNnVYruXv/LK3XBMXpBbp9DkNyZKjFN1/img.jpg?width=1200&amp;amp;height=763&amp;amp;face=386_60_453_133&quot;&gt;&lt;a href=&quot;https://www.yegor256.com/2015/02/26/composable-decorators.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.yegor256.com/2015/02/26/composable-decorators.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/yHplo/hyNnVYruXv/LK3XBMXpBbp9DkNyZKjFN1/img.jpg?width=1200&amp;amp;height=763&amp;amp;face=386_60_453_133');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Composable Decorators vs. Imperative Utility Methods&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A decorator pattern, while being the best instrument to keep objects highly cohesive, solid, and loosely coupled, is unfortunately not very popular in traditional Java programming.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.yegor256.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;span style=&quot;color: #000000;&quot;&gt;composable decorators라는 이름이 흥미롭다. decorators들을 composable로 사용 할 수 있게 하는 패턴이다. imperative utility methods는 절차지향적 프로그래밍이라고 보면 된다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;해당 링크의 아래 예제에서 PrintableText는 Text가 어디서 왔는지 신경 쓰지 않아도 된다는 점, 신경 쓰지 않는다는 것은 곳 encapsulated가 잘되어 있다는 점에서 좋은 패턴이라고 한다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1644730647881&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;final Text text = new PrintableText(
  new TextInFile(new File(&quot;/tmp/a.txt&quot;))
);
String content = text.read();&lt;/code&gt;&lt;/pre&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;span style=&quot;color: #000000;&quot;&gt;그리고 아래와 같은 형태로 decorators들을 composable 할 수 있는 방법을 설명해주고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1644730731072&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;final Text text = new AllCapsText(
  new TrimmedText(
    new PrintableText(
      new TextInFile(new File(&quot;/tmp/a.txt&quot;))
    )
  )
);
String content = text.read();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 객체가 생성되어도 read()가 호출되기 전까지 아무런 오퍼레이션을 하지 않는다는 점에서 절차지향적 프로그래밍과는 다르다고 설명한다.&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;마지막으로 자바의 절차지향적인 String method()와 객체지향적 선언적 프로그래밍의 방법을 비교해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1644730846251&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;final String txt = &quot;hello, world!&quot;;
final String[] parts = txt.trim().toUpperCase().split(&quot; &quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vs&lt;/p&gt;
&lt;pre id=&quot;code_1644730859851&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;final String[] parts = new String.Split(
  new String.UpperCased(
    new String.Trimmed(&quot;hello, world!&quot;)
  )
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디자인 상으로는 아래가 좋다고 생각한다. 단일책임의 원칙에 따라 한 클래스는 하나의 책임을 맡을 수 있어 객체가 스스로를 가공하는 로직을 가지지 않아도 된다. 그럼에 따라 각각의 클래스가 하는 동작을 encapsulate할수 있다고 생각한다. 하지만 String 클래스의 메소드 사용도 괜찮지 않을까 생각한다. 이미 널리알려진 JDK라는 관점에서 encapsulate되었다고 볼 수 있다고 생각한다. 절차지향은 사람의 생각의 흐름대로 따라갈 수 있기 때문에 이해하고 사용하기 쉽다고 하지만 쉽다고 해서 꼭 좋은 디자인으로만은 볼 수 없다.&lt;/p&gt;</description>
      <category>DESIGN</category>
      <category>OOP</category>
      <author>아빠악어.</author>
      <guid isPermaLink="true">https://dev-punxism.tistory.com/51</guid>
      <comments>https://dev-punxism.tistory.com/entry/Composable-Decorators-vs-Imperative-Utility-Methods#entry51comment</comments>
      <pubDate>Sun, 13 Feb 2022 14:46:26 +0900</pubDate>
    </item>
    <item>
      <title>동시성 프로그래밍</title>
      <link>https://dev-punxism.tistory.com/entry/%EB%8F%99%EC%8B%9C%EC%84%B1-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</link>
      <description>&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;heap 영역에 코드를 두고 실행 할 thread가 코드를 가져가 실행하는 형태&lt;/li&gt;
&lt;li&gt;한 코드는 하나의 thread에서만 실행, 전용 thread를 만드는 것과는 차이가 있음&lt;/li&gt;
&lt;li&gt;java thread에 동시성 지원을 위한 자원을 효율적으로 사용&lt;/li&gt;
&lt;li&gt;코루틴 간에 메세지를 주고 받는 channel등 여러가지 개념이 존재&lt;/li&gt;
&lt;li&gt;보통 rxjava보다 가독성이 뛰어나다는 이유로 사용&lt;/li&gt;
&lt;li&gt;기본적으로 cpu core수와 같은 수의 thread를 가진다&lt;/li&gt;
&lt;li&gt;결국 thread 기반이긴 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;sync vs async, blocking vs nonblocking
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;sync, async는 task가 순차 진행 되느냐 또는 동시/병렬로 진행되는가의 문제&lt;/li&gt;
&lt;li&gt;blocking, nonblocking은 io가 block, nonblock인가&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@codemcd/Sync-VS-Async-Blocking-VS-Non-Blocking-sak6d01fhx&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@codemcd/Sync-VS-Async-Blocking-VS-Non-Blocking-sak6d01fhx&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1624084405705&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Sync VS Async, Blocking VS Non-Blocking&quot; data-og-description=&quot;1. Sync VS Async 먼저 Synchronous와 Asynchronous의 어원을 보자. Synchronous의 Syn는 together이란 뜻이고, chrono는 time이다. 따라서 Synchronous는 함께 시간을 맞춘다라는 뜻으로 해석된다. 반면에 A&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@codemcd/Sync-VS-Async-Blocking-VS-Non-Blocking-sak6d01fhx&quot; data-og-url=&quot;https://velog.io/@codemcd/Sync-VS-Async-Blocking-VS-Non-Blocking-sak6d01fhx&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hrOzg/hyKCIyV4IO/Qj8iWTs8AJWBj9wpmt49G1/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500&quot;&gt;&lt;a href=&quot;https://velog.io/@codemcd/Sync-VS-Async-Blocking-VS-Non-Blocking-sak6d01fhx&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@codemcd/Sync-VS-Async-Blocking-VS-Non-Blocking-sak6d01fhx&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hrOzg/hyKCIyV4IO/Qj8iWTs8AJWBj9wpmt49G1/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Sync VS Async, Blocking VS Non-Blocking&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. Sync VS Async 먼저 Synchronous와 Asynchronous의 어원을 보자. Synchronous의 Syn는 together이란 뜻이고, chrono는 time이다. 따라서 Synchronous는 함께 시간을 맞춘다라는 뜻으로 해석된다. 반면에 A&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>인터뷰</category>
      <author>아빠악어.</author>
      <guid isPermaLink="true">https://dev-punxism.tistory.com/50</guid>
      <comments>https://dev-punxism.tistory.com/entry/%EB%8F%99%EC%8B%9C%EC%84%B1-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D#entry50comment</comments>
      <pubDate>Sat, 19 Jun 2021 15:33:52 +0900</pubDate>
    </item>
  </channel>
</rss>