<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>매일 꾸준히, 더 깊이</title>
    <link>https://engineer-mole.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sat, 27 Jun 2026 07:06:49 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>개발자 두더지</managingEditor>
    <image>
      <title>매일 꾸준히, 더 깊이</title>
      <url>https://tistory1.daumcdn.net/tistory/3863241/attach/d621edb1058e4226b5f41e4ee0407788</url>
      <link>https://engineer-mole.tistory.com</link>
    </image>
    <item>
      <title>해외에서 방송대 지원하기</title>
      <link>https://engineer-mole.tistory.com/463</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;이번에 방송대 경영학과에 지원했다. 나는 이미 방송대 컴퓨터 공학과를 2020년에 한 번 졸업했지만, 경영학과의 교과 과목에 마케팅론, 소비자행동론, e-비즈니스등 내가 최근에 배우고 싶은 내용들이 있어서 2026년 2학기 3학년 편입학 지원을 결심했다. 2020년과 달리 나는 현재 일본에 있으므로 일본에서 지원을 했는데, 관련 내용 기억으로 남기기 위해 이 글을 작성하고자한다.&amp;nbsp; &amp;nbsp;&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;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;내가 졸업했던 2020년까지만해도 학부과정의 경우 해외거주자는 지원이 불가했다. 반드시 한 학기에 몇 번 출석을 해야하는 룰이 존재했고 시험도 오프라인으로 진행했기 때문이다.&amp;nbsp; 찾아보니 2024년부터 실습이 필요한 학부를 제외한 약 20개 학부에 지원이 가능해졌다고 한다 (사회복지학과, 식품영양학과, 유아교육과는 입학 제한) . 그리고 해외 거주자의 경우 모든 학사 운영을 온라인으로 받게 된다고 한다.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;275&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQNGxE/dJMcabrbXT9/eKxRVAfIynPFvhgjJR5i9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQNGxE/dJMcabrbXT9/eKxRVAfIynPFvhgjJR5i9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQNGxE/dJMcabrbXT9/eKxRVAfIynPFvhgjJR5i9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQNGxE%2FdJMcabrbXT9%2FeKxRVAfIynPFvhgjJR5i9k%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;591&quot; height=&quot;275&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;275&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;아무튼 &lt;a href=&quot;https://admission.knou.ac.kr/admission/index.do&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;방송대학교 입학안내&lt;/a&gt; 페이지에 액세스하면 해외거주용 모집요강과 입학지원 가이드가 존재하며 먼저 모집요강을 &amp;nbsp;PDF를 확인하여 본인에게 해당하는 내용을 참고하면된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q1OZo/dJMcahkGSSk/6WLftC3h4kOqFkCu2ZFkdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q1OZo/dJMcahkGSSk/6WLftC3h4kOqFkCu2ZFkdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q1OZo/dJMcahkGSSk/6WLftC3h4kOqFkCu2ZFkdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq1OZo%2FdJMcahkGSSk%2F6WLftC3h4kOqFkCu2ZFkdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;445&quot; height=&quot;242&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;242&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;확인 해 본 결과 나의 경우, 즉 방송대 졸업자(방송대 학적 보유자) + 해외거주자의 편입학으로 필요한 서류는 출입국사실증명서뿐이었다. 다른 유형 및 신입학에 대해서는 앞서 말했듯 모집요강 파일에 친절하게 설명되어 있으니 관련 내용을 참고하면 된다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;모집요강을 통해 요건과 제출에 필요한 내용을 확인을 마쳤다면, 입학지원 가이드을 보고 어떻게 지원하면 되는지 확인하면 된다. 지원시의 주의사항은 다음과 같다. 지원시에 전형료는 지불해야하며 가격은 15,000원이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1095&quot; data-origin-height=&quot;523&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bksRDZ/dJMcahdS4sJ/pDEPzlzCsZ3uVmz0GnaEe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bksRDZ/dJMcahdS4sJ/pDEPzlzCsZ3uVmz0GnaEe0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bksRDZ/dJMcahdS4sJ/pDEPzlzCsZ3uVmz0GnaEe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbksRDZ%2FdJMcahdS4sJ%2FpDEPzlzCsZ3uVmz0GnaEe0%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;1095&quot; height=&quot;523&quot; data-origin-width=&quot;1095&quot; data-origin-height=&quot;523&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp; 참고로 지원서의 일부 내용은 수정이 가능하다. 지원서 수정을 하기위해선 지원번호 + 비밀번호 혹은 지원시에 작성한 휴대폰 번호 + 비밀번호를 반드시 기억해두자. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;따라서 부속 서류의 파일이 준비되어 있지 않았다면, 일단 부속 서류 업로드외에 모든 내용을 작성해두고, 지원서 수정을 통해 추가 업로드할 수 있다.&amp;nbsp; 하지만 그럴 경우 다음과 같은 메일을 받게 된다. 그러므로 모든 서류를 미리 정부 24를 통해서 다운로드해두고 원활하게 지원할 수 있도록 하는 것이 좋을 것이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;78&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAoiQf/dJMcaiX3X3b/rfWJzy1dOciSUOd5Dqqg3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAoiQf/dJMcaiX3X3b/rfWJzy1dOciSUOd5Dqqg3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAoiQf/dJMcaiX3X3b/rfWJzy1dOciSUOd5Dqqg3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAoiQf%2FdJMcaiX3X3b%2FrfWJzy1dOciSUOd5Dqqg3K%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;805&quot; height=&quot;78&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;78&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp; 모든 지원서의 항목 작성을 완료하면 다음과 같은 메일을 받게 된다. 이로써 방송대 지원은 끝나게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;49&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7WSxl/dJMcabxUDAv/4Hm3HWSwU3z649rVuVkRC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7WSxl/dJMcabxUDAv/4Hm3HWSwU3z649rVuVkRC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7WSxl/dJMcabxUDAv/4Hm3HWSwU3z649rVuVkRC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7WSxl%2FdJMcabxUDAv%2F4Hm3HWSwU3z649rVuVkRC1%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;596&quot; height=&quot;49&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;49&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;지금 글을 작성하는 현재도 지원 가능한 기간이며&amp;nbsp;&lt;/span&gt;2026년 2학기 지원기간은 2026년 6월 8일(월) 9시부터 2026년 7월 7일(화) 20시까지이다. 그리고 합격자 발표일은 7월 27일 오전 9시 30분이다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>개인 기록/도전과 성장</category>
      <author>개발자 두더지</author>
      <guid isPermaLink="true">https://engineer-mole.tistory.com/463</guid>
      <comments>https://engineer-mole.tistory.com/463#entry463comment</comments>
      <pubDate>Fri, 26 Jun 2026 20:46:47 +0900</pubDate>
    </item>
    <item>
      <title>Trailblazing Women Summit Japan 2026 참가 후기</title>
      <link>https://engineer-mole.tistory.com/462</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;지난 6월 23일 화요일 Salesforce에서 진행한 &lt;a href=&quot;https://www.salesforce.com/jp/blog/trailblazing-women-summit-japan-2026/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Trailblazing Women Summit Japan 2026&lt;/a&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;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp; 이벤트 개최 장소는 Salesforce Tokyo Tower에서 개최되었으며 고쿄와 도쿄타워가 동시에 보이는 뷰가 훌륭한 장소에 위치해있다. 이번 Trailblazing Women Summit Japan 2026의 테마는 AI 에이전트와 함께 만들갈 새로운 리더십의 형태였으며, 이벤트 타이틀에서 알 수 있듯 각 계의 여성 리더들이 관련 테마에 대한 통찰을 공유하는 자리였다. 하지만 여성들만 참여가능한 행사는 아니다. 성별상관없이 참여 가능했으며, 실제로 남성분들도 4분의 1정도 계셨다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260625_204445174_01.jpg&quot; data-origin-width=&quot;4190&quot; data-origin-height=&quot;5587&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcBeM2/dJMcajo5Po1/WpVgw0MjgT2Roc8jZ13nUK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcBeM2/dJMcajo5Po1/WpVgw0MjgT2Roc8jZ13nUK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcBeM2/dJMcajo5Po1/WpVgw0MjgT2Roc8jZ13nUK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcBeM2%2FdJMcajo5Po1%2FWpVgw0MjgT2Roc8jZ13nUK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4190&quot; height=&quot;5587&quot; data-filename=&quot;KakaoTalk_20260625_204445174_01.jpg&quot; data-origin-width=&quot;4190&quot; data-origin-height=&quot;5587&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;Salesforce Tokyo Tower 1층에서 접수(이벤트 전날 사전등록 이메일이 도착하며, 메일의 register버튼을 누르고 폼을 작성하면 QR코드가 표시되며 그 QR코드를 이용해 접수) 를 하고 직원분들의 안내를 받아 엘리베이터를 타면 이벤트 장소인 22층에 도착, 입구에서 가방을 맡아주시고 가볍게 웰컴 드링크를 마시며, 발표 세션 시간까지 대기하게 되고, 발표 시간전 10분전에 착석 안내를 받은 후 발표 세션이 끝나면 다과와 함께 친목회가 진행되는 흐름이었다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;발표 세션은 크게 세 가지로 나뉘어져 있었지만, 모든 세션이 AI에 관련된 내용이라 하나의 큰 세션으로 봐도 무방한 느낌이 었다. 발표 등단자는 일본의 대형 여행사인 JTB의 역임, IT업계의 후지통( &lt;span style=&quot;color: #181818; text-align: start;&quot;&gt;富士通&lt;/span&gt; )의 역임, 이직 에이전트계의 PASONA 역임 그리고 구글 클라우드 일본 대표와 같이 일본에서도 대기업에 속하는 회사들의 여성 리더분들이었다.&amp;nbsp;&amp;nbsp;발표 내용에서 제일 기억에 남는 내용은 사용 AI 등장 후 아직 3년정도로 모두 스타트라인에 서 있으니 AI를 두려워하지말고 적극적으로 활용해보고 사용하자는 것과 이렇게 혼란스러운 시대에서도 나만의 북극성을 가지면 길을 잃지 않을 것이라는 격려였다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;하지만 내용에 대해 조금 아쉬웠던 것은 발표 내용들이 테마와 거리가 느껴졌다는 것이다.&amp;nbsp; 앞서 말했듯, 테마는 새로운 형태의 리더십였기에 그러한 내용을 기대했지만, 리더십보다는 AI 에이전트에 대한 두려움을 가질 필요가 없다라는 내용이 주가 되었다. 그렇지만 여성 리더들을 이렇게 한 자리에서 만날 수 있는 기회는 좀 처럼 없기 때문에 많은 업계에서 활약하는 여성 리더가 있다는 것을 직접 눈으로 보면서 앞으로 커리어에 대한 막연한 불안감을 줄었고, 동기부여가 됐다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;그외 인상깊었던 점은 수화 및 통역이 철저하게 준비되어 있었다는 점. 각 의자에 실시간으로 통역 내용을 들을 수 있도록 무선 통역기가 준비되어 있었고, 사이드 화면에도 통역 내용은 물론 수화를 띄어주고 있었다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260625_204445174_02.jpg&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3w5ip/dJMcacQ5Y7y/WH94NaNuPSYTPozecBAorK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3w5ip/dJMcacQ5Y7y/WH94NaNuPSYTPozecBAorK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3w5ip/dJMcacQ5Y7y/WH94NaNuPSYTPozecBAorK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3w5ip%2FdJMcacQ5Y7y%2FWH94NaNuPSYTPozecBAorK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4284&quot; height=&quot;5712&quot; data-filename=&quot;KakaoTalk_20260625_204445174_02.jpg&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260625_204445174_03.jpg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sJwAN/dJMcabLxH7D/jbd4XeZ2OHNRsoDJNGGct1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sJwAN/dJMcabLxH7D/jbd4XeZ2OHNRsoDJNGGct1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sJwAN/dJMcabLxH7D/jbd4XeZ2OHNRsoDJNGGct1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsJwAN%2FdJMcabLxH7D%2Fjbd4XeZ2OHNRsoDJNGGct1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3024&quot; height=&quot;4032&quot; data-filename=&quot;KakaoTalk_20260625_204445174_03.jpg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;발표 세션이 끝나고 네트워킹 행사가 진행되었는데, 스시와 다과, 술이 준비되어 있었으며, 경품 추첨 및 프로필 사진 촬영등 다양한 미니 이벤트도 함께 준비되어 있었다. 네트워킹이지만 누군가와 동행해서 같이 온 분들이 많아 새로운 분들과 대화를 나누는 느낌보다는 동행해서 오신 분과 대화를 나누는 느낌이 강했다. 나 또한 동행자가 있었기에 다행이었지&amp;nbsp; 혼자 왔었으면 굉장히 어색했을 것 같다는 생각이 들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;아무튼 좀 처럼 다른 기업의 오피스에 방문해볼 수 있는 기회가 없으며, 다양한 업계의 얘기를 들을 수 있는 것만으로도 충분히 유익한 이벤트였다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>IT/세미나,컨퍼런스등</category>
      <author>개발자 두더지</author>
      <guid isPermaLink="true">https://engineer-mole.tistory.com/462</guid>
      <comments>https://engineer-mole.tistory.com/462#entry462comment</comments>
      <pubDate>Thu, 25 Jun 2026 20:52:28 +0900</pubDate>
    </item>
    <item>
      <title>html의 iframe 태그</title>
      <link>https://engineer-mole.tistory.com/461</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;※&lt;/span&gt; 일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 의역, 직역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다.&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;iframe이란?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 웹 페이지 안에 별도의 페이지나 동영상, 지도 등의 외부 콘텐츠를 삽입하여 표시하기 위한 HTML 태그이다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;iframe 사용예&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;웹 페이지에서 외부 사이트의 정보를 원본 콘텐츠와 동일하게 표시하거나 여러 외부 사이트를 콘텐츠로 병렬로 표시할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예를 들어 SNS에서 콘텐츠에 대한 최신 정보를 발신하고 있다면, 웹 페이지에 해당 SNS의 정보를 포함하여 새 피드를 대체 할 수 있다. Instagram 같은 사진이 메인 SNS라면 카탈로그 대신 표시할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;iframe의 주의점&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;적절한 디자인의 어려움&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;iframe을 통해 읽어들인 web 페이지의 디자인을 변경하기 위해서, 읽어들인 곳의 정보를 수정하거나 설치한 페이지에 JavaScript을 설정해야하는 경우가 많다.&amp;nbsp;또한 로드한 정보가 표시할 수 있는 범위보다 크면 불편한 사이트가 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;SEO의 관점에서 역효과 가능성이 존재&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; &amp;nbsp;iframe을 이용했다고 해서 SEO의 순쉬 상승으로 연결되지 않는다. 오히려 떨어지는 경우도 존재한다. 그 이유는 사용자가 사용하는 브라우저나 환경에 의해 디자인이 무너지면 페이지가 인식되지 않는 경우가 발생하기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;또한 &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;원래 iframe은 head 태그 안에 작성하는 것이 권장되지 않는 태그이다. 태그를 적절히 기재하지 않으면 로딩 시점이 달라져 SEO 평가에 큰 영향을 미칠 수 있다 예를 들어 title이나 meta description 앞에 iframe 삽입하면, 로드된 페이지의 정보를 전혀 다른 것으로 구글에 전달할 가능성이다. 실수로라도 head 태그 안에 삽입하지 않도록 주의해야한다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;iframe 태그 사용법&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1780228188524&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;iframe&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;iframe 태그의 사용법은 위와 같다. 기본 속성은 scr나 srcdoc이다. srcdoc의 경우 특정 url이 아닌 파일 경로를 지정할 때 사용한다. 주로 sandbox라는 속성과 함께 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;scr와 srcdoc가 둘 다 사용되는 경우,&amp;nbsp; &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;웹 페이지를 여는 브라우저가 srcdoc 속성과 일치하지 않으면 src 속성에 설명 된 URL이 대체로 표시되게 된다.&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;또한 iframe 속성에는 HTML4.01에서 HTML5로 전환하면서 폐지&amp;middot;추가된 속성이 있기 때문에 사용시에 주의해야할 속성이 존재한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&amp;nbsp;인라인 프레임의 크기 변경&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다음 요소를 입력하여 다른 웹 페이지를 표시하는 프레임의 크기를 조정할 수 있습다&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;width 속성&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1780228927317&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;iframe src=&amp;rdquo;&amp;rdquo; width=&amp;rdquo;&amp;rdquo;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;프레임의 가로 폭을 지정한다. 속성 값에 숫자 또는 %를 입력한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;height 속성&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1780228938733&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;iframe src=&amp;rdquo;&amp;rdquo; height=&amp;rdquo;&amp;rdquo;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;프레임의 높이를 지정한다. 속성 값에 숫자 또는 %를 입력한다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;기타 속성 지정&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;프레임 크기 이외의 속성은 다음과 같다&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;name 속성&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1780228956588&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;iframe src=&amp;rdquo;&amp;rdquo; name=&amp;rdquo;&amp;rdquo;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이름을 지정할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;loading 속성&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1780228968174&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;iframe src=&amp;rdquo;&amp;rdquo; loading=&amp;rdquo;&amp;rdquo;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;브라우저에 대해서, 프레임의 로드 방법을 지정하는 속성이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;속성치에는, 아래와 같은 것이 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;eager: 가시 뷰포트 외부에 있는지 여부에 관계없이 설치된 웹 페이지를 로드할 때 인라인 프레임의 내용을 로드 (기본값)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;lazy : 표시가 가능해지고 나서 인라인 프레임의 내용을 로드하는 설정&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;보안 대책으로 할 수 있는 작업 제한&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;HTML5 이후, 악성코드에 의한 바이러스 감염 등에 대한 대책으로서, 송신하는 데이터에 제한을 추가해, 로드처의 JavaScript등을 원칙 작동시키지 않게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;referrerpolicy 속성&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1780228978449&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;iframe src=&amp;rdquo;&amp;rdquo; referrerpolicy=&amp;rdquo;&amp;rdquo;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;설치한 Web 페이지의 정보에 대해, 로드처의 Web 페이지에 송신하는 데이터를 지정하는 속성이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;속성으로 설정할 수 있는 것들로는 다음과 같은 것이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;no-referrer-when-downgrade : RSSL / TLS를 사용하여 HTTPS로 시작하는 로딩 대상 만 설치된 웹 페이지의 정보를 송신 (기본값)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;no-referrer: 설치한 웹페이지의 정보를 전송하지 않음.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;origin: 설치한 웹 페이지의 정보 중 origin(스키마, 호스트 이름, 포트 번호)만 전송.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;same-origin: 동일한 &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;origin&lt;/span&gt; 에만 설치한 웹 페이지의 정보를 송신.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;origin-when-cross-origin: &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;origin&lt;/span&gt; 이 다른 로딩에 대해서는 설치한 웹 페이지의 정보 중 &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;origin&lt;/span&gt;만 전송. 동일한 &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;origin&lt;/span&gt;로드할 경우 전체 URL을 전송.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;strict-origin: 보안 수준이 높은 HTTPS로 시작하는 로드 대상에 &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;origin&lt;/span&gt;만 전송. 로드 대상의 안전성이 설치된 웹페이지보다 뒤떨어지는 경우는 송신하지 않음.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;strict-origin-when-cross-origin: &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;origin&lt;/span&gt;이 다르고 보안 수준이 높은 HTTPS로 시작하는 로드 대상으로 &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;origin&lt;/span&gt;만 송신. 동일한 &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;origin&lt;/span&gt;을 로드할 경우 전체 URL을 전송.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;sandbox 속성&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1780228989014&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;iframe src=&amp;rdquo;&amp;rdquo; sandbox=&amp;rdquo;&amp;rdquo;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;로드 대상의 웹 페이지가 할 수 있는 것에 제한을 추가해, 보안 높이는 속성이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;sandbox 자체의 기능은 JavaScript를 움직이지 않게 하거나 API와의 소통을 저지하는 것이지만, 속성의 값과 조합하는 것으로, 지정한 내용의 움직임을 허용하는 효과가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;속성 값은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;allow-downloads: 사용자의 조작에 의한 다운로드가 가능.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;allow-downloads-without-user-activation: 사용자 작업 없이 다운로드가 발생하도록 허용.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;allow-same-origin: 로드할 문서를 설치한 페이지의 문서와 동일한 &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;origin &lt;/span&gt;문서로 사용할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;allow-forms: 로드 대상이 양식을 제출하도록 허용하고 정보를 제출할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;allow-popups: 로드할 팝업을 표시할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;allow-scripts: 로드 대상이 자바스크립트(팝업 제외)를 실행할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;allow-modals: 모달 창을 연다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;allow-orientation-lock: 화면 방향을 lock할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;allow-pointer-lock: Pointer Lock API(en-US)를 사용할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;allow-presentation: 프레젠테이션 세션(en-US)을 시작할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;덧붙여 지금까지 소개한 각각의 속성은, 많은 경우에서 다음와 같이 조합해 사용되고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1780229008100&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;iframe src=&amp;rdquo;&amp;rdquo; width=&amp;rdquo;&amp;rdquo; height=&amp;rdquo;&amp;rdquo; sandbox=&amp;rdquo;allow-〇〇&amp;rdquo;&amp;gt;&amp;lt;/iframe&amp;gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://www.geo-code.co.jp/webdev/mag/iframe/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.geo-code.co.jp/webdev/mag/iframe/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>IT/WEB</category>
      <author>개발자 두더지</author>
      <guid isPermaLink="true">https://engineer-mole.tistory.com/461</guid>
      <comments>https://engineer-mole.tistory.com/461#entry461comment</comments>
      <pubDate>Sun, 31 May 2026 21:03:45 +0900</pubDate>
    </item>
    <item>
      <title>Claude 101</title>
      <link>https://engineer-mole.tistory.com/460</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;Anthropic Academy에서 제공하는 무료 강좌인 Claude 101&amp;nbsp; 코스 중 필요한 내용을 요약한 글입니다. 참고로 아래에서 직접 무료로 내용을 확인 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://anthropic.skilljar.com/claude-101&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://anthropic.skilljar.com/claude-101&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1778918204639&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;skilljar:online_course&quot; data-og-title=&quot;Claude 101&quot; data-og-description=&quot;Learn how to use Claude for everyday work tasks, understand core features, and explore resources for more advanced learning on other topics.&quot; data-og-host=&quot;anthropic.skilljar.com&quot; data-og-source-url=&quot;https://anthropic.skilljar.com/claude-101&quot; data-og-url=&quot;https://anthropic.skilljar.com/claude-101&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dGRn22/dJMb8WMuPFQ/dY8HKxeNKv4hBKoxZ8SV3K/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500,https://scrap.kakaocdn.net/dn/mkwOU/dJMb8XkkCKC/Je4hPq5UMvdp3mHovrqT80/img.png?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260,https://scrap.kakaocdn.net/dn/biEjoy/dJMb8UHUpS2/kafZoCtoPmoewfkMpzZEZ1/img.png?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260&quot;&gt;&lt;a href=&quot;https://anthropic.skilljar.com/claude-101&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://anthropic.skilljar.com/claude-101&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dGRn22/dJMb8WMuPFQ/dY8HKxeNKv4hBKoxZ8SV3K/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500,https://scrap.kakaocdn.net/dn/mkwOU/dJMb8XkkCKC/Je4hPq5UMvdp3mHovrqT80/img.png?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260,https://scrap.kakaocdn.net/dn/biEjoy/dJMb8UHUpS2/kafZoCtoPmoewfkMpzZEZ1/img.png?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260');&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;Claude 101&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Learn how to use Claude for everyday work tasks, understand core features, and explore resources for more advanced learning on other topics.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;anthropic.skilljar.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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Meet Claude&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;프롬프트 사용시 클로드에게 전달하면 좋은 요소&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. 상황 설정 : 당신의 역할과 목표, 클로드가 알아야할 업무 관련 배경 정보&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2. 과제 정의 : 클로드에게 시키고 싶은 행동&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;3. 규칙 명시 : 출력 결과의 어조나 스타일, 예시 자료&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;흔히 발생하는 문제점과 해결법&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 102px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문제&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그 문제가 일어난 원인&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;해결&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;답변이 너무 일반적인 경우&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;프롬프트에 충분한 맥락이 포함되어 있지 않음&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;대상, 역할 또는 제약 조건에 대한 세부 정보를 추가 기재&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;답변이 너무 길거나 짧은 경우&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클로드가 적절한 길이를 추측해서 출력&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;구체적으로 답변의 양을 지정&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;답변이 원하는 형식이 아닌 경우&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클로드가 원하는 바는 이해했지만 그것을 어떻게 출력할지는 이해하지 못함&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;형식의 예시를 제공하거나 구조를 더욱 명확하게 설명&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;틀린 정보를 출력한 경우&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클로드는 때때로 그럴듯한 잘못된 정보를 제공&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;중요도가 높은 업무의 경우 클로드에게 출처를 제시해달라거나 신뢰 수준을 표시하도록 요청 혹은 웹 검색 기능을 활용하여 최신 정보에 근거한 답변을 제공하도록 요청&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;적절하지 못한 어조로 답변을 출력하는 경우&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클로드는 기본적으로 친절하고 전문적인 태도로 답변하지만 필요에 맞지 않을 수 있음&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;원하는 어조를 설명. 예를 들어, 대화체로 출력해주세요 등&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;클로드의 세 가지 모드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;채팅&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코워킹&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;최적화 대상&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;빠른 의견 교환, 아이디어 탐색, 반복적인 초안 작성, 신속한 답변이 필요한 경우, 대화를 통한 학습&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;복잡하거나 지속적인 작업, 연구, 분석, 파일 정리, 문서 작성 및 결과물 제작&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;소프트 웨어 개발 : 코드 작성, 테스트, 실행 및 배포&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;특징&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;빠른 입력, 받아쓰기&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;로컬 폴더, 플러그인, 서브에이전트, 예정된 작업등에 활용&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;질문/코드/계획 모드, 코드의 차이점 비교, git 통합, 로컬 및 원격 환경&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도구 및 확장 프로그램&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: left; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; Connectors, Skills, Claude in Chrome &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: left; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; Connectors (local and remote), Skills, Claude in Chrome, Plugins, Computer Use &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: left; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; Connectors, Skills, Claude in Chrome, Plugins, Hooks &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Organizing your work and knowledge&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&quot;프로젝트&quot;의 소개&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. 개념 : 프로젝트는 자체 메모리, 채팅 기록, 지식 기반 및 사용자 지정 지침을 갖춘 독립적인 작업 공간으로 특정 작업을 위한 전용 환경이라고 생각하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2. 특징 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2-1. 한 프로젝트에 관련 정보를 업로드하면 그 프로젝트 내의 모든 채팅에서 그 문서를 참조하기 때문에 높은 이해도를 가지게 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2-2. 프로젝트 지침( Project instructions guide ) : 프로젝트내에서 클로드의 행동을 정할 수 있다. 어조, 전문성 수준, 응답 방식 등을 지정할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2-3. Claude for Work : 프로젝트 단위로 공유가 가능하므로 팀원들과 한 프로젝트에서 축적된 지식을 활용할 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2-4. 프로젝트는 참조할 지식을 저장하고, 특정 주제나 업무 영역을 중심으로 관련 대화를 정리할 수 있으므로 협업하는데에 이상적이다. 따라서 지속적인 작업을 진행할 때 유용하게 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;프로젝트에서 대규모 지식 기반을 처리하는 방법&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #141413; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 프로젝트는 RAG(Retrieval Augmented Generation)라는 프로세스를 통해 대용량 데이터를 자동으로 처리할 수 있도록 확장됩니다. 간단히 말해, 사용자가 어떤 파일을 참조해야 하는지 지정하지 않아도 Claude는 업로드된 문서에서 가장 관련성이 높은 부분을 자동으로 찾아 활용하여 답변하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;artifacts를 활용한 창작&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;artifacts란 클로드 대화창 옆에 별도의 창에서 생성하는 독립적인 대화형 결과물이다. &lt;span style=&quot;color: #141413; text-align: start;&quot;&gt;Claude는 콘텐츠가 특정 기준을 충족하면 자동으로 artifacts를를 생성한다.&amp;nbsp;&lt;/span&gt;&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&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;내용이 중요하고 독립적이며 15줄이 넘는 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;수정, 반복, 재사용할 가능성이 높은 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그 자체로 의미를 갖는 복잡한 내용인 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;나중에 참고하거나 사용하고 싶은 내용인 경우&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; artifacts의 유형은 다음과 같다&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&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문서 (마크다운, 일반 ​​텍스트, 워드 문서, PDF, 파워포인트, 엑셀 포함): 회의록, 보고서, 프로젝트 계획서, 블로그 게시물 등 내보내거나 편집을 계속해야 하는 텍스트 위주의 문서에 적합&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드 스니펫: 파이썬, 자바스크립트, C++ 등 다양한 프로그래밍 언어로 작성된 작동 가능한 코드. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;HTML 페이지: HTML, CSS, JavaScript가 모두 포함된 완벽한 웹 페이지를 하나의 파일로 제공. 랜딩 페이지, 양식, 인터랙티브 데모 또는 빠른 프로토타입 제작에 적합.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;SVG 이미지: 로고, 아이콘, 일러스트레이션 및 기타 시각적 요소에 사용되는 확장 가능한 벡터 그래픽. 이러한 이미지는 결과물 창에 직접 렌더링되므로 최종 결과물을 정확하게 확인 가능.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;머메이드 다이어그램: 순서도, 시퀀스 다이어그램, 간트 차트, 조직도 등 다양한 다이어그램을 생성 가능. 시각화하고 싶은 관계를 설명해 주시면 클로드가 사용자가 수정할 수 있는 다이어그램을 생성.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;React 컴포넌트: 계산기, 대시보드, 게임, 데이터 시각화 등 실제 기능을 갖춘 대화형 UI 요소. 단순한 목업이 아니라 실제 로직을 포함하고 사용자 입력에 반응.&lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Expanding Cluade's reach&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Skills&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. 개념 : 쿨로드가&amp;nbsp;특정&amp;nbsp;작업&amp;nbsp;수행&amp;nbsp;능력을&amp;nbsp;향상시키기&amp;nbsp;위해&amp;nbsp;동적으로&amp;nbsp;불러오는&amp;nbsp;지침,&amp;nbsp;스크립트&amp;nbsp;및&amp;nbsp;리소스&amp;nbsp;폴더를&amp;nbsp;일컫는다.&amp;nbsp;특정&amp;nbsp;작업을&amp;nbsp;반복적으로&amp;nbsp;완료하는&amp;nbsp;방법에&amp;nbsp;대해&amp;nbsp;기재한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2. 유형&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2-1. Anthropic&amp;nbsp;Skills:&amp;nbsp;Anthropic에서&amp;nbsp;개발&amp;nbsp;및&amp;nbsp;관리하며,&amp;nbsp;여기에는&amp;nbsp;Excel,&amp;nbsp;Word,&amp;nbsp;PowerPoint&amp;nbsp;및&amp;nbsp;PDF&amp;nbsp;파일에&amp;nbsp;대한&amp;nbsp;향상된&amp;nbsp;문서&amp;nbsp;작성&amp;nbsp;기능이&amp;nbsp;포함된다.&amp;nbsp;Anthropic&amp;nbsp;Skills는&amp;nbsp;모든&amp;nbsp;유료&amp;nbsp;사용자에게&amp;nbsp;제공되며,&amp;nbsp;Claude는&amp;nbsp;필요할&amp;nbsp;때&amp;nbsp;자동으로&amp;nbsp;이를&amp;nbsp;호출한다.&amp;nbsp;따라서&amp;nbsp;사용자가&amp;nbsp;별도로&amp;nbsp;설정할&amp;nbsp;필요가&amp;nbsp;없다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2-2. 사용자 지정 스킬 : 특정 워크플로 및 도메인별 작업을 위해 사용자 또는 조직에서 직접 생성하는 스킬이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;프로젝트 vs 스킬&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 136px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;프로젝트&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기술&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;목적&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클로드가 참고할 자료 저장소&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: left; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; Claude가 실행하는 프로세스를 정의 &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 34px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 34px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;적합한 사용처&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 34px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;장기적인 맥락, 참고 자료, 팀 협업&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 34px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;반복 워크플로우, 일관된 출력, 다단계 작업&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 34px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 34px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 34px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;연구 지원&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 34px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;프로레스 가이드라인, 블로그 게시물 작성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 34px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 34px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;영속성&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 34px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;프로젝트 내 모든 채팅방에서 정보 확인 가능&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 34px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;적용되는 지침&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Putting it all together&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;커넥터&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. 개념 : 유저가 매일 사용하는 도구, 데이터 및 컨텍스트에 대한 접근 권한을 부여하기 도구로 유저의 정보를 클로드가 직접 활용.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2. 유형&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2-1. 웹 커넥터&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클로드를 구글 드라이브, 노션, 슬랙와 같은 클라우드 서비스와 연결하는 것&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2-2. 데스크톱 확장 프로그램&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클로드 데스크톱 앱을 통해 로컬에서 실행. 클로드가 로컬 파일과 기본 애플리케이션에 접근하도록 하는 것.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;엔터프라이즈 서치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;사이드바에 &quot;{조직 이름}에게 질문하기&quot;라는 전용 업션을 추가하여 회사 내 여러 도구와 데이터 소스로 부터 지식을 찾아 종합적으로 정리하는 데 특화된 기능.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;리서치 모드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. 개념 :&amp;nbsp;대화형 도우미에서 조사자로 바꾸는 고급 기능. 질문에 답하는데에 그치지 않고 웹과 연결된 여러 플랫폼에서 수집한 정보를 종합해 다양한 관점에서 질문을 탐구하는 모드.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2. 추천 활용법:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2-1. 시장 분석 및 경쟁자 조사&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2-2. 팀 워크숍이나 제품 출시와 같은 복잡한 프로젝트 계획&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2-3. 이메일, 캘린더, 문서의 정보 종합&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2-4. 다양한 출처를 활용한 기술 문서 작성&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2-5. 최신이며 검증된 정보가 필요한 브리핑 준비&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;3. 주의: 웹 검색을 활성화시키지 않으면 리서치모드를 사용할 수 없음.&lt;/span&gt;&lt;/p&gt;</description>
      <category>IT/코딩툴</category>
      <author>개발자 두더지</author>
      <guid isPermaLink="true">https://engineer-mole.tistory.com/460</guid>
      <comments>https://engineer-mole.tistory.com/460#entry460comment</comments>
      <pubDate>Sat, 16 May 2026 20:50:56 +0900</pubDate>
    </item>
    <item>
      <title>Domain 이벤트 (도메인 이벤트)</title>
      <link>https://engineer-mole.tistory.com/459</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;시작하기에 앞서&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;2&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;도메인 이벤트는 도메인 중심 설계에서 사용되는 설계 패턴 중 하나로, 도메인 이벤트 자체는 단순한 개념이지만, 여러 문맥에 사용되기 때문에, 좀처럼 이해가 어려운 부분이 있다. 따라서 이번 기회를 통해 관련 내용을 정리하고자 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;2&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;2&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Domain 이벤트란?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;29&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;이벤트는 &quot;과거에 발생한 사건&quot;이며 도메인 이벤트는 &quot;비즈니스 도메인에서 발생한 중요한 사건을 나타내는 메시지&quot;이다(예: 주문이 할당되었으나 주문이 취소됨). 도메인 이벤트는 시스템의 상태 변경(=집약 상태의 변화)을 나타내며, 일반적으로 집약이 도메인 이벤트의 출처가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1774&quot; data-origin-height=&quot;471&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tzbeH/dJMcahDRONq/aFbTt0d5IOKWKxKhWEN0e1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tzbeH/dJMcahDRONq/aFbTt0d5IOKWKxKhWEN0e1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tzbeH/dJMcahDRONq/aFbTt0d5IOKWKxKhWEN0e1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtzbeH%2FdJMcahDRONq%2FaFbTt0d5IOKWKxKhWEN0e1%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;1774&quot; height=&quot;471&quot; data-origin-width=&quot;1774&quot; data-origin-height=&quot;471&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;용도&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;도메인 이벤트는 주로 다음과 같은 목적으로 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 이벤트 발생을 기점으로, 다른 처리에 대한 트리거가 된다.&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;도메인 이벤트는 시스템의 다른 부분간 연동을 위해 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DEHmA/dJMcaaksSnW/VMPSWStYHzrTg9pqF8ImP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DEHmA/dJMcaaksSnW/VMPSWStYHzrTg9pqF8ImP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DEHmA/dJMcaaksSnW/VMPSWStYHzrTg9pqF8ImP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDEHmA%2FdJMcaaksSnW%2FVMPSWStYHzrTg9pqF8ImP1%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;602&quot; height=&quot;284&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;52&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 요구사항으로 '...하고 싶은 경우...'라는 문구가 나오면 도메인 이벤트의 사용에 적합한 부분일지도 모른다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;54&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;54&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;여러 집약간의 무결성을 가져옵니다(예: 주문이 취소된 경우 재고 반환)&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;55&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;외부 시스템과의 연계(예: 신규 예약이 들어오면 메일 송신, 외부 API 호출)&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;56&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;로그 기록&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;57&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;etc.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;60&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;장점은 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;62&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;62&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트의 발생원이 되는 처리와 관련되어 연동되는 처리를 분리할 수 있다(관심의 분리)&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;63&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기존 코드를 변경하지 않고 이벤트에 반응하는 새로운 처리를 추가할 수 있다(확장성).&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;65&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 포스트에서는 이 내용을 중심으로 구현 방법을 설명하려고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;65&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;2.-%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E8%A8%98%E9%8C%B2%E3%81%97%E6%B4%BB%E7%94%A8%E3%81%99%E3%82%8B&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;67&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 도메인 이벤트 기록 및 활용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;69&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트를 지속하고 축적함으로써 현재 상태에 이르는 과정을 추적할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;71&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;71&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;감사 추적&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;72&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;조사 및 디버깅&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;73&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;사용자 활동 분석&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;3.-%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E6%83%85%E5%A0%B1%E6%BA%90%E3%81%A8%E3%81%97%E3%81%9F%E7%8A%B6%E6%85%8B%E7%AE%A1%E7%90%86%EF%BC%88%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%BD%E3%83%BC%E3%82%B7%E3%83%B3%E3%82%B0%EF%BC%89&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;75&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 이벤트를 정보원으로 한 상태 관리(이벤트 소싱)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;77&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;이벤트 소싱&lt;/b&gt;&amp;nbsp;은 시스템 상태를 이벤트의 연속으로 저장하는 설계 패턴이다. 도메인 개체의 상태를 직접 저장(=상태 소싱)하는 대신 발생한 모든 이벤트를 순차적으로 기록하고 해당 이벤트를 재생하여 현재 상태를 다시 작성한다. 이러한 이벤트 소싱은 종종 CQRS와 함께 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;77&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;4.-%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A8%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%AE%E8%B2%AC%E5%8B%99%E5%88%86%E9%9B%A2%EF%BC%88cqrs%EF%BC%89&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;81&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. 명령 및 쿼리 책임 분리(CQRS)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;83&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;CQRS(Command Query Responsibility Segregation)&lt;/b&gt;&amp;nbsp;는 명령(쓰기 작업)과 쿼리(읽기 작업)를 분리하는 아키텍처 패턴이다. 집약(명령 모델)에 대한 변경사항을 이벤트로 알리고, 이를 수신한 이벤트 핸들러가 읽기 전용 뷰(쿼리 모델)를 구축하여 쓰기 및 읽기 각각에 최적화된 모델 및 아키텍처 특성을 가질 수 있게 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;83&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;5.-%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E4%B8%AD%E5%BF%83%E3%81%A8%E3%81%97%E3%81%9F%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%81%AE%E5%88%86%E6%9E%90%E3%83%BB%E3%83%A2%E3%83%87%E3%83%AA%E3%83%B3%E3%82%B0%EF%BC%88%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%B9%E3%83%88%E3%83%BC%E3%83%9F%E3%83%B3%E3%82%B0%EF%BC%89&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;86&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;5. 이벤트를 중심으로 한 비즈니스 도메인 분석 및 모델링 (이벤트 스토밍)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;88&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;시스템 구현과 직접 관련이 있는 것은 아니지만 도메인 이벤트를 중심으로 비즈니스 도메인을 분석하는 기법으로&amp;nbsp;&lt;b&gt;이벤트 스토밍&lt;/b&gt;&amp;nbsp;이 있다. 이는 비즈니스 도메인에 대한 이해를 높이고 공유하고 모델링과 디자인에 활용하는 데 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;91&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트는 비즈니스 도메인에서 일어나는 중요한 결과이며 여기에서 거슬러 올라가 전체를 탐색해 나간다(이벤트 &amp;rarr; 이벤트를 일으킨 명령 &amp;rarr; 명령 실행 주체(액터, 정책) &amp;rarr; 액터가 의사결정을 위해 참조한 리드 모델).&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;91&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;91&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E6%89%B1%E3%81%86%E3%81%9F%E3%82%81%E3%81%AE%E5%AE%9F%E8%A3%85&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;94&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;도메인 이벤트를 처리하기 위한 구현&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;96&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트를 생성해, 바운디드 컨텍스트내에서 처리하기 위해서 필요한 구현을 소개하도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;98&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;98&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트 발생 ~ 소비는 동기화 혹은 비동기.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;99&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;일반적으로 도메인 이벤트는 발생한 바운디드 컨텍스트 내에서 소비.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;100&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;100&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문맥 밖에 통지하고 싶은 경우는, 공개용으로 변환&amp;middot;정형한 후에 ​​통지하는 것이 일반적.&lt;/span&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 도메인 이벤트 설계&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;104&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트는 집약에 대한 작업(명령)의 결과로 발생한다. 예를 들어, &quot;주문&quot;이라는 집약에 대한 &quot;취소&quot; 작업은 집약 상태를 취소됨으로 변경하고 &quot;주문이 취소됨&quot;이라는 도메인 이벤트를 발생시킨다. 우선은 도메인 이벤트를 설계, 구현해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774958360083&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/**「주문이 취소되었다」이벤트 */
data class OrderCancelled(
  // 일어난 일을 설명하기 위한 정보를 속성으로 가진다.
  val orderId: OrderId,
  val reason: String,
  val occurredAt: Instant,
  ...
) : DomainEvent&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;121&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;포인트:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;123&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;123&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;과거에 발생한 사건이기 때문에 과거형으로 명명(예: OrderCancelled, ItemShipped)&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;124&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;비즈니스 도메인 단어에서 어떤 일이 발생했는지 이름에 정확하게 반영&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;125&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;과거에 발생한 사건이기 때문에 이뮤터블&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;126&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트는 도메인 모델의 일부&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AB%E6%8C%81%E3%81%9F%E3%81%9B%E3%82%8B%E6%83%85%E5%A0%B1&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;128&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;도메인 이벤트에 제공하는 정보&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;130&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트에는 도메인에서 무슨 일이 일어났는지 설명하는 완전한 정보가 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;132&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;132&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트를 설명하는 데 필요한 모든 정보가 존재.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;133&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트가 암시적으로 의존하는 외부 정보 포함.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;134&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;134&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예를 들어, 세금 포함 가격을 계산하고 기록하는 이벤트라면, 그 계산에 사용한 소비세율의 스냅샷도 포함한다(장래 세율이 바뀌어도 계산 결과를 재현할 수 있도록)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;135&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그 외, 구독자가 필요로 하는 정보도 포함할 수도 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;136&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위의 내용을 충족시킨 후 필요한 최소한의 정보를 유지.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AB%E5%85%B1%E9%80%9A%E3%81%99%E3%82%8B%E6%83%85%E5%A0%B1&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;138&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;모든 도메인 이벤트에 공통된 정보&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;140&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;모든 도메인 이벤트에 공통적으로 가져야 하는 정보가 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;142&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;142&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;집약 ID (필수) ... 이벤트는 집약에서 발생하므로 집약 식별자를 가짐.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;143&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트 발생 시간 (필수) ... 과거의 이벤트이므로 발생 시간이 있음.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;144&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트 식별자 ... 비동기로 처리 할 때 이벤트 중복을 제외하는 데 유용함 (아래 참조).&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;145&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;집계 버전 ... 이벤트를 지속할 때 낙관적 배타적 제어를 수행하거나 이벤트 순서를 보장하는 데 사용함.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;147&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이러한 항목은 공통 인터페이스에 정의하는 것이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;147&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;147&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 도메인 이벤트 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;147&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;집약이 도메인 이벤트를 생성하고 발행하는 구현 방법으로 다음 세 가지 패턴이 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B31.-%E9%9B%86%E7%B4%84%E8%87%AA%E8%BA%AB%E3%81%8C-event-publisher-%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E7%99%BA%E8%A1%8C%E3%81%99%E3%82%8B&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;153&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;패턴 1. 집약 자체가 Event Publisher를 사용하여 도메인 이벤트를 발행&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;155&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;집약 자체가 도메인 이벤트를 발행한다. &lt;a style=&quot;color: #0f83fd;&quot; href=&quot;https://amzn.asia/d/0eV44aXJ&quot;&gt;실천 도메인 구동 설계&lt;/a&gt;&amp;nbsp;등에서 소개되고 있는 패턴이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774958592598&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Order {
  fun cancel(reason: String) {
    check(canCancel())
    // 집약의 상태를 변화시킴
    this.status = OrderStatus.CANCELLED
    this.cancelReason = reason

    // 이트를 생성하고 발행함
    val event = OrderCancelled(id, reason, ...)
    DomainEventPublisher.publish(event)
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;173&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;(여기서는&amp;nbsp;DomainEventPublisher이벤트를 받아 디스패치하는 부품으로 사용하고 있다. 구현에 대해서는 후술하도록 하겠다)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;175&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 패턴은 구현은 간단합니다만, 아래의 문제가 있기 때문에 남용해서는 안된다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;177&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;177&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;집약이 이벤트 발행 처리에 의존하기 때문에 안정성과 시험 가능성이 떨어짐&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;178&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;즉시 디스패치되므로 집약을 지속하기 전에 핸들러가 이벤트를 처리할 수 있음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B32.-%E9%9B%86%E7%B4%84%E3%81%8C%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E4%BF%9D%E6%8C%81%E3%81%97%E3%80%81%E5%BE%8C%E3%81%A7%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%97%E3%81%A6%E7%99%BA%E8%A1%8C%E3%81%99%E3%82%8B&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;180&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;패턴 2. 집약이 도메인 이벤트를 유지하고 나중에 검색하고 게시&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;182&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 패턴이 가장 자주 소개되는 패턴이다 (Jimmy Bogard의&amp;nbsp;&lt;a style=&quot;color: #0f83fd;&quot; href=&quot;https://lostechies.com/jimmybogard/2014/05/13/a-better-domain-events-pattern/&quot;&gt;A better domain events pattern&lt;/a&gt;&amp;nbsp;등).&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774958848234&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Order {
  // 집약내에서 발생한 미발행의 이벤트를 보유할 필드
  // 공통의 기저 클래스를 가지도록 해도 좋을 것이다
  private val events = mutableListOf&amp;lt;DomainEvent&amp;gt;()

  fun cancel(reason: String) {
    check(canCancel())
    this.status = OrderStatus.CANCELLED
    this.cancelReason = reason

    // 생성한 이벤트를 events에 추가
    // 이 시점에서는 이벤트는 디스패치되지 않는다
    val event = OrderCancelled(id, reason, ...)
    events.add(event)
  }

  fun events(): List&amp;lt;DomainEvent&amp;gt; { // 외부에서 꺼낼 수 있도록 해둠
    return events.toList()
  }
}

// Use case
fun cancelOrder(orderId: OrderId, reason: String) {
  val order = orderRepository.findById(orderId)
  order.cancel(reason)
  orderRepository.save(order)

  // 생성된 이벤트를 발행
  // 리포지터리의 구현 내에 이를 구현하는 사람들도 있다(리포지터리의 책임 범위 밖이지만)
  domainEventPublisher.publish(order.events())
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B33.-%E9%9B%86%E7%B4%84%E3%81%AE%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%8C%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E8%BF%94%E3%81%99&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;218&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;패턴 3. 집계 명령이 이벤트를 반환합니다.&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;220&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;집약에 대한 조작이 이벤트를 리턴하게 함으로써, 이벤트의 발행을 명시적으로 실시할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774958907522&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Order {
  fun cancel(reason: String): List&amp;lt;DomainEvent&amp;gt; {
    check(canCancel())
    this.status = OrderStatus.CANCELLED
    this.cancelReason = reason

    // 이벤트를 생성하고 반환
    val event = OrderCancelled(orderId, reason, ...)
    return listOf(event)
  }
}

// Use case
fun cancelOrder(orderId: OrderId, reason: String) {
  val order = orderRepository.findById(orderId)
  val events = order.cancel(reason)
  orderRepository.save(order)

  domainEventPublisher.publish(events) // 이벤트를 발행
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 이 패턴은 집약의 설계를 이뮤터블로 하는 경우에도 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774958938908&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Use case
fun cancelOrder(orderId: OrderId, reason: String) {
  val order = orderRepository.findById(orderId)
  val (cancelledOrder, events) = order.cancel(reason) // 변경 후의 집약과 이벤트를 반환
  orderRepository.save(cancelledOrder)

  domainEventPublisher.publish(events)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;3.-%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E5%87%A6%E7%90%86%E3%81%99%E3%82%8B&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;262&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 이벤트 처리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;264&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;DomainEventPublisher에서 발행된 이벤트를 구독하고 처리하는 구현 예를 살펴보자. 먼저 도메인 이벤트를 처리하기 위한 인터페이스로&amp;nbsp;DomainEventHandler정의한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774959023173&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface DomainEventHandler&amp;lt;T : DomainEvent&amp;gt; {
  fun eventType(): KClass&amp;lt;T&amp;gt; // 이 핸들러가 이벤트 형으로 반환
  fun handle(event: T) // 이벤트를 처리
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 다음에 이것을 구현한 클래스를 작성한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774959085971&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class SendEmailWhenOrderCancelledHandler : DomainEventHandler&amp;lt;OrderCancelled&amp;gt; {
  override fun eventType() = OrderCancelled::class
  override fun handle(event: OrderCancelled) {
    // 이벤트에 반응하여 행할 액션을 기재
    // 이벤트 핸들러는 어플리케이션 층의 주인이며, 리포지터나 서비스를 이용하는 것이 가능
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;287&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;명명은&amp;nbsp;&lt;a style=&quot;color: #0f83fd;&quot; href=&quot;https://learn.microsoft.com/ja-jp/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/domain-events-design-implementation&quot;&gt;도메인 이벤트: 디자인 및 구현 - .NET | Microsoft Learn&lt;/a&gt;&amp;nbsp;예제를 따른다. (&amp;nbsp;${무엇을 할것인가}When${무엇이일어났을때}Handler) 하나의 이벤트에 대해 수행하려는 여러 작업이 있는 경우 일반적으로 처리기를 여러 개 만든다. (단일 책임의 원칙, 개방 폐쇄의 원칙)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;287&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;4-1.-%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AE%E5%90%8C%E6%9C%9F%E7%9A%84%E3%81%AA%E3%83%87%E3%82%A3%E3%82%B9%E3%83%91%E3%83%83%E3%83%81&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;291&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4-1. 이벤트의 동기 디스패치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;293&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;마지막으로 발생한 이벤트를 핸들러에 디스패치하는&amp;nbsp;DomainEventPublisher구현한다. 이벤트의 디스패치를 ​​동기적으로 실시하는 경우와 비동기적으로 실시하는 경우가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;296&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;우선은 동기적인 디스패치의 구현 예는 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774959239378&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class DomainEventPublisher {
  // 이벤트 타입마다 핸들러를 보유한다
  private val handlers = mutableMapOf&amp;lt;KClass&amp;lt;out DomainEvent&amp;gt;, List&amp;lt;DomainEventHandler&amp;lt;out DomainEvent&amp;gt;&amp;gt;&amp;gt;()

  // 이벤트 핸들러를 등록한다
  fun subscribe(handler: DomainEventHandler&amp;lt;out DomainEvent&amp;gt;) {
    val eventType = handler.eventType()
    handlers[eventType] = handlers.getOrDefault(eventType, emptyList()) + handler
  }

  // 발생한 이벤트 타입에 따라 핸들러에 디스패치한다
  // 이벤트에 대응할 핸들러를 순서대로 동기적으로 호출한다
  fun publish(events: List&amp;lt;DomainEvent&amp;gt;) {
    events.forEach { event -&amp;gt;
      handlers[event::class]?.forEach { handler -&amp;gt;
        (handler as DomainEventHandler&amp;lt;DomainEvent&amp;gt;).handle(event)
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 이벤트 핸들러는 애플리케이션이 시작될 때 등록된다. DI 컨테이너를 사용하는 경우 DI 컨테이너에 등록된 모든 핸들러를 자동으로 등록하는 것이 편리하다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774959280584&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun registerDomainEventHandlers() { // 어플리케이션 기동시에 호출한다
  val handlers = applicationContext.getBeansOfType(DomainEventHandler::class.java) // Spring Framework の例
  handlers.values.forEach { handler -&amp;gt; domainEventPublisher.subscribe(handler) }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1670&quot; data-origin-height=&quot;923&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vupV9/dJMcahcOx07/1xnqklTCyvOnyoMP9mkcj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vupV9/dJMcahcOx07/1xnqklTCyvOnyoMP9mkcj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vupV9/dJMcahcOx07/1xnqklTCyvOnyoMP9mkcj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvupV9%2FdJMcahcOx07%2F1xnqklTCyvOnyoMP9mkcj0%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;1670&quot; height=&quot;923&quot; data-origin-width=&quot;1670&quot; data-origin-height=&quot;923&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;4-2.-%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AE%E9%9D%9E%E5%90%8C%E6%9C%9F%E7%9A%84%E3%81%AA%E3%83%87%E3%82%A3%E3%82%B9%E3%83%91%E3%83%83%E3%83%81&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;335&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4-2. 이벤트의 비동기 디스패치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;337&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;동일한 컨텍스트 (동일한 시스템) 내에서도 이벤트를 비동기적으로 처리하고 싶을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;339&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;339&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트를 소비하는 측의 처리를 기다리지 않기 때문에 응답성이 향상&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;340&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트를 소비하는 쪽이 다운되어도 처리를 계속할 수 있으므로 가용성이 향상&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;341&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;트랜잭션이 작아지고 데이터베이스 독점 제어 충돌이 삭감&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;343&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;한편, 이벤트가 확실하게 처리되도록(듯이) 하기 위해서는 복잡한 구현이 필요하게 된다 (이벤트 중복, 순서 보증, 오류 처리, 보상 조치 등)&lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;%E7%B5%90%E6%9E%9C%E6%95%B4%E5%90%88%E6%80%A7%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;346&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;결과 무결성 정보&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;348&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트를 비동기적으로 처리하면 이벤트가 발생한 후 이벤트 핸들러 측 처리가 완료될 때까지 시스템 상태에 일시적으로 일관성이 없는 상태가 발생한다 (예: 상품 구입 처리와 포인트 부여 처리가 비동기로 행해지는 경우, 구입했는데 포인트가 미부여 상태가 일시적으로 발생).&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;351&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이러한 일시적인 불일치를 허용하고 시간이 지남에 따라 결국 일관성을 담보하는 설계를&amp;nbsp;&lt;b&gt;결과 무결성&lt;/b&gt;이라고한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;참고로 반대되는 단어는&amp;nbsp;&lt;b&gt;트랜잭션 무결성&lt;/b&gt;&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&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;일관성 지연은 허용되지만 일관성 자체를 생략하는 것은 아니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;무결성이 취해질 때까지의 지연을 어느 정도 허용하는지는 비즈니스 요건에 따른다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;결과 무결성을 확실하게 담보하기 위한 구현은 꽤 어렵다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h3 id=&quot;outbox-%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-%2B-%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%83%90%E3%82%B9%E3%81%AB%E3%82%88%E3%82%8B%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E9%85%8D%E4%BF%A1&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;362&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Outbox 패턴 + 메시지 버스를 통한 이벤트 전달&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;364&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Producer - Consumer간을 결과 무결성으로 한다고 해도, 「이벤트의 발생원(=집약)의 상태의 영속화」와 「이벤트가 공개되는 것」은 확실히 정합할 필요가 있다. (한쪽만 성공하는 것은 안되기 때문)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;366&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 경우 Outbox 패턴을 사용하는 것이 일반적이다. (다른 방법으로는 도메인 이벤트만을 영속화하고 집약은 이벤트에서 재구성하는 방법도 있다)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;369&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Outbox 패턴을 사용하면 집계를 저장하는 것과 동일한 트랜잭션에서 알림을 받고 싶은 이벤트를 일시적으로 유지하고 다른 프로세스가 이벤트를 가져와서 알리게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6wIg0/dJMcaiQh4l3/QuBarGXYdlw2jsIIPbwZ5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6wIg0/dJMcaiQh4l3/QuBarGXYdlw2jsIIPbwZ5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6wIg0/dJMcaiQh4l3/QuBarGXYdlw2jsIIPbwZ5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6wIg0%2FdJMcaiQh4l3%2FQuBarGXYdlw2jsIIPbwZ5k%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;1110&quot; height=&quot;425&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;383&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: decimal;&quot; data-line=&quot;383&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;알리고 싶은 이벤트를 영속화하기 위한 테이블(Outbox 테이블)을 준비한다&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot; data-line=&quot;384&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;동일한 트랜잭션 내에서 집약 지속성 및 이벤트 지속성을 수행하고 트랜잭션 커밋&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot; data-line=&quot;385&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다른 프로세스(메세지 릴레이)가 Outbox 테이블을 모니터링하고 새 이벤트를 검색한다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot; data-line=&quot;386&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;메세지 릴레이는 취득한 이벤트를 메시지 버스(Kafka, RabbitMQ, etc.)에 투입한다&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot; data-line=&quot;387&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;성공하면 메세지 릴레이는 Outbox 테이블에서 이벤트를 삭제하거나 게시됨으로 표시한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;389&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;5에서 실패하면 3-4가 다시 실행되므로 이벤트가 두 번 이상 전송될 수 있다(At-least-once)&lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%83%AA%E3%83%AC%E3%83%BC%E3%81%AE%E5%AE%9F%E8%A3%85&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;391&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;메시지 릴레이 구현&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;393&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Outbox 테이블에 기록된 새 이벤트를 검색하는 방법에는 두 가지가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;395&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;395&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;폴링 ... 정기적으로 Outbox 테이블에 액세스하여 새 이벤트를 검색.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;396&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;CDC(Change Data Capture) ... 어떠한 방식으로 데이터 변경 통지를 받음(DB에 따라서는 할 수 없는 경우도 존재)&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;397&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;397&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;셀프 호스팅된 RDB라면&amp;nbsp;&lt;a style=&quot;color: #0f83fd;&quot; href=&quot;https://debezium.io/&quot;&gt;Debezium&lt;/a&gt;&amp;nbsp;등의 툴을 사용&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;398&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;AWS의 경우,&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;399&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;399&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;DynamoDB라면 DynamoDB Streams로 구현 가능&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;400&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;PostgresSQL이면 논리 복제를 사용하여 구현 가능&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E5%8F%97%E4%BF%A1%E5%81%B4%E3%81%AE%E5%AE%9F%E8%A3%85&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;402&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;이벤트 수신자 구현&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;404&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;메세지 버스로부터 이벤트를 취득해 핸들러에 건네줍다. 핸들러의 구현은 기본적으로 동기적인 경우와 동일하다. 그러나 이벤트 알림이 비동기화되어 다음과 같은 문제가 발생할 수 있으므로 이를 해결해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;409&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;409&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트가 중복되어 도착&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;410&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트가 순서에 따라 도착&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;411&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;핸들러가 이벤트 처리에 실패함&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AE%E9%87%8D%E8%A4%87%E6%8E%92%E9%99%A4&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;413&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;이벤트 중복 제거&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;415&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;일반적으로 이벤트는 적어도 한 번(At-least-once) 통지된다(메시지 버스나 Outbox가 배송 과정에서 잠재적인 재시도를 수행하기 때문에). 따라서 받은 이벤트의 중복을 제거하는 메커니즘이 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;418&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;418&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트 핸들러의 처리를 멱등으로 설계해, 같은 이벤트가 복수회 처리되어도 결과가 변하지 않도록 한다&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;419&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;각 이벤트에 고유 식별자를 부여하고 처리된 이벤트 ID를 기록합니다. 중복 이벤트가 도착하면 무시하도록 말이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AE%E9%A0%86%E5%BA%8F%E4%BF%9D%E8%A8%BC&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;421&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;이벤트 순서 보증&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;423&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트를 비동기적으로 알리는 경우 이벤트가 소비자에게 도달하는 순서가 발생 순서와 일치하지 않을 수 있다. 기본적으로 동일한 집약에 관한 이벤트는 발생순으로 처리되도록 한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;426&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;426&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;메시지 버스 순서 보증 기능 사용&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;427&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;427&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예: Kafka 파티션(파티션 키를 집계 ID로 설정)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;428&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;수신자의 이벤트 순서 재정렬&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;%E3%82%A8%E3%83%A9%E3%83%BC%E5%87%A6%E7%90%86&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;430&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;오류 처리&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;432&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트 수신 측에서 예기치 않게 오류가 발생할 수 있습니다. (네트워크 오류 등)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;일반적으로 다음과 같은 접근 방식을 취합니다. 구현 방법은 메시지 버스에 따라 다릅니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;435&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;435&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;자동 재시도(재시도 간격을 지수 백오프로 조정)&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;436&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;오류가 발생한 이벤트를 교착 상태 큐로 이동하고 나중에 다시 처리&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;%E8%A3%9C%E5%84%9F%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;438&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;보상 액션&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;440&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트 핸들러가 어떤 이유로 처리를 완료하지 못할 수 있다. 예를 들면 주문 이벤트에 응답하여 결제를 수행하는 처리기에서 지정된 결제 방법으로 결제할 수 없는 경우 등 말이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;443&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트는 이미 발생한 것을 설명하며 이벤트가 없었던 걸로 할 수는 없다. 이벤트를 뒤집는 유일한 방법은 이벤트의 효과를 상쇄하기 위한 추가 조치를 수행하는 것 이다. 앞의 예에서 '주문 취소 및 재고 되돌리기'와 같은 작업을 수행하는 보상 작업이 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;443&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E3%82%B3%E3%83%B3%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%AE%E5%A4%96%E9%83%A8%E3%81%AB%E9%80%9A%E7%9F%A5%E3%81%99%E3%82%8B%EF%BC%88%E7%B5%B1%E5%90%88%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%EF%BC%89&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;467&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;도메인 이벤트를 컨텍스트 외부에 알리기(통합 이벤트)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;469&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;여러 컨텍스트의 연동을 위해 도메인 이벤트를 바운디드 컨텍스트 외부에 알리고 싶을 수 있다. 이벤트를 문맥내에 통지하는 경우와는 몇 가지 다른 점이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E3%81%9D%E3%81%AE%E3%81%BE%E3%81%BE%E5%A4%96%E9%83%A8%E3%81%AB%E5%85%AC%E9%96%8B%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%AE%E6%98%AF%E9%9D%9E&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;472&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;도메인 이벤트를 그대로 외부에 공개하는 것&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;474&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;우선 도메인 이벤트를 외부에 그대로 공개해도 좋은가 하는 문제가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;476&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;476&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트는 도메인 모델의 일부이며 바운디드 컨텍스트의 내부 표현이다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;477&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;477&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;외부에 공개하면 캡슐화가 무너진다&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;478&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;내부 표현과 외부 시스템이 결합하면 이벤트 구조 변경이 어려워진다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;479&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;외부와의 협력에 필요한 정보와 도메인 이벤트 정보가 일치하지 않을 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;481&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이러한 이유로 일반적으로 도메인 이벤트를 그대로 외부에 게시하는 것은 피해야 하지만, 책이나 기사에 따라서는 그대로 공개하는 실장예를 소개하고 있는 것도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;%E5%A4%89%E6%8F%9B%E3%81%97%E3%81%A6%E5%85%AC%E9%96%8B%E3%81%99%E3%82%8B%E6%B4%BE&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;483&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;변환하고 공개하는 구현&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;485&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트를 외부 컨텍스트로 전달하기 전에 게시 이벤트로 변환한다. (이후 통합 이벤트(&amp;nbsp;&lt;b&gt;Integration Event&lt;/b&gt;&amp;nbsp;)라고 한다.)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;변환에는 상태 비저장 변환과 상태 저장 변환이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;488&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;488&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;스테이트리스 변환(=도메인 이벤트만을 출처로 한다)&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;489&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;489&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;불필요한 메시지와 속성을 생략&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;490&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;490&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;컨텍스트 간의 우발적인 결합을 피하기 위해&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;491&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;보안을 위해&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;492&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;연계에 적합한 형식이나 명칭으로 변환&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;493&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;상태 저장 변환 (= 과거 도메인 이벤트 및 다른 데이터 스토어에서 얻은 정보 사용)&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;494&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;494&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;여러 이벤트 집계 및 통합&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;495&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;리포지토리에서 얻은 정보 추가&lt;/span&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 Sans Demilight', 'Noto Sans KR';&quot;&gt;관련 예나 블로그 포스트는 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-line=&quot;499&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;499&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a style=&quot;color: #0f83fd;&quot; href=&quot;https://learn.microsoft.com/ja-jp/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/domain-events-design-implementation&quot;&gt;도메인 이벤트: 디자인 및 구현 - .NET | Microsoft Learn&lt;/a&gt;&amp;nbsp;은 도메인 이벤트를 통합 이벤트(Integration Event)로 변환하여 외부에 게시한다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;500&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;500&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 변환은 DomainEventHandler에서 수행하고 통합 이벤트 전송 서비스에 전달한다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;501&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;속성은 도메인 이벤트와 동일하지 않으며 필요에 따라 추가 및 삭제된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;502&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a style=&quot;color: #0f83fd;&quot; href=&quot;https://learning.oreilly.com/library/view/learning-domain-driven-design/9781098100124/&quot;&gt;Learning Domain-Driven Design&lt;/a&gt;&amp;nbsp;에서는 도메인 이벤트를 공개 언어로 변환하여 외부에 게시한다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;503&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;503&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트를 전달하기 전에 프록시를 통해 변환&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;504&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;504&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;스테이트리스 모델 변환&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;505&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;상태 저장 모델 변환&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;506&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트 및 기타 이벤트를 구분하는 것이 좋다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;507&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;507&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Event notification ... 사건의 발생을 통지하지만, 상세 정보는 가지지 않는다. 자세한 정보가 필요한 경우 소비자로부터 명시적으로 문의&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;508&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Event-carried state transfer ... 컨텍스트간에 데이터 복제를 동기화하기 위해 업스트림 컨텍스트의 데이터 변경을 다른 컨텍스트로 전송&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;509&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Domain event ... 도메인 내에서 발생한 사건을 설명하는 메시지&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;그대로 공개하는 구현&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 이벤트를 변환하는 데 어려움이 있다면 여기를 선택하는 것도 가능하다. 다만 위에서 언급한 문제가 있으므로 주의가 필요가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-line=&quot;520&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;520&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a style=&quot;color: #0f83fd;&quot; href=&quot;https://amzn.asia/d/0eV44aXJ&quot;&gt;실습 도메인 구동 설계&lt;/a&gt;&amp;nbsp;에서는 JSON 직렬화된 도메인 이벤트를 외부에 통지하는 예가 소개되어 있다&lt;/span&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-line=&quot;521&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: decimal;&quot; data-line=&quot;521&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;시스템 내에서 발생한 모든 도메인 이벤트를 받는 핸들러 만들기&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot; data-line=&quot;522&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트 핸들러는 수신한 이벤트를 JSON으로 직렬화하여 이벤트 스토어(RDB의 1 테이블)에 영속화&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot; data-line=&quot;523&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트 스토어에 저장된 이벤트는 다음 방법 중 하나로 외부에 통지&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;524&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;524&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트를 얻기 위해 RESTful API를 공개하고 외부 서비스에서 폴링&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;525&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;메시징 미들웨어로 전송&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;526&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a style=&quot;color: #0f83fd;&quot; href=&quot;https://amzn.asia/d/0bdNXgEr&quot;&gt;마이크로서비스 패턴&lt;/a&gt;&amp;nbsp;에서도 도메인 이벤트를 외부에 알리는 예가 소개되어 있다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;527&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;527&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;원래 도메인 이벤트를 외부와의 연계를 위한 것으로 설계하고 있다&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;528&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;'이벤트 인리치먼트'라고 하여 외부 서비스가 요구하는 추가 정보를 도메인 이벤트에 포함시키는 설계를 소개하고 있다.&lt;/span&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;h3 id=&quot;%E7%B5%B1%E5%90%88%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AE%E8%A8%AD%E8%A8%88&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;532&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;통합 이벤트 설계&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;534&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트는 &quot;도메인상의 사건을 정확하게 설명하는 과부족한 정보&quot;라는 관점에서 설계된다. 한편, 통합 이벤트는 바운디드 컨텍스트의 공개 I/F의 일부이며, 「외부 컨텍스트와의 제휴를 위한 계약」이라고 하는 성질이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #ffffff; color: #000000; text-align: start; border-collapse: collapse; width: 100%; height: 68px;&quot; border=&quot;1&quot; data-line=&quot;536&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;background-color: #ffffff; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;통합 이벤트&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot; data-line=&quot;538&quot;&gt;
&lt;td style=&quot;background-color: #ffffff; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인의 사건을 설명하는 정보&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;외부 컨텍스트와의 연계를 위한 계약&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot; data-line=&quot;539&quot;&gt;
&lt;td style=&quot;background-color: #ffffff; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;경계화된 컨텍스트 내에서 소비&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;경계가 붙은 컨텍스트 외부에 게시&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot; data-line=&quot;540&quot;&gt;
&lt;td style=&quot;background-color: #ffffff; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트 처리는 동기화 또는 비동기일 수 있습니다.&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;항상 비동기적으로 처리됨&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;%E5%A5%91%E7%B4%84%E3%81%A8%E3%81%97%E3%81%A6%E3%81%AE%E7%B5%B1%E5%90%88%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;543&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;계약으로서의 통합 이벤트&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;545&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a style=&quot;color: #0f83fd;&quot; href=&quot;https://amzn.asia/d/0j03Un9r&quot;&gt;함수형 도메인 모델링&lt;/a&gt;&amp;nbsp;에는 두 가지 컨텍스트가 계약에 동의하는 패턴으로 다음 세 가지가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;547&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;547&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;공유 커널&lt;/b&gt;&amp;nbsp;관계 ... 컨텍스트간에 도메인 디자인을 공동 소유한다. 이벤트의 정의는 다른 공동 소유자와의 협의에 기초.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;548&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;고객 / 공급자&lt;/b&gt;&amp;nbsp;관계 ... 다운 스트림 컨텍스트가 업스트림 컨텍스트에 대해 원하는 계약을 정의한다 (&amp;nbsp;&lt;b&gt;소비자 중심 계약&lt;/b&gt;&amp;nbsp;). 이 계약을 충족하는 한 각 컨텍스트는 독립적으로 발전할&amp;nbsp; 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;549&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;순응자&lt;/b&gt;&amp;nbsp;관계 ... 하류 컨텍스트는 업스트림 컨텍스트가 제공하는 계약을 수락합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;551&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;소비자 구동 계약은 이벤트뿐만 아니라 마이크로 서비스 간의 I / F 설계에 사용되는 일반적인 패턴이다.계약을 끊지 않았음을 소비자와 공급자 모두가 테스트하여 통신이 끊어지지 않도록 보장할 수 있다. 계약을 테스트하는 도구로&amp;nbsp;&lt;a style=&quot;color: #0f83fd;&quot; href=&quot;https://docs.pact.io/&quot;&gt;Pact&lt;/a&gt;&amp;nbsp;가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E%E9%80%B2%E5%8C%96&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;554&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;스키마 진화&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;556&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트의 스키마는 비즈니스 요구 사항의 변경 등에 따라 변경된다. 이벤트의 생산자와 소비자가 서로 독립적으로 진화할 수 있고 모든 시점에서 중단없이 협력할 수 있도록 하려면 스키마 호환성을 고려해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;559&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;호환성 유형:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;561&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;561&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;정방향 호환성&lt;/b&gt;&amp;nbsp;: 새 스키마 데이터를 이전 스키마로 읽을 수 있음&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;562&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;562&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;생산자 측에서 새 스키마 이벤트를 제출해도 소비자 측은 코드를 변경할 필요가 없음.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;563&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;소비자는 새로운 스키마 정보가 필요한 경우에만 코드를 수정.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;564&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;역호환성&lt;/b&gt;&amp;nbsp;: 이전 스키마 데이터를 새 스키마로 읽을 수 있음&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;565&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;565&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;스키마가 미리 정의된 경우 소비자는 생산자보다 먼저 코드 업데이트를 릴리스할 수 있음.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;566&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이전 이벤트를 재처리해야 하는 경우에 대응 가능.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;567&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;완전 호환성&lt;/b&gt;&amp;nbsp;: 전방 호환성과 후방 호환성 모두&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;568&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;568&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;가능한 한 목표로 삼아야함.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;569&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;호환성 요구 사항을 나중에 푸는 것은 쉽지만 엄격하게하기는 어려움.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;571&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;파괴적 변경이 필요한 경우에는 오래된 이벤트와 새 이벤트를 모두 지원하고 마감일을 사용하여 이전 이벤트를 폐지하는 것이 일반적이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;571&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;%E7%B5%B1%E5%90%88%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%B8%E3%81%AE%E5%A4%89%E6%8F%9B%E3%81%A8%E9%80%81%E4%BF%A1&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;573&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;통합 이벤트로 변환 및 전송&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;575&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트의 경우와 달리 통합 이벤트는 항상 비동기적으로 통지 및 처리된다. 통합 이벤트를 처리하는 메커니즘은 도메인 이벤트의 메커니즘을 기반으로 구축한다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B31.-%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%83%8F%E3%83%B3%E3%83%89%E3%83%A9%E3%83%BC%E3%81%A7%E7%B5%B1%E5%90%88%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AB%E6%98%8E%E7%A4%BA%E7%9A%84%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%97%E3%81%A6%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;578&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;패턴 1. 도메인 이벤트 핸들러에서 통합 이벤트로 명시적으로 변환 및 전송&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;580&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트를 받은 핸들러가 통합 이벤트로 변환하여 전송한다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;582&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: decimal;&quot; data-line=&quot;582&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;대상 도메인 이벤트를 구독하는 핸들러 만들기&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot; data-line=&quot;583&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. 핸들러 내에서 도메인 이벤트에서 통합 이벤트로 변환&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot; data-line=&quot;584&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2. 통합 이벤트를 Outbox 패턴 및 메시지 버스를 사용하여 비동기 적으로 전송&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1774961029282&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// OrderCancelled 이벤트를 통합 이벤트로 변환 송신하는 핸들러
class PublishIntegrationEventWhenOrderCancelledHandler(
  private val integrationEventPublisher: IntegrationEventPublisher
) : DomainEventHandler&amp;lt;OrderCancelled&amp;gt; {
  override fun eventType() = OrderCancelled::class

  override fun handle(domainEvent: OrderCancelled) {
    // 통합 이벤트로 변환
    // - 연계를 통해 정보를 변환한다
    // - 불필요한 정보는 생략한다
    // - 리포지터리를 사용하여 추가 정보를 획득한다
    // - 여러 이벤트를 집약, 통합
    val integrationEvent = OrderCancelledIntegrationEvent(
      domainEvent.orderId,
      ...
    )
    // IntegrationEventPublisher는 Outbox 패턴 &amp;amp; 메세지를 이용한 비동기적으로 이벤트를 송신한다
    // （도메인 이벤트를 비동기로 디스패치할 경우와 같이 동일한 기술을 사용하여 구현한다）
    integrationEventPublisher.publish(integrationEvent)
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 위 예제에서는 도메인 이벤트를 개별적으로 처리하지만 모든 도메인 이벤트를 중앙 집중식으로 처리하는 핸들러를 만들 수도 있다. 단일 책임의 원칙에 반하는 것 같지만 편한 방법이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774961060917&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class PublishIntegrationEventHandledHandler(
  private val integrationEventPublisher: IntegrationEventPublisher
) : DomainEventHandler&amp;lt;DomainEvent&amp;gt; {
  override fun eventType() = DomainEvent::class

  override fun handle(domainEvent: DomainEvent) {
    val integrationEvent = when (domainEvent) {
      is OrderCancelled -&amp;gt; OrderCancelledIntegrationEvent(
        domainEvent.orderId,
        ...
      )
      is OrderShipped -&amp;gt; OrderShippedIntegrationEvent(
        domainEvent.orderId,
        ...
      )
      ...
    }
    integrationEventPublisher.publish(integrationEvent)
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B32.-%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E5%A4%89%E6%8F%9B%E3%83%AC%E3%82%A4%E3%83%A4%E3%83%BC%E3%82%92%E9%85%8D%E7%BD%AE%E3%81%99%E3%82%8B&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;635&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;패턴 2. 이벤트 변환 레이어 배치&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;637&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 이벤트를 비동기적으로 보내는 메커니즘이 있는 경우 어딘가에서 이벤트 흐름을 가로채고 통합 이벤트로 변환할 수 있다. 이벤트 변환 레이어를 배치하는 장소로는 다음과 같은 후보들이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;640&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;640&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Outbox 테이블에서 도메인 이벤트를 검색한 직후 통합 이벤트로 변환하여 메시지 버스에 입력&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;641&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;메시지 버스에 투입된 도메인 이벤트를 검색하여 통합 이벤트로 변환한 후 다시 메시지 버스에 투입&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;642&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;메시지 버스에 따라서는 변환 처리를 실시하기 위한 후크를 제공하고 있는 경우가 있다&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;643&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;643&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;AWS Kinesis Data Firehose, Kafka Connect 등&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B33.-%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8Bapi%E3%82%92%E6%8F%90%E4%BE%9B%E3%81%97%E3%80%81%E8%B3%BC%E8%AA%AD%E5%81%B4%E3%81%8B%E3%82%89%E3%83%9D%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;645&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;패턴 3. 이벤트를 검색하는 API를 제공하고 구독자로부터 폴링&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;647&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;전혀 다른 접근법으로는 이벤트를 발행하는 측이 이벤트 취득의 엔드 포인트를 공개하고 이벤트를 수신하는 측에서 폴링하는 방법도 있다. 이 방법은&amp;nbsp;&lt;a style=&quot;color: #0f83fd;&quot; href=&quot;https://amzn.asia/d/0eV44aXJ&quot;&gt;실습 도메인 기반 설계&lt;/a&gt;&amp;nbsp;에서 &quot;RESTful 리소스를 통한 알림 발행&quot;이라는 타이틀로 소개되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트 발행자:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;651&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;651&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;시스템 내에서 발생한 모든 이벤트를 이벤트 저장소에 영속화&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;652&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;새로운 이벤트를 얻기 위한 엔드포인트 준비&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;653&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;653&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;RSS 및 Atom 피드와 같은 이미지&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;654&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;내부에서는 이벤트 스토어에서 이벤트를 검색하고 반환&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;650&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;655&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트 수신자:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-line=&quot;656&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;656&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이벤트 발행자의 엔드포인트를 정기적으로 폴링&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot; data-line=&quot;657&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;어디까지 처리했는지 직접 관리&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;659&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;통합 이벤트로의 변환은, 이벤트 스토어에의 기입시 또는, 응답을 돌려주기 전에 실시하면 좋을 것이다. (서적에서는 변환 처리는 생략되어 있다)&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://zenn.dev/kohii/articles/4a68e768c93573&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://zenn.dev/kohii/articles/4a68e768c93573&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>IT/기초 지식</category>
      <author>개발자 두더지</author>
      <guid isPermaLink="true">https://engineer-mole.tistory.com/459</guid>
      <comments>https://engineer-mole.tistory.com/459#entry459comment</comments>
      <pubDate>Tue, 31 Mar 2026 21:46:06 +0900</pubDate>
    </item>
    <item>
      <title>Node.js 버전 관리 툴 Volta</title>
      <link>https://engineer-mole.tistory.com/458</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Volta란?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/odT3w/dJMcabQVPSw/z56lMHrEKve7S0VKfyGyTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/odT3w/dJMcabQVPSw/z56lMHrEKve7S0VKfyGyTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/odT3w/dJMcabQVPSw/z56lMHrEKve7S0VKfyGyTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FodT3w%2FdJMcabQVPSw%2Fz56lMHrEKve7S0VKfyGyTk%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;953&quot; height=&quot;334&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;334&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&amp;nbsp;Volta&lt;/b&gt;&amp;nbsp;는&amp;nbsp;&lt;b&gt;JavaScript 도구 관리툴이다&lt;/b&gt;. 타이틀에서는 Node.js 의 버전 관리툴로 소개하고 있지만, npm&amp;middot;yarn 의 버전 관리도 할 수 있다. &lt;a style=&quot;color: #0f83fd;&quot; href=&quot;https://volta.sh/&quot;&gt;공식 사이트&lt;/a&gt;&amp;nbsp;에서는 &quot;The Hassle-Free JavaScript Tool Manager(수고 없는 JavaScript 도구 관리자)&quot;라고 소개되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;9&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;팀의 Node.js 버전 관리를 Volta에 통합한 결과 DX가 높아져 Volta 장점을 느끼게 됐다.이 포스트에서는 개발자의 Volta 인구를 늘리기 위해 Volta를 소개하고 사용하는 방법에 대해 설명하고자한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;15&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;15&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;15&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Volta 개요&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 공식 사이트에서 소개된 Volta의 3가지 특징을 살펴보도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1069&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UYiU1/dJMcadA9pTW/iuyK4lHntWdLdopQPp0jkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UYiU1/dJMcadA9pTW/iuyK4lHntWdLdopQPp0jkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UYiU1/dJMcadA9pTW/iuyK4lHntWdLdopQPp0jkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUYiU1%2FdJMcadA9pTW%2FiuyK4lHntWdLdopQPp0jkK%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;1069&quot; height=&quot;179&quot; data-origin-width=&quot;1069&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Fast : Volta는 Rust로 제작되었으므로 다른 버전 관리 도구보다 더 빠르다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Reliable : 개인적으로 가장 장점을 부분으로 volta pin라는 명령을 사용하면 프로젝트 멤버의 Node.js 및 npm 버전을 쉽게 맞출 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Universal :&amp;nbsp; &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;Windows &amp;middot; Mac &amp;middot; Linux. 모든 OS에서 작동한다.&amp;nbsp;&lt;/span&gt;&lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;Volta의 특징&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; &amp;nbsp;Volta는 Node 엔진을 한 번 선택하면 그 이후에는 걱정할 필요가 없다. 프로젝트를 전환한다고 해도 Node를 수동으로 전환할 필요가 없다. 정기적으로 다시 설치하거나 왜 작동하지 않는지 확인하지 않고도 툴체인에 npm 패키지 바이너리를 설치할 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;다음의 커맨드 하나로 특정 버전의 노드를 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773230433806&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ volta install node@14&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;그리고 공동 작업자를 위한 재현 가능한 환경을 커맨드 하나로 만들 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773230465925&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ volta pin node@12&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; &amp;nbsp;위 커맨드를 실행하면 Node 엔진의 버전을 package.json에 저장, 그 내용을 git에 커밋 할 수 있다. 따라서 프로젝트 디렉토리에서 Node를 실행할 때마다 Volta는 자동으로 &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;package.json에 설정된&lt;/span&gt; 버전과 동일한 버전의 Node로 전환한다. 이로 인해 공동 연구자는 각 개발 머신에 Volta를 설치하여 동일한 환경을 구현할 수 있다. &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;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;volta-%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%82%88%E3%81%86-%EF%BD%9C-getting-started&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;106&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Volta 설치하기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 id=&quot;%E4%B8%80%E6%97%A6-node.js%E3%83%BBnpm-%E3%82%92%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;110&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;먼저 Node.js &amp;middot; npm 삭제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 설치하기 전에 현재 사용중인 Node 버전 관리 도구를 제거하고 Node &amp;middot; npm을 사용할 수없는 상태로 만드는 것이 좋다. 툴&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt; 삭제에 관해서는 환경에 따른 패턴이 너무 많기 때문에 (nodebrew, NVM, nodist, ...) 삭제 방법에 대해서는 생략하도록 하겠다. 자신의 환경에 맞는 삭제 방법을 조사 후 실행하길 바란다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;volta-%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;119&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Volta 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;121&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a style=&quot;color: #0f83fd;&quot; href=&quot;https://docs.volta.sh/guide/getting-started&quot;&gt;공식 Getting Started&lt;/a&gt;&amp;nbsp;에 따라 설치하면 된다. OS가 Mac / Linux (WSL 포함)이면 다음 커맨드로 쉽게 설치할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1773230793978&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ curl https://get.volta.sh | bash&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;133&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Windows는 Windows Installer를 사용할 수 있으므로 공식 설명서에 따라 다운로드하여 실행하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;133&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;설치 확인&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;133&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; .zshrc파일등의 쉘의 설정 파일을&amp;nbsp;cat커멘드등으로 파일 내용을 살펴자. 이하의 패스가 통하고 있으면 OK다. &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773230858353&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export VOLTA_HOME=&quot;$HOME/.volta&quot;
export PATH=&quot;$VOLTA_HOME/bin:$PATH&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;그리고 터미널을 통해 volta 명령어를 사용할 수 있는지 확인해보자. 버전이 뜬다면 무사히 설치가 된 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773230884338&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ volta --version&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;툴 체인 관리&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; Volta 툴체인이 관리하는 툴은&amp;nbsp;volta install과&amp;nbsp;volta uninstall 이 두 가지 커맨드로로 제어되게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 특정 버전을 설정하여 Node의 기본 버전을 선택할 수 있습니다. &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773231017707&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ volta install node@14.15.5&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;다음과 같이 정확한 버전을 지정하지 않는 경우 Volta쪽에서 적절한 버전을 선정하여 설치하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773231046485&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ volta install node@14&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;그냥 최신 버전을 다운로드 받고 싶다면 &lt;span style=&quot;text-align: start;&quot;&gt;latest를 사용하면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773231085354&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ volta install node@latest&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; &amp;nbsp;앞서 말했듯 node이외에도 npm과 Yarn도 install 커맨드로 설치할 수 있다.&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;프로젝트 관리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp; Volt의 특징에서 설명했듯 공동 작업자 팀 또는 커뮤니티 프로젝트에 사용할 개발 도구를 표준화 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;node-%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%B3%E3%81%AE%E5%9B%BA%E5%AE%9A&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-line=&quot;211&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Node 엔진 버전&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; volta pin명령을 사용하여 프로젝트의 Node 엔진 및 패키지 관리자 버전을 선택할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773231193910&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Node의 버전 고정
$ volta pin node@14.17

# npm의 버전 고정
$ volta pin npm@6.14&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;pin 명령어를 사용하면 Volta는 이를&amp;nbsp;package.json저장하므로 선택한 도구를 버전 관리에 커밋할 수 있게 된다. 즉, package.json에 다음과 같은 내용이 추가되게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773231239988&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;volta&quot;: {
  &quot;node&quot;: &quot;14.17.3&quot;,
  &quot;npm&quot;: &quot;6.14.13&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 이 방법으로 Volta를 사용하여 프로젝트를 수행하는 모든 사람이 선택한 버전과 동일한 버전을 자동으로 가져 오게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773231260319&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;node --version # 14.17.3
npm --version # 6.14.13&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Volta 커맨드 옵션&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 공식 커맨드 레퍼런스는&amp;nbsp;&lt;a style=&quot;background-color: #ffffff; color: #0f83fd; text-align: start;&quot; href=&quot;https://docs.volta.sh/reference/&quot;&gt;이쪽&lt;/a&gt; 에서 확인 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773231497808&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 이용 방법
volta [FLAGS] [SUBCOMMAND]

# FLAGS
    --verbose   # 상세진단을 유효화
    --quiet     # 불필요한 출력을 없앰
-v, --version   # Volta의 현재 버전 표시
-h, --help      # 헬프정보 표시


# SUBCOMMANDS
fetch          # 로컬 머신에 툴을 패치
install        # 툴을 툴 체인에 설치
uninstall      # 툴을 툴 체인에서 삭제
pin            # 프로젝트의 런타임이나 패키지 매니저를 고정
list           # 현재 툴 체인을 표시
completions    # Volta컴플리트를 생성
which          # Volta가 호출한 실제 바이너리를 특정
setup          # 현재 유저/쉘에 대해 Volta를 유효화
help           # 메시지 혹은 지정된 서브 커맨드의 헬프 표시&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://zenn.dev/taichifukumoto/articles/how-to-use-volta&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://zenn.dev/taichifukumoto/articles/how-to-use-volta&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT/기초 지식</category>
      <author>개발자 두더지</author>
      <guid isPermaLink="true">https://engineer-mole.tistory.com/458</guid>
      <comments>https://engineer-mole.tistory.com/458#entry458comment</comments>
      <pubDate>Wed, 11 Mar 2026 21:19:02 +0900</pubDate>
    </item>
    <item>
      <title>의지를 구현하는 아키텍처 모더나이제이션</title>
      <link>https://engineer-mole.tistory.com/457</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&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;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-section-id=&quot;1cbju28&quot; data-end=&quot;239&quot; data-start=&quot;205&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1.&amp;nbsp; AI 시대에 엔지니어의 역할은 무엇인가&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-end=&quot;273&quot; data-start=&quot;241&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;최근에는 &lt;b&gt;AI가 코드를 작성하는 시대&lt;/b&gt;가 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-end=&quot;296&quot; data-start=&quot;275&quot; data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;과거 &amp;rarr; 개발자가 코드를 직접 작성&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;현재 &amp;rarr; AI가 코드를 생성&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-end=&quot;344&quot; data-start=&quot;317&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그래서 개발자의 역할은 점점 다음으로 이동하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;407&quot; data-start=&quot;346&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-section-id=&quot;6lja16&quot; data-end=&quot;362&quot; data-start=&quot;346&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;어떤 기술을 선택할 것인가&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;uwm57n&quot; data-end=&quot;384&quot; data-start=&quot;363&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;시스템을 어떤 구조로 설계할 것인가&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;kqm4i3&quot; data-end=&quot;407&quot; data-start=&quot;385&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 시스템이 어떤 가치를 만들 것인가&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;410&quot; data-start=&quot;409&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;즉&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-end=&quot;466&quot; data-start=&quot;412&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;466&quot; data-start=&quot;414&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&amp;ldquo;코드를 작성하는 것&amp;rdquo;보다&lt;br /&gt;&amp;ldquo;어떤 시스템을 만들 것인가를 결정하는 것&amp;rdquo;이 중요해진다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;521&quot; data-start=&quot;468&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;521&quot; data-start=&quot;468&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-section-id=&quot;x35flb&quot; data-end=&quot;559&quot; data-start=&quot;528&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-section-id=&quot;x35flb&quot; data-end=&quot;559&quot; data-start=&quot;528&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 레거시 시스템 문제 (Legacy System)&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-end=&quot;609&quot; data-start=&quot;561&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;레거시 시스템(legacy system) &lt;/b&gt;은 오래되어 구조가 복잡해진 시스템을 의미한다. 이러한 시스템들은 보통 다음 특징을 가진다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-section-id=&quot;1hrlj9m&quot; data-end=&quot;642&quot; data-start=&quot;636&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;682&quot; data-start=&quot;644&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;변경이 어렵다&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;682&quot; data-start=&quot;644&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;조금만 수정해도 다른 기능이 망가질 수 있음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;682&quot; data-start=&quot;644&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;개발 속도가 느리다&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;682&quot; data-start=&quot;644&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드가 복잡해서 수정하기 어려움&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;751&quot; data-start=&quot;720&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;운영이 어렵다&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;751&quot; data-start=&quot;720&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문제가 생기면 원인을 찾기 힘듦&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;761&quot; data-start=&quot;753&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이런 상태에서는 아래의 것들이 어려워진다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;791&quot; data-start=&quot;763&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-section-id=&quot;1rhr2cp&quot; data-end=&quot;774&quot; data-start=&quot;763&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;새로운 기능 추가&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;1igezxg&quot; data-end=&quot;783&quot; data-start=&quot;775&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;서비스 확장&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;62cyu1&quot; data-end=&quot;791&quot; data-start=&quot;784&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기술 도입&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;846&quot; data-start=&quot;807&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그래서 레거시 시스템의 경우 &lt;b&gt;시스템을 현대화(modernization)&lt;/b&gt; 해야할 필요가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h1 data-section-id=&quot;1vkaxg1&quot; data-end=&quot;877&quot; data-start=&quot;853&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-section-id=&quot;1vkaxg1&quot; data-end=&quot;877&quot; data-start=&quot;853&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 아키텍처 모더나이제이션이란 무엇인가&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-end=&quot;927&quot; data-start=&quot;879&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;아키텍처(Architecture) &lt;/b&gt;는 시스템의 &lt;b&gt;전체 구조와 설계 방식 &lt;/b&gt;라고 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;934&quot; data-start=&quot;929&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예를 들어 다음의 것들을 의미한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;984&quot; data-start=&quot;936&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-section-id=&quot;1oscwzn&quot; data-end=&quot;951&quot; data-start=&quot;936&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;서비스가 어떻게 나뉘는지&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;1bot0kv&quot; data-end=&quot;967&quot; data-start=&quot;952&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;데이터가 어떻게 흐르는지&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;1eue6v&quot; data-end=&quot;984&quot; data-start=&quot;968&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;시스템이 어떻게 연결되는지&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;그렇다면 모더나이제이션은 무엇인가. 오래된 시스템을 &lt;b&gt;현재 환경에 맞게 바꾸는 것을 의미한다. &lt;/b&gt;즉, &lt;b&gt;아키텍처 모더나이제이션 = &lt;/b&gt;&lt;b&gt;시스템 구조를 새롭게 설계&lt;/b&gt;하는 것이다. 하지만 이는&lt;u&gt; 단순한 기술 교체가 아니다.&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1165&quot; data-start=&quot;1160&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예를 들어 다음과 같은 것으로 문제가 해결되지 않을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1205&quot; data-start=&quot;1167&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-section-id=&quot;2ji7vd&quot; data-end=&quot;1181&quot; data-start=&quot;1167&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;서버를 클라우드로 이동&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;ps1h38&quot; data-end=&quot;1192&quot; data-start=&quot;1182&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;프레임워크 교체&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;1k3q9q1&quot; data-end=&quot;1205&quot; data-start=&quot;1193&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;마이크로서비스 도입&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1243&quot; data-start=&quot;1239&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;왜냐하면 &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;시스템 문제는 &lt;/span&gt;&lt;b&gt;기술이 아니라 구조와 조직 문제일 수 있기 때문이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h1 data-section-id=&quot;drynmi&quot; data-end=&quot;1331&quot; data-start=&quot;1298&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-section-id=&quot;drynmi&quot; data-end=&quot;1331&quot; data-start=&quot;1298&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-section-id=&quot;drynmi&quot; data-end=&quot;1331&quot; data-start=&quot;1298&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;4. 소시오테크니컬 관점 (Socio-technical)&lt;/span&gt;&lt;/h1&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-end=&quot;1421&quot; data-start=&quot;1358&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;소시오테크니컬(Socio-technical) 은 &lt;/b&gt;&amp;ldquo;사회(조직)&amp;rdquo; + &amp;ldquo;기술&amp;rdquo;이 함께 영향을 준다는 개념으로 정리할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1424&quot; data-start=&quot;1423&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;즉 아래의 것들이 모두 연결되어 있다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1457&quot; data-start=&quot;1426&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-section-id=&quot;1fkbs05&quot; data-end=&quot;1433&quot; data-start=&quot;1426&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;조직 구조&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;ac7hg4&quot; data-end=&quot;1440&quot; data-start=&quot;1434&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;팀 구조&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;1rmdaxo&quot; data-end=&quot;1448&quot; data-start=&quot;1441&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;개발 방식&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;ozdjqo&quot; data-end=&quot;1457&quot; data-start=&quot;1449&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;시스템 구조&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1485&quot; data-start=&quot;1480&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예를 들어 팀 구조가 다음과 같은 경우&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;A팀&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;B팀&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;C팀&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1537&quot; data-start=&quot;1518&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;시스템도 보통 이런 구조가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;서비스 A&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;서비스 B&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;서비스 C&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1569&quot; data-start=&quot;1566&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그래서 &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;시스템 구조는 &lt;/span&gt;&lt;b&gt;조직 구조를 반영한다고 할 수 있으며,&amp;nbsp; &lt;/b&gt;이것을 흔히 &lt;b&gt;Conway&amp;rsquo;s Law&lt;/b&gt;라고 합니다. 따라서 &lt;b&gt;시스템을 바꾸려면 조직도 함께 바뀌어야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1569&quot; data-start=&quot;1566&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1569&quot; data-start=&quot;1566&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1569&quot; data-start=&quot;1566&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-section-id=&quot;6hm505&quot; data-end=&quot;1699&quot; data-start=&quot;1670&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;5. 비즈니스 이해 &amp;ndash; Event Storming&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-end=&quot;1724&quot; data-start=&quot;1701&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;아키텍처를 바꾸기 전에 먼저 해야 할 것은 &lt;b&gt;비즈니스가 어떻게 동작하는지 이해하는 것이다&lt;/b&gt;. 여기서 사용할 수 있는 방법은 &lt;b&gt;Event Storming 이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-section-id=&quot;1xsm62l&quot; data-end=&quot;1820&quot; data-start=&quot;1802&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Event Storming&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1860&quot; data-start=&quot;1822&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 것은 비즈니스에서 발생하는 사건(event)을 정리하는 하나의 방법이다. 예를 들어 살펴보자. 쇼핑몰 서비스가 존재한다고 하자. 비즈니스에서 실제로 발생하는 사건을 나열하면 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;상품 등록됨&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;상품 주문됨&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;결제 완료됨&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;배송 시작됨&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;배송 완료됨&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1952&quot; data-start=&quot;1918&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Event Storming &lt;/b&gt;은 이렇게 &lt;b&gt;비즈니스에서 실제로 발생하는 사건을 나열&lt;/b&gt;합니다.이 작업을 통해 서비스 흐름, 시스템 경계, 중요한 도메인을 발견할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1952&quot; data-start=&quot;1918&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1952&quot; data-start=&quot;1918&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-section-id=&quot;166jft7&quot; data-end=&quot;2033&quot; data-start=&quot;2013&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;6. 도메인 주도 설계 (DDD)&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-end=&quot;2088&quot; data-start=&quot;2035&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;Event Storming으로 이해한 비즈니스 구조를 기반으로 다음 단계에서 사용하는 방법은&amp;nbsp;&lt;b&gt;DDD (Domain Driven Design)&lt;/b&gt; 이다. &lt;b&gt;도메인(domain) &lt;/b&gt;은 서비스가 해결하려는 &lt;b&gt;비즈니스 영역&lt;/b&gt;으로 정의할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2088&quot; data-start=&quot;2035&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;위에서 살펴보았던 예를 다시 인용하도록 하겠다. &amp;nbsp;Event Storming으로 사건을 정리한 후 필요한 기능을 정리하면 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2172&quot; data-start=&quot;2171&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2198&quot; data-start=&quot;2174&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-section-id=&quot;1pb5zvk&quot; data-end=&quot;2181&quot; data-start=&quot;2174&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;주문 관리&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;15zfrls&quot; data-end=&quot;2190&quot; data-start=&quot;2182&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;결제 시스템&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;6klnh1&quot; data-end=&quot;2198&quot; data-start=&quot;2191&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;배송 관리&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2208&quot; data-start=&quot;2200&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;DDD의 핵심은 &lt;b&gt;비즈니스 구조를 중심으로 시스템을 설계한다하는 것이다. &lt;/b&gt;그래서 시스템을 다음과 같이 나눌 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;주문 도메인&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;결제 도메인&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;배송 도메인&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2303&quot; data-start=&quot;2297&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이렇게 비즈니스 구조를 중심으로 시스템을 설계하게 되면 시스템 이해가 쉬워지고 변경이 쉬워진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2303&quot; data-start=&quot;2297&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2303&quot; data-start=&quot;2297&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-section-id=&quot;1esy7oy&quot; data-end=&quot;2369&quot; data-start=&quot;2339&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-section-id=&quot;1esy7oy&quot; data-end=&quot;2369&quot; data-start=&quot;2339&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;7. 팀 구조 설계 &amp;ndash; Team Topologies&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-end=&quot;2382&quot; data-start=&quot;2371&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다음으로 중요한 것은 &lt;b&gt;팀 구조&lt;/b&gt;이다. &lt;b&gt;Team Topologies&lt;/b&gt; 개념에 대해서 한 마디로 설명하자면,&amp;nbsp; 시스템 구조에 맞게 &lt;b&gt;팀을 설계하는 방법&lt;/b&gt;을 의미한다. 대표적인 팀 유형은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-section-id=&quot;1d9j86z&quot; data-end=&quot;2524&quot; data-start=&quot;2497&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Stream-aligned team&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;2539&quot; data-start=&quot;2526&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;제품 기능을 담당하는 팀&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2542&quot; data-start=&quot;2541&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2557&quot; data-start=&quot;2544&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-section-id=&quot;cmbdfw&quot; data-end=&quot;2550&quot; data-start=&quot;2544&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;주문 팀&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;1x8r678&quot; data-end=&quot;2557&quot; data-start=&quot;2551&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;결제 팀&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-section-id=&quot;muw2gq&quot; data-end=&quot;2580&quot; data-start=&quot;2559&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Platform team&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;2611&quot; data-start=&quot;2582&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다른 팀들이 사용하는 &lt;b&gt;공통 플랫폼&lt;/b&gt;을 만드는 팀&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2614&quot; data-start=&quot;2613&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2640&quot; data-start=&quot;2616&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-section-id=&quot;16wjjgq&quot; data-end=&quot;2623&quot; data-start=&quot;2616&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;CI/CD&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;2jp0dk&quot; data-end=&quot;2629&quot; data-start=&quot;2624&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;인프라&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;j5glav&quot; data-end=&quot;2640&quot; data-start=&quot;2630&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클라우드 플랫폼&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-section-id=&quot;9obwm8&quot; data-end=&quot;2663&quot; data-start=&quot;2642&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Enabling team&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;2672&quot; data-start=&quot;2665&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기술 지원 팀&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2690&quot; data-start=&quot;2674&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;새 기술 도입을 도와주는 역할&lt;/span&gt;&lt;/p&gt;
&lt;h1 data-section-id=&quot;1ttgibo&quot; data-end=&quot;2717&quot; data-start=&quot;2697&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-section-id=&quot;1ttgibo&quot; data-end=&quot;2717&quot; data-start=&quot;2697&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-section-id=&quot;1ttgibo&quot; data-end=&quot;2717&quot; data-start=&quot;2697&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;8. 조직과 아키텍처를 함께 설계&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-end=&quot;2740&quot; data-start=&quot;2719&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-end=&quot;2777&quot; data-start=&quot;2742&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2777&quot; data-start=&quot;2744&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;소프트웨어 아키텍처와 조직 구조는 함께 설계해야 한다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2783&quot; data-start=&quot;2779&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;왜냐하면 앞서 설명해왔듯 시스템 구조, 팀 구조, 개발 프로세스가 서로 영향을 주기 때문이다. 예를 들어, 마이크로서비스를 도입했는데 팀이 하나뿐이라면 실제로는 효과가 없다. 그래서 다음과 같은 흐름으로 설계해야한다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;비즈니스 구조&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;darr;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;도메인 설계&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;darr;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;시스템 구조&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;darr;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;팀 구조&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2942&quot; data-start=&quot;2926&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-section-id=&quot;es1wrp&quot; data-end=&quot;2970&quot; data-start=&quot;2949&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-section-id=&quot;es1wrp&quot; data-end=&quot;2970&quot; data-start=&quot;2949&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-section-id=&quot;es1wrp&quot; data-end=&quot;2970&quot; data-start=&quot;2949&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;9. 아키텍처는 &amp;ldquo;의지&amp;rdquo;를 구현한다&lt;/span&gt;&lt;/h1&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-end=&quot;2985&quot; data-start=&quot;2972&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2997&quot; data-start=&quot;2987&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;여기서 내가 정의하는 &lt;b&gt;의지(意志)는 &lt;/b&gt;회사나 팀이 이루고 싶은 목표이다.&amp;nbsp; 예를 들어 조직이 다음과 같은 목표를 가지고 있다면, 이 목표가 아키텍처에 반영되어야한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3057&quot; data-start=&quot;3022&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-section-id=&quot;vhhszp&quot; data-end=&quot;3033&quot; data-start=&quot;3022&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;빠르게 기능 출시&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;jide7k&quot; data-end=&quot;3044&quot; data-start=&quot;3034&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;안정적인 서비스&lt;/span&gt;&lt;/li&gt;
&lt;li data-section-id=&quot;zige85&quot; data-end=&quot;3057&quot; data-start=&quot;3045&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;확장 가능한 시스템&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-end=&quot;3103&quot; data-start=&quot;3091&quot; data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;목표&amp;rarr; 빠른 개발&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;설계&amp;rarr; 작은 서비스 + 독립 팀&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;목표&amp;rarr; 높은 안정성&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;설계&amp;rarr; 강한 테스트 + 안정적 인프라&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-end=&quot;3168&quot; data-start=&quot;3167&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;즉 &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;아키텍처는 기술 선택이 아니라 &lt;/span&gt;&lt;b&gt;조직의 전략을 구현하는 구조이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3168&quot; data-start=&quot;3167&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-section-id=&quot;ppuml0&quot; data-end=&quot;3245&quot; data-start=&quot;3225&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-section-id=&quot;ppuml0&quot; data-end=&quot;3245&quot; data-start=&quot;3225&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;10. 레거시를 경쟁력으로 바꾸기&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-end=&quot;3277&quot; data-start=&quot;3247&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;레거시 시스템을 단순히 제거하는 것이 아니라 &lt;b&gt;경쟁력으로 바꾸는 것&lt;/b&gt;이 목표이다. 방법은 지금까지 설명해왔다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3348&quot; data-start=&quot;3317&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. 비즈니스 흐름 이해 (Event Storming)&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3366&quot; data-start=&quot;3350&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2. 도메인 설계 (DDD)&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3397&quot; data-start=&quot;3368&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;3. 팀 구조 설계 (Team Topologies)&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3413&quot; data-start=&quot;3399&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;4. 시스템 구조 재설계&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3451&quot; data-start=&quot;3415&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이렇게 &lt;b&gt;기술 + 조직 + 비즈니스&lt;/b&gt;를 함께 바꾸어야 레거시 프로그램이 경쟁력을 갖추게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3451&quot; data-start=&quot;3415&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-section-id=&quot;okswgo&quot; data-end=&quot;3466&quot; data-start=&quot;3458&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-section-id=&quot;okswgo&quot; data-end=&quot;3466&quot; data-start=&quot;3458&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-section-id=&quot;okswgo&quot; data-end=&quot;3466&quot; data-start=&quot;3458&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;11. 마무리&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-end=&quot;3512&quot; data-start=&quot;3480&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1.&amp;nbsp; AI 시대에는 &lt;b&gt;아키텍처 설계가 더 중요해진다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3553&quot; data-start=&quot;3514&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2.&amp;nbsp; 아키텍처 모더나이제이션은 &lt;b&gt;기술 교체 프로젝트가 아니다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3593&quot; data-start=&quot;3555&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;3. 시스템과 조직은 함께 설계해야 한다(소시오테크니컬 관점)&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3669&quot; data-start=&quot;3595&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;4. Event Storming / DDD / Team Topologies 같은 방법을 사용해 비즈니스와 시스템을 연결해야 한다&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3683&quot; data-start=&quot;3671&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;5. 결국 아키텍처는 &lt;b&gt;조직의 의지와 전략을 구현하는 것&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://speakerdeck.com/nwiizo/yi-zhi-woshi-zhuang-suruakitekutiyamodanaizesiyon&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://speakerdeck.com/nwiizo/yi-zhi-woshi-zhuang-suruakitekutiyamodanaizesiyon&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>IT/기초 지식</category>
      <author>개발자 두더지</author>
      <guid isPermaLink="true">https://engineer-mole.tistory.com/457</guid>
      <comments>https://engineer-mole.tistory.com/457#entry457comment</comments>
      <pubDate>Tue, 10 Mar 2026 21:47:22 +0900</pubDate>
    </item>
    <item>
      <title>의존성 주입 (DI: Dependency Injection)</title>
      <link>https://engineer-mole.tistory.com/456</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;DI의 탄생 경위&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;참고로 코드는 Kotlin으로 작성하도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;제일 먼저 DI를 하지 않고 어느 오브젝트 내에서 외부 오브젝트를 인스턴스화하는 경우를 살펴보도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773057562678&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Apple(val hasPoison: Boolean = false)

// 식품 클래스. 추상적인 개념이어야하지만 사과(Apple)에 의존해버리고 만다.
class Food {
    fun eat() {
        val apple = Apple(hasPoison = false)
        if (apple.hasPoison) {
            println(&quot;게임 오버&quot;)
        } else {
            println(&quot;사과 맛있다！&quot;)
        }
    }
}

class Human {
    // 이 메소드에서 eat()메소드를 호출. 테스크 코드에 해당하는 부분이기도 하다.
    fun doSomething() {
        val food = Food()
        food.eat()
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;doSomething() 실행 결과는 항상&lt;/span&gt; 동일하다. 위 코드는 Food클래스의&amp;nbsp;eat()메소드로, 외부의&amp;nbsp;Apple클래스를 인스턴스화하고 있다. 즉, &amp;nbsp;Food클래스의&amp;nbsp;eat()메소드는&amp;nbsp;Apple클래스에&amp;nbsp;&lt;b&gt;의존하고 있다. &lt;/b&gt;하지만 이것은 문제이다. 왜냐하면 eat()메소드의 처리 내용을 직접 편집하거나&amp;nbsp;Apple클래스를 편집하지 않는 한 eat() 메소드의 처리 결과는 변화하지 않기 때문이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 식품(Food)은 사과 이외에 바나나나 치즈도 있을 것이며, 한층 더 사과 안에도 독들이와 독 없음 2종류 있을 것인데, 식품(Food)를 먹을 때의 결과는 항상 같고, 유닛 테스트의 작성도 어렵다. &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;예를 들어, eat() 메소드내에서 if문에 문제가 없는지 등을 확인하기 위해서는 , Apple 클래스를 다시 작성할 수 밖에 없다. 그로인해 테스트 코드(doSomething() 메소드)만으로 테스트하는 것은 불가능하게 되어 버린다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&amp;nbsp;이러한 문제를 해결하기 위해 &amp;nbsp;eat() 메소드의 Apple 클래스에 대한&amp;nbsp;&lt;b&gt;의존성&lt;/b&gt;&amp;nbsp;을 일단 약하게 하고 나중에 주입하자라는 생각으로 이어지게 되었고, 이러한 경위로 의존성 주입이 탄생하게 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;b&gt;&amp;nbsp;즉 하나의 객체 A가 객체 B에 의존하는 경우, 즉 객체 A가 다른 객체 B를 가지는 것은 사용할 때의 유연성이나 테스트의 어려움의 관점에서 볼 때 좋지 않으므로, 먼저 오브젝트 A가 오브젝트 B를 가지지 않도록 하고 외부에서 오브젝트 A에 오브젝트 B를 주입해 주는 것이 DI의 아이디어이다.&lt;/b&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;DI의 간단한 예에 대해서 살펴보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773058895441&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Food클래스・eat()메소드의 Apple에 대한 의존성을 없애고, Food클래스・eat()메소드를 추상화
interface Food {
    fun eat()
}

// Food 인터페이스를 비준하여, eat()메소드를 Apple클래스용으로 구현한다.
class Apple(val hasPoison: Boolean) : Food {
    override fun eat() {
        if (hasPoison) {
            println(&quot;게임 오버&quot;)
        } else {
            println(&quot;사과 맛있다!&quot;)
        }
    }
}

class Human {
    // 이 메소드로 부터 eat()메소드를 호출. 테스트 코드에 해당하는 부분이기도 하다.
    fun doSomething() {
        val apple = Apple(hasPoison = false)
        val poisonApple = Apple(hasPoison = true)
        apple.eat()
        poisonApple.eat()
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; doSomething() 실행 결과는 다음과 같이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773058962920&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;사과 맛있다！ // apple.eat()의 실행결과
게임오버    　　　// poisonApple.eat()의 실행결과&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 덧붙여서, 식품(Food) 인터페이스는 사과(Apple)에 의존하지 않는 추상적인 개념이므로, 다음과 같이 바나나(Banana)도 만들 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773058991493&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Banana : Food {
    override fun eat() {
        println(&quot;바나나를 먹으면 힘이나&quot;)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; Banana().eat() 실행 결과는 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773059012173&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;바나나를 먹으면 힘이나&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;DI의 종류&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-sourcepos=&quot;198:1-206:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;198:1-200:137&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Interface Injection&lt;/b&gt;&amp;nbsp;: 바로 앞에서 살펴본 예가 여기에 해당한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 방법에서는 인터페이스, 즉 기초가 되는 메소드군을 정의해, 작성하는 클래스에 그 인터페이스를 비준시키는 것으로 DI를 구현한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Java / Kotlin에서는 인터페이스, Objective-C / Swift는 프로토콜이 인터페이스에 해당한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;201:1-202:176&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Constructor Injection&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;어떤 클래스 A의 생성자로서 그 변수 hoge 를 인스턴스화하는 것으로, 클래스 A에 Hoge 클래스의 「의존성」을 「주입」한다&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;203:1-206:0&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Setter Injection&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;한 클래스 내의 프로퍼티에 다른 클래스의 인스턴스가 되는 것을 선언만 해 두어(var hoge: Hoge?)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;외부로부터 액세스 가능한 setter 메소드 경유로 hoge 를 인스턴스화하는 방법으로, Hoge 클래스의 「의존성」을 「주입」한다&lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&quot;의존성&quot;의 의미&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;의존성이라는 단어로 인해 이해하기 어려운 느낌이므로 다음과 같이 생각해보았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;의존성 주입에서의 &quot;의존성 = 객체 &quot;. 영어판 Wikipedia에는 의존성을 객체라고 정의하고 있다. 즉, &quot;의존성=인스턴스&quot;,&amp;nbsp; &quot;의존성=Java / Kotlin 등이라면&amp;nbsp;interface에서 정의 된 메소드의 처리 내용을 실제로 기술하고있는 메소드&quot;, &quot;의존성 =Objective-C/Swift에서 말하는 것을&amp;nbsp;protocol비준하고 있는 클래스내에서 처리 내용을 실제로 기술하고 있는 델리게이트 메소드&quot;가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;다음엔 주입이라는 단어를 덧붙어 의존성 주입이라는 단어를 바꿔보도록하겠다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&quot;의존성 주입&quot;이란&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-sourcepos=&quot;268:1-268:212&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;(오브젝트 A의 외부로부터) 「오브젝트 A에서 필요한, 오브젝트 B의 객체(인스턴스나 구체적인 메소드)」를 「주입/대입/설정/제공」하는 것이다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-sourcepos=&quot;270:1-271:84&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;라고 말을 더해 설명할 수 있겠다. 덧붙여 여기서 객체는 클래스나 메소드에 해당한다. 하지만 이것만으로는, 아직 뭐야라고 생각할지도 모른다. 앞에서 설명한 3가지 DI 방법을 의존성 정의에 따라 다음과 같이 따라 바꿔 보았다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-sourcepos=&quot;278:1-285:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;278:1-279:150&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Interface Injection&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;메소드 A가 정의된 인터페이스를 비준한 클래스 B로, 메소드 A의 구체적인 처리를 구현하는 것이다&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;280:1-281:130&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Constructor Injection&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클래스 A의 생성자로 클래스 B를 설정하고 클래스 A 생성시 클래스 B를 구현하는 것이다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;282:1-285:0&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Setter Injection&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;먼저 클래스 A의 속성으로 클래스 B를 설정하고 클래스 B의 setter 메서드도 정의한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그리고 클래스 A 생성 후 클래스 B의 setter 메서드를 호출하여 클래스 B를 구현하는 것이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1773059574966&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface Food {
    fun eat()  // &amp;lt;- 메소드A
}

// Apple &amp;lt;- 클래스B
class Apple(val hasPoison: Boolean) : Food {
    // 여기서「메소드A의 구체적인 처리를 구현」
    override fun eat() {
        if (hasPoison) {
            println(&quot;게임 오버&quot;)
        } else {
            println(&quot;사과 맛있다!&quot;)
        }
    }
}


class Human {
    // 이 메소드에서 eat()메소드를 호출. 테스트 코드에 해당하는 부분도 있다.
    fun doSomething() {
        val apple = Apple(hasPoison = false)
        val poisonApple = Apple(hasPoison = true)
        apple.eat()
        poisonApple.eat()
    }
}&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;DI의 장점&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;마지막으로 지금까지 중간 중간에 설명했던 DI의 장점을 모두 정리하도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-sourcepos=&quot;325:3-327:55&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;325:3-325:64&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;결합 정도의 저하에 의한 컴포넌트화 촉진&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;326:3-326:31&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;단위 테스트 효율성&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;327:3-327:55&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;특정 프레임워크에 대한 의존도 감소&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://qiita.com/iTakahiro/items/353a11f6c9d2a927158d&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://qiita.com/iTakahiro/items/353a11f6c9d2a927158d&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>IT/기초 지식</category>
      <author>개발자 두더지</author>
      <guid isPermaLink="true">https://engineer-mole.tistory.com/456</guid>
      <comments>https://engineer-mole.tistory.com/456#entry456comment</comments>
      <pubDate>Mon, 9 Mar 2026 21:34:15 +0900</pubDate>
    </item>
    <item>
      <title>VSCode(Visual Studio Code)의 GitHub Copilot SKILL.md</title>
      <link>https://engineer-mole.tistory.com/455</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;시작하기 전에&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; copilot-instructions.md 하나에 많은 정보를 제공할 수 있지만. 그 때문에 추론에 사용하는 모델의 성능이 낮거나, 한 번의 세션에서 대화가 오래 지속되면 처음에 말했던 내용이나, 애초에 copilot-instructions.md에 정의하고 있던 것을 잊어버리는 경우 생긴다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;또한, 제공한 많은 맥락이 잡음이 되어 추론에 시간이 오래 걸리거나 엉뚱한 답을 내는 경우도 있었습니다. 그런 문제를 보완하기 위해 SKILL.md를 활용할 수 있다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Agent Skills란?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; &amp;nbsp;에이전트 스킬은 Copilot이 관련된 경우에 불러올 수 있는 명령, 스크립트 및 리소스 폴더이며, 특수 작업의 성능을 향상시킵니다. 에이전트 스킬은 다양한 에이전트에서 사용되는 표준이다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&amp;nbsp;스킬이라는 이름만 듣자면 어떤 도구를 사용하는 능력이나 도구 자체를 정의하는 것처럼 들리지만, 실제로는 프로젝트의 도메인 지식 등을 넣는 것이 가장 일반적인 사용 방법이다. &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;실제로 어떤 식으로 사용되는지 소개하도록 하겠다. &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;아래가 SKILL.md 중 하나이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1772019323135&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;---
name: testing
설명: TooMe's Task App (Web)의 테스트 전략. Vitest, React Testing Library, MSW를 사용한 단위&amp;middot;컴포넌트 테스트에 대해 설명. 테스트를 만들 때 참고.
---

# 테스트 전략

## 기술 스택

- **단위 테스트**: Vitest
- **컴포넌트 테스트**: React Testing Library + user-event
- **API Mock**: MSW (Mock Service Worker)
- **E2E테스트**: Playwright / Cypress
- **훅 테스트**: `@testing-library/react-hooks` (또는 RTL의 `renderHook`)

## 유닛 테스트 (Utils / Hooks / Stores)

- 순수 함수 utils, 커스텀 훅,USTStand 스토어 로직을 검증한다
- 비동기 처리를 포함하는 경우에는 `대기`와 `act`를 적절히 사용한다

```typescript
// stores/authStore.test.ts
import { describe, it, expect, beforeEach } from 'vitest';
import { renderHook, act } from '@testing-library/react';
import { useAuthStore } from './authStore';

describe('useAuthStore', () =&amp;gt; {
beforeEach(() =&amp;gt; {
const { result } = renderHook(() =&amp;gt; useAuthStore());
act(() =&amp;gt; result.current.logout());
});

it('should set user and authentication status', () =&amp;gt; {
const { result } = renderHook(() =&amp;gt; useAuthStore());
const mockUser = { uid: '123', email: 'test@example.com' };

act(() =&amp;gt; {
result.current.setUser(mockUser as any);
});

expect(result.current.user).toEqual(mockUser);
expect(result.current.isAuthenticated).toBe(true);
});
});
```

## 컴포넌트 테스트 (UI / 통합)

- 사용자 인터랙션(클릭, 입력)을 `user-event`로 시뮬레이션한다
- 구현 상세가 아니라 사용자가 볼 수 있는 행동(접근성 속성이나 텍스트)을 테스트한다

```typescript
// features/task/components/TaskInput.test.tsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { TaskInput } from './TaskInput';
import { vi } from 'vitest';

describe('TaskInput', () =&amp;gt; {
it('calls onSubmit with input text when enter is pressed', async () =&amp;gt; {
const handleCreate = vi.fn();
const user = userEvent.setup();

render(&amp;lt;TaskInput onCreate={handleCreate} /&amp;gt;);

const input = screen.getByRole('textbox', { name: /タスクを入力/i });

// 입력 및 전송 시뮬레이션
await user.type(input, 'New Task{enter}');

expect(handleCreate).toHaveBeenCalledWith('New Task');
expect(input). &amp;forall; 값(''); // 전송 후 클리어 확인
});
});
```

## API 목업 (MSW)

- 컴포넌트 테스트나 통합 테스트에서 API 응답이 필요할 경우 MSW를 사용한다
- 실제 네트워크 요청이 발생하지 않도록 한다

```typescript
// tests/mocks/handlers.ts
import { http, HttpResponse } from 'msw';

export const handlers = [
http.get('/api/tasks', () =&amp;gt; {
return HttpResponse.json([
{ id: '1', title: 'Buy milk', completed: false },
{ id: '2', title: 'Walk the dog', completed: true },
]);
}),
];
```

## E2E 테스트

- 비판적인 사용자 여정(로그인 &amp;rarr; 작업 생성 &amp;rarr; 완료)를 검증한다
Playwright 또는 Cypress를 사용해 실제 브라우저 환경에서 동작을 확인한다

## 테스트 베스트 프랙티스

- **AAA 패턴**: Arrange (준비), Act (실행), Assert (검증) 을 의식한다
- **쿼리 우선순위**: `getByRole` &amp;gt; `getByLabelText` &amp;gt; `getByText` &amp;gt; `getByTestId` 순서대로 요소를 가져온다
- **비동기 대기**: 데이터를 가져오는 대기 등에는 `await screenfindBy...` 또는 `대기` 를 사용한다&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;md 파일의 시작 부분에는 특징적인 파티션이 있으며, 그곳에 name과 description이 설정되어 있다. &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;간단히 이 파라미터들에 대해 설명하도록 하겠다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;파라미터명&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;내용&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;name&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; SKILL.md 가 있는 디렉터리 이름. 디렉터리 구조에 대해서는 뒤에서 설명하도록 하겠다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;description&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 스킬의 기능과 사용 시점을 설명한다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; GitHub Copilot은 각 SKILL.md를 필요에 따라 불러와 작업을 실행한다. 필요에 따라 설명을 디스크립션으로 정의하는 이미지를 떠올리면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;앞서 예시에서는 다음과 같이 description을 정의했다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;TooMe's Task App (Web)의 테스트 전략. Vitest, React Testing Library, MSW를 사용한 단위&amp;middot;컴포넌트 테스트에 대해 설명. 테스트를 만들 때 참고.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그래서 테스트 관련 작업을 실행할 때 이 SKILL.md읽게 된다. 이를 통해 주요 copilot-instructions.md 테스트 전략과 관련된 컨텍스트를 분리된다. 더욱이, 이 분리된 컨텍스트는 필요에 따라만 읽히게 된다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-sourcepos=&quot;158:1-158:37&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;SKILL.md의 작성법, 사용법&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-sourcepos=&quot;159:1-159:64&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. vsode의 설정에서 chat.useAgentSkills을 유효화&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-sourcepos=&quot;159:1-159:64&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;설정 단축키를 누른 후, chat.userAgentSkills를 입력한 후 유효화&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 2. 다음과 같은 디렉터리 구조로 각 SKILL.md를 정의&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이렇게 하면 GitHub Copilot이 필요에 따라 필요한 SKILL.md 참고하게 된다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;물론 여기서 정의한 디렉터리는 예시일 뿐이므로, 프로젝트에 따라 원하는 만큼 새 디렉터리를 만들고 그 안에 SKILL.md를 추가해도 괜찮다. 즉, 아래와 &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;같은 구성을 하지 않아도, vscode의 chat.agentSkillsLocations를 설정하면 원하는 디렉터리 구성을 만들 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1772019662089&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.github
│── skills
│   ├── architecture
│   │   └── SKILL.md
│   ├── ui-design
│   │   └── SKILL.md
│   ├── state-managment
│   │   └── SKILL.md
│   ├── backend-integration
│   │   └── SKILL.md
│   ├── coding-standards
│   │   └── SKILL.md
│   └── testing
│       └── SKILL.md
└── copilot-instructions.md&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;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;이로 인해 copilot-instructins.md도 매우 깔끔해진다. 다음과 같이 말이다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1772019753454&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Copilot Instructions for TooMe's Task App (Web)

## 전제 조건

- **답변은 반드시 한국어로 해 주세요. **
- 코드를 변경할 때, 변경량이 200줄을 초과할 가능성이 높다면, 사전에 &amp;ldquo;이 지시에서는 변경량이 200줄을 초과할 가능성이 있습니다만, 실행하시겠습니까?&amp;rdquo;라고 사용자에게 확인하도록 해 주세요.
- 큰 변화를 주고자 할 경우, 먼저 무엇을 할지 계획을 세운 뒤, 사용자에게 &amp;ldquo;이와 같은 계획으로 진행하려고 합니다.&amp;rdquo;라고 제안해 주세요.

## 참고 스킬 가이드 (Skills)

특정 작업을 실행할 때는 반드시 아래의 해당 문서를 참고하고, 그 지침을 따르세요.

- **아키텍처 디렉터리 구성**
- 파일 배치, 모듈 구성, 기능 분리
-   `.github/skills/architecture/SKILL.md`

- **UI 구현&amp;middot;스타일링**
- Tailwind CSS, 컴포넌트 설계, 접근성 (a11y)
-   `.github/skills/ui-design/SKILL.md`

#### 생략&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;마무리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; GitHub Copilot의 최신 기능인 Agent Skills를 활용하고, SKILL.md를이용해 이전보다 더욱 강력하게 GitHub Copilot을 활용하는 방법을 소개했다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;여러분도 꼭 자신의 프로젝트에 Agent Skills를 도입해, &amp;lsquo;그 정도로 뛰어난 어시스턴트&amp;rsquo;를 &amp;lsquo;믿을 수 있는 에이전트&amp;rsquo;로 키워 보길 바란다. &lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;참고자료&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://qiita.com/TooMe/items/230a730ce0387c77e822&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://qiita.com/TooMe/items/230a730ce0387c77e822&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>IT/코딩툴</category>
      <author>개발자 두더지</author>
      <guid isPermaLink="true">https://engineer-mole.tistory.com/455</guid>
      <comments>https://engineer-mole.tistory.com/455#entry455comment</comments>
      <pubDate>Wed, 25 Feb 2026 20:45:46 +0900</pubDate>
    </item>
    <item>
      <title>MyNavi 전직 페어 (MyNavi転職フェア)  참가 후기</title>
      <link>https://engineer-mole.tistory.com/454</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;작년 말에 최근 일본 엔지니어 이직 동향이나 분위기 파악을 위해 MyNavi 전직 페어를 참가했었기에 관련 후기를 짧막하게 공유하고자한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;MyNavi 전직 페어는 다양한 지역에서 동시에 개최되고 있고 경우에 따라 엔지니어 메인이라던가 테마가 정해지는 경우가 있다. 전직 페어 개최 장소랑 참가 기업은 아래의 MyNavi 전직 페어 사이트에서 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1769943005109&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;転職フェア・イベントならマイナビ転職～日本最大級の転職セミナー | 転職サイトは【マイナ&quot; data-og-description=&quot;マイナビ転職の転職フェア・イベント(合同企業説明会)は全国各地で開催！　企業との出合いはもちろん、キャリアアドバイザーとの面談など転職支援サービスが充実、あなたの転職活動を&quot; data-og-host=&quot;tenshoku.mynavi.jp&quot; data-og-source-url=&quot;https://tenshoku.mynavi.jp/event/&quot; data-og-url=&quot;https://tenshoku.mynavi.jp/event/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/CFwGU/dJMb86nSytb/EmGeuPYc4nZ7QdwGecMvG0/img.jpg?width=600&amp;amp;height=315&amp;amp;face=0_0_600_315,https://scrap.kakaocdn.net/dn/bPb3EW/dJMb83SdQk8/DYmkvJpcHoR8IKwJpRwGB0/img.png?width=950&amp;amp;height=330&amp;amp;face=0_0_950_330,https://scrap.kakaocdn.net/dn/bASbug/dJMb86OWPyK/hku91W3pXTkQsAbucBtZCk/img.png?width=206&amp;amp;height=334&amp;amp;face=0_0_206_334&quot;&gt;&lt;a href=&quot;https://tenshoku.mynavi.jp/event/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://tenshoku.mynavi.jp/event/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/CFwGU/dJMb86nSytb/EmGeuPYc4nZ7QdwGecMvG0/img.jpg?width=600&amp;amp;height=315&amp;amp;face=0_0_600_315,https://scrap.kakaocdn.net/dn/bPb3EW/dJMb83SdQk8/DYmkvJpcHoR8IKwJpRwGB0/img.png?width=950&amp;amp;height=330&amp;amp;face=0_0_950_330,https://scrap.kakaocdn.net/dn/bASbug/dJMb86OWPyK/hku91W3pXTkQsAbucBtZCk/img.png?width=206&amp;amp;height=334&amp;amp;face=0_0_206_334');&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;転職フェア・イベントならマイナビ転職～日本最大級の転職セミナー | 転職サイトは【マイナ&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;マイナビ転職の転職フェア・イベント(合同企業説明会)は全国各地で開催！　企業との出合いはもちろん、キャリアアドバイザーとの面談など転職支援サービスが充実、あなたの転職活動を&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;tenshoku.mynavi.jp&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;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;내가 참가했던 전직 페어는 작년인 25년 11월 29일 토요일 신주쿠에서 엔지니어 전직 응원 테마로 열린 행사였다. 일단 참가하기 위해 MyNavi 전직 어플리케이션을 다운 받아야할 필요가 있다. 어플리케이션 다운로드 후 회원가입은 물론 이력서와 같이 이직에 필요한 정보를 입력해야한다.&amp;nbsp; 그 후엔 お役立ち탭 &amp;gt; 개최 목록에서 참가하고 싶은 행사를 선택, 사전 신청 혹은 캔슬 버튼을 누르면 끝이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20260201_202619023.png&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;2556&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdTPtp/dJMcai9XCUV/X9qH9d2y1rAj2FHADhsJG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdTPtp/dJMcai9XCUV/X9qH9d2y1rAj2FHADhsJG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdTPtp/dJMcai9XCUV/X9qH9d2y1rAj2FHADhsJG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdTPtp%2FdJMcai9XCUV%2FX9qH9d2y1rAj2FHADhsJG0%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;1179&quot; height=&quot;2556&quot; data-filename=&quot;KakaoTalk_20260201_202619023.png&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;2556&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;행사 당일 장소에 가면, 먼저 이력서를 출력해야한다. 어플리케이션을 기동한 다음 신청시에 들어갔었던 お役立ち탭에 들어간 후 QR코드 표시 버튼을 누르면 QR코드가 표시되는데, 컴퓨터와 프린터기가 나열되어 있는 곳으로 가서 이 QR코드를 스캔하여 이력서를 출력하면 된다. 출력 후 입장 전 설명을 위해 잠시 대기하게 되고 설명이 끝나면 본격적으로 입장을 하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;Type 전직 페어와 다른 점이라고 하면 입장하면 MyNavi전직 페어 직원이 1:1로 붙어 이벤트 개요를 설명해주고, 기업 부스로 안내를 해준다는 점이다. 어떤 이직 기준으로 기업을 찾고 있는지 질문을 해오는데 그 질문에 대해 대답을하면 참가한 기업 중 관련 기업 목록을 보여주고, 상담하고 싶은 기업이 있다고하면 그 기업 부스로 안내해주는 형식이다. 기업 부스로 안내된 뒤 상담이 끝나면 다시 찾아와달라고 했는데, 나는 굳이 다시 찾진 않았다.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;아무튼 기업 부스로 가면 이력서를 건낸 뒤 바로 회사 인사부 직원이나 현직 엔지니어분이랑 대화를 나누게 되는데, 채용 면접을 진행하는 기업은 없었으며 기업이나 지금 채용하고 있는 포지션에 대한 설명을 듣고 질의응답하는 형식이었다. 그리고 마지막에 기업에 대한 흥미가 있다면 어떤 방식으로 지원하면 되는지에 대한 안내를 받게 된다. 처음에 낸 이력서를 돌려 받는 경우도 있고, 기업 측에서 회수하는 경우도 있다. 아, 혹시 기업 부스의 상담이 만석이라면, 그 뒤 의자에 앉아 대기하게 된다.&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;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;나는 당시 한 열군데 정도의 부스에 들렸었다. 그 중 관심이 생긴 기업은 세 군데였고, 하고 싶은 일이나 기업 분위기에 맞을 거 같다고 느낀 딱 한 곳 마이나비 전직 홈페이지를 통해 지원을 했었다. 결과는 서류 불합격이라 나의 착각이었구나 했지만,&amp;nbsp; 현재 일본 채용 분위기를 느낄 수 있었다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;내가 당시 느낀 최근 일본 채용 분위기는 금융 프로젝트관련된 엔지니어 혹은 인프라 엔지니어를 많이 원하는 느낌이었다. 금융 기업(은행, 증권사) 프로젝트 엔지니어를 구인하는 기업이 굉장히 많았고, 프로그래밍 보다는 기반을 구축하는 인프라 엔지니어 포지션이 많이 열려 있었다. &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;뉴스나 각 종 매체를 통해 현재 일본은 투자, 주식관련된 관심이 한국보다는 아니지만 조금씩 증가하고 있어 이런 고객을 잡기 위해 새로운 어플리케이션이나 기반 만들려고 하는 움직임이나 개선을 시행하고 있다고 봤는데 이 움직임이 일본 엔지니어 채용 세계에 큰 영향을 주고 있구나를 체감하게 됐다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;</description>
      <category>개인 기록/도전과 성장</category>
      <author>개발자 두더지</author>
      <guid isPermaLink="true">https://engineer-mole.tistory.com/454</guid>
      <comments>https://engineer-mole.tistory.com/454#entry454comment</comments>
      <pubDate>Sun, 1 Feb 2026 20:25:11 +0900</pubDate>
    </item>
  </channel>
</rss>