<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>호구마츄로그</title>
    <link>https://hogumachu.tistory.com/</link>
    <description>iOS 및 개발에 대한 글을 작성합니다</description>
    <language>ko</language>
    <pubDate>Sun, 12 Apr 2026 09:48:00 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>호구마츄</managingEditor>
    <image>
      <title>호구마츄로그</title>
      <url>https://tistory1.daumcdn.net/tistory/4983513/attach/5e31ad4a181a4e538e79ed18fabb4591</url>
      <link>https://hogumachu.tistory.com</link>
    </image>
    <item>
      <title>2024 회고</title>
      <link>https://hogumachu.tistory.com/44</link>
      <description>&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2024에는 많은 일이 있었다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;특히 기존에 겪었던 환경과 매우 다른 환경의 회사에 입사하게 되었고 이를 통해 많은 것을 경험하였다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;1. 새로운 회사 그리고 새로운 사람들 그리고 새로운 불만&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;긴 이직 준비를 끝으로 5월에 새로운 회사에 입사할 수 있었다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;전에 다녔던 회사와는 굉장히 달랐다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;스타트업에서 직급이 있는 회사로 가게 되었고 많은 부분에 불만이 많아졌다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;커뮤니케이션에 정말 불필요한 리소스를 쏟아야 하는 것이 싫었다. 특히 담당자에게 직접 이야기하기 어려운 경우와 담당자가 누구인지 파악하기 어려울 때 정말 현타가 왔다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;일정 또한 기획과 디자인이 나왔는데 ASAP..? 이게 가능한가&amp;hellip; 회사를 봉사 차원에서 운영하는 것인가 하는 생각이 들었다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;의사결정 또한 이해가 안되는 것이 많았다. 이미 결정되었는데 회의를 하는 이유가 무엇일까? 그냥 통보해 주면 되는데.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;의사결정에 &amp;lsquo;그냥&amp;rsquo;, &amp;lsquo;뭔가&amp;rsquo; &amp;lsquo;약간&amp;rsquo; 이라는 말을 하는 이유가 무엇인가? 이러한 이야기를 듣고 나도 그냥 뭔가 약간 답답했다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;A/B Test나 Analytics는 왜 활용은 안 할까? 일정이 병목이 되었다면 어떤 곳에서 병목 있는지 확인을 해야 하는데 단순히 가장 마지막 결과물이 나오는 모바일 팀에 프레셔가 들어와야 하는가?&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;정말 셀 수 없는 많은 불만이 있었지만 기술적으로 하고 싶은 것은 다 할 수 있어서 좋았다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2. iOS 개발자&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;입사했을 당시 iOS 앱은 존재하지 않았고 안드로이드 앱만 존재했다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 1년 정도 먼저 개발되었으며 iOS 팀도 내가 최초였다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;새로운 프로젝트를 위해 설계 및 여러 작업을 해야 했으며 추후 들어올 팀원을 위해 문서화 및 최대한 불편하지 않게 하기 위해 했다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;의사 결정에 대해서는 모두 ADR을 작성하였고 가이드라인 등 여러 문서화를 꼼꼼하게 하였다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다행히 새로오신 분도 잘 적응하시고 함께 열심히 서비스를 만들었다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;몇 개월 정신없이 기능 개발을 하니 iOS 개발자로서 도파민이 굉장히 떨어졌다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;전 회사에서는 업무를 스프린트 방식으로 진행하고 정말 야근도 하며 서비스를 만들고 데이터도 함께 보며 개선점을 이야기를 했는데 현재는 칼퇴에 업무 기간은 그냥 내가 정하면 된다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러다 보니 열심히 해야겠다는 동력이 많이 사라졌다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3. 그럼에도&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;내가 어떤 사람들과 일을 하고 싶은지 알게 되었다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 그렇지 않은 사람들과 함께 일을 하며 상생하는 방법을 조금 알게 되었다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;정말 커뮤니케이션의 중요성을 뼈저리게 느꼈으며 초등학생이 이해할 수 있을 정도로 설명해줘야 한다는 것도 느꼈다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;모든 사람이 일을 통해 성취감을 얻으려 하지 않고 일은 그냥 일이다라고 생각하는 사람도 많았으며 열심히 일을 하는 사람을 좋지 않은 시선으로 보는 사람도 있었다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;굉장히 많은 불만이 생겼지만 나와 비슷하게 불만이 있지만 젠틀하게 이를 해결하는 사람도 있었다. 그는 나에게 &amp;lsquo;지금 개발로서 배우는 것이 적을 수는 있어도 이러한 사람들에게 잘 설명하고 이야기할 수 있는 것도 개발자로서의 역량이고 이를 키울 수 있는 좋은 기회다.&amp;rsquo;라고 얘기해 주었다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;불만이 많이 생겼지만 그 안에서 배우는 것도 많이 생겼다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;4. 2025년에는&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;커뮤니케이션 역량을 더 키우고 싶다. 초등학생도 이해할 수 있도록 잘 대화하고 싶다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사이드 프로젝트를 크게 하나 하고 싶다. 단발성이 아닌 지속 가능한 것으로.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Analytics를 꼭 추가할 수 있도록 필요성에 대한 설득을 해야겠다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;블로그 글을 더 자주 발행 해야겠다.&lt;/p&gt;</description>
      <category>잡담</category>
      <category>2024 회고</category>
      <category>IOS</category>
      <category>회고</category>
      <author>호구마츄</author>
      <guid isPermaLink="true">https://hogumachu.tistory.com/44</guid>
      <comments>https://hogumachu.tistory.com/44#entry44comment</comments>
      <pubDate>Sun, 29 Dec 2024 14:41:21 +0900</pubDate>
    </item>
    <item>
      <title>클린 아키텍처 반드시 필요한가? (Mobile)</title>
      <link>https://hogumachu.tistory.com/43</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;굉장히 어그로성이 강한 제목이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;클린 아키텍처는 왜 이리 인기가 많을까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;그리고 모두에게 필요한 것일까?&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;initial_Sv7Ih8iLAxtgzg8UqE1z_block&quot;&gt;
&lt;div data-block-content=&quot;initial_Sv7Ih8iLAxtgzg8UqE1z_block&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;initial_Sv7Ih8iLAxtgzg8UqE1z_text&quot;&gt;&lt;span data-offset-key=&quot;initial_Sv7Ih8iLAxtgzg8UqE1z_text:0&quot;&gt;최근 (아마도 오래 전부터) 에 모바일 개발에는 대부분 클린 아키텍처로 되어있다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;w0XHa36TczS7&quot;&gt;
&lt;div data-block-content=&quot;w0XHa36TczS7&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;gpXV4riUR5o1&quot;&gt;&lt;span data-offset-key=&quot;gpXV4riUR5o1:0&quot;&gt;왜 이렇게 인기가 많을까?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div data-block-content=&quot;w0XHa36TczS7&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;Zc9HmJlDQKkC&quot;&gt;
&lt;div data-block-content=&quot;Zc9HmJlDQKkC&quot;&gt;
&lt;h3 id=&quot;undefined&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span data-key=&quot;RqasfFp55la1&quot;&gt;&lt;span data-offset-key=&quot;RqasfFp55la1:0&quot;&gt;클린 아키텍처가 인기가 많은 이유&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;E3tQ9ueYT5e5&quot;&gt;
&lt;div data-block-content=&quot;E3tQ9ueYT5e5&quot;&gt;
&lt;h4 id=&quot;undefined-1&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span data-key=&quot;LtTrWvilOTOJ&quot;&gt;&lt;span data-offset-key=&quot;LtTrWvilOTOJ:0&quot;&gt;확장성과 유연성이 뛰어나다&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;UChNoEMghpO3&quot;&gt;
&lt;div data-block-content=&quot;UChNoEMghpO3&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;aBiLoRMInLmF&quot;&gt;&lt;span data-offset-key=&quot;aBiLoRMInLmF:0&quot;&gt;말 그대로 클린 아키텍처는 확장성과 유연성이 뛰어나다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;ZIW6q2pWH9be&quot;&gt;
&lt;div data-block-content=&quot;ZIW6q2pWH9be&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;4J7mq6nNfcZT&quot;&gt;&lt;span data-offset-key=&quot;4J7mq6nNfcZT:0&quot;&gt;즉 쉽게 변경할 수 있고 테스트에 용이하다. (의존성 역전)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;mKyFsVAWt0Dy&quot;&gt;
&lt;div data-block-content=&quot;mKyFsVAWt0Dy&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;7MJ1vq7tUTOO&quot;&gt;&lt;span data-offset-key=&quot;7MJ1vq7tUTOO:0&quot;&gt;Domain과 Data Layer 를 잘 분리하여 서버의 응답이 변경 되어도 쉽게 반영할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;wNKm7nqfyTfb&quot;&gt;
&lt;div data-block-content=&quot;wNKm7nqfyTfb&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;aq0YdbSBUZoZ&quot;&gt;&lt;span data-offset-key=&quot;aq0YdbSBUZoZ:0&quot;&gt;이것만 봐도 굉장한 장점이다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div data-block-content=&quot;wNKm7nqfyTfb&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;XbGlbcy3ubeB&quot;&gt;
&lt;div data-block-content=&quot;XbGlbcy3ubeB&quot;&gt;
&lt;h4 id=&quot;undefined-2&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span data-key=&quot;2COLWZFvhMAz&quot;&gt;&lt;span data-offset-key=&quot;2COLWZFvhMAz:0&quot;&gt;멋지다&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;LIuJ2YljdjFI&quot;&gt;
&lt;div data-block-content=&quot;LIuJ2YljdjFI&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;7SqrWiaBQ7ZB&quot;&gt;&lt;span data-offset-key=&quot;7SqrWiaBQ7ZB:0&quot;&gt;일단 뭔가 멋지다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;87jgCypcMA9W&quot;&gt;
&lt;div data-block-content=&quot;87jgCypcMA9W&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;hEuqqvGtufRs&quot;&gt;&lt;span data-offset-key=&quot;hEuqqvGtufRs:0&quot;&gt;클린 코드 책과 더불어 클린 아키텍처 책도 굉장히 인기가 많다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;zqcifQ7l7UF9&quot;&gt;
&lt;div data-block-content=&quot;zqcifQ7l7UF9&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;8EgYNmM3mhVD&quot;&gt;&lt;span data-offset-key=&quot;8EgYNmM3mhVD:0&quot;&gt;책이 먼저인지 아니면 아키텍처 자체가 먼저 유명해진 것인지는 중요하지 않다. 일단 멋지다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div data-block-content=&quot;zqcifQ7l7UF9&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;1gFssJqjaH4z&quot;&gt;
&lt;div data-block-content=&quot;1gFssJqjaH4z&quot;&gt;
&lt;h3 id=&quot;undefined-3&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span data-key=&quot;12BWflRmMlLI&quot;&gt;&lt;span data-offset-key=&quot;12BWflRmMlLI:0&quot;&gt;클린 아키텍처는 과연 모두에게 멋진가?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;SKTXp6QAPbVW&quot;&gt;
&lt;div data-block-content=&quot;SKTXp6QAPbVW&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;bghZcTS9SANx&quot;&gt;&lt;span data-offset-key=&quot;bghZcTS9SANx:0&quot;&gt;'클린 아키텍처가 모두에게 잘 어울리는 아키텍처인가' 라는 생각이 든다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;o9KkBliMmvWU&quot;&gt;
&lt;div data-block-content=&quot;o9KkBliMmvWU&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;TXDCsjkJcnAR&quot;&gt;&lt;span data-offset-key=&quot;TXDCsjkJcnAR:0&quot;&gt;정말 작은 앱을 확장성이 매우 뛰어난 앱으로 만드는 것이 과연 좋은 것인가?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;Za1HVC2H7c5i&quot;&gt;
&lt;div data-block-content=&quot;Za1HVC2H7c5i&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;ZuefG3J3txiB&quot;&gt;&lt;span data-offset-key=&quot;ZuefG3J3txiB:0&quot;&gt;클린 아키텍처를 반영하다보면 종종 UseCase가 단순 Repository에 있는 데이터를 변경만 해주고 있다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;tOevEjs1VTVg&quot;&gt;
&lt;div data-block-content=&quot;tOevEjs1VTVg&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;OkrQMFwArC92&quot;&gt;&lt;span data-offset-key=&quot;OkrQMFwArC92:0&quot;&gt;API Response가 변경이 되면 Entity도 변경이 된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;UjqQzOOuvQbg&quot;&gt;
&lt;div data-block-content=&quot;UjqQzOOuvQbg&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;oE2n72jorHVA&quot;&gt;&lt;span data-offset-key=&quot;oE2n72jorHVA:0&quot;&gt;즉 클라이언트-서버의 관계가 강하게 결합이 되었다는 의미이다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-slate-fragment=&quot;JTdCJTIyb2JqZWN0JTIyJTNBJTIyZG9jdW1lbnQlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQyVCNSU5QyVFQSVCNyVCQyUyMCglRUMlOTUlODQlRUIlQTclODglRUIlOEYlODQlMjAlRUMlOTglQTQlRUIlOUUlOTglMjAlRUMlQTAlODQlRUIlQjYlODAlRUQlODQlQjApJTIwJUVDJTk3JTkwJTIwJUVCJUFBJUE4JUVCJUIwJTk0JUVDJTlEJUJDJTIwJUVBJUIwJTlDJUVCJUIwJTlDJUVDJTk3JTkwJUVCJThBJTk0JTIwJUVCJThDJTgwJUVCJUI2JTgwJUVCJUI2JTg0JTIwJUVEJTgxJUI0JUVCJUE2JUIwJTIwJUVDJTk1JTg0JUVEJTgyJUE0JUVEJTg1JThEJUVDJUIyJTk4JUVCJUExJTlDJTIwJUVCJTkwJTk4JUVDJTk2JUI0JUVDJTlFJTg4JUVCJThCJUE0LiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyOHo3SzFFWFNyYUlNJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyR2lBU0xRdFROV3p5JTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUMlOTklOUMlMjAlRUMlOUQlQjQlRUIlQTAlODclRUElQjIlOEMlMjAlRUMlOUQlQjglRUElQjglQjAlRUElQjAlODAlMjAlRUIlQTclOEUlRUMlOUQlODQlRUElQjklOEMlM0YlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMmdwWFY0cmlVUjVvMSUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMncwWEhhMzZUY3pTNyUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMmhlYWRpbmctMiUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJUVEJTgxJUI0JUVCJUE2JUIwJTIwJUVDJTk1JTg0JUVEJTgyJUE0JUVEJTg1JThEJUVDJUIyJTk4JUVBJUIwJTgwJTIwJUVDJTlEJUI4JUVBJUI4JUIwJUVBJUIwJTgwJTIwJUVCJUE3JThFJUVDJTlEJTgwJTIwJUVDJTlEJUI0JUVDJTlDJUEwJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJScWFzZkZwNTVsYTElMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJaYzlIbUpsRFFLa0MlMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJoZWFkaW5nLTMlMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFRCU5OSU5NSVFQyU5RSVBNSVFQyU4NCVCMSVFQSVCMyVCQyUyMCVFQyU5QyVBMCVFQyU5NyVCMCVFQyU4NCVCMSVFQyU5RCVCNCUyMCVFQiU5QiVCMCVFQyU5NiVCNCVFQiU4MiU5OCVFQiU4QiVBNCUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyTHRUcld2aWxPVE9KJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyRTN0UTl1ZVlUNWU1JTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUIlQTclOTAlMjAlRUElQjclQjglRUIlOEMlODAlRUIlQTElOUMlMjAlRUQlODElQjQlRUIlQTYlQjAlMjAlRUMlOTUlODQlRUQlODIlQTQlRUQlODUlOEQlRUMlQjIlOTglRUIlOEElOTQlMjAlRUQlOTklOTUlRUMlOUUlQTUlRUMlODQlQjElRUElQjMlQkMlMjAlRUMlOUMlQTAlRUMlOTclQjAlRUMlODQlQjElRUMlOUQlQjQlMjAlRUIlOUIlQjAlRUMlOTYlQjQlRUIlODIlOTglRUIlOEIlQTQuJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJhQmlMb1JNSW5MbUYlMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJVQ2hOb0VNZ2hwTzMlMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQyVBNiU4OSUyMCVFQyU4OSVCRCVFQSVCMiU4QyUyMCVFQiVCMyU4MCVFQSVCMiVCRCVFRCU5NSVBMCUyMCVFQyU4OCU5OCUyMCVFQyU5RSU4OCVFQSVCMyVBMCUyMCVFRCU4NSU4QyVFQyU4QSVBNCVFRCU4QSVCOCVFQyU5NyU5MCUyMCVFQyU5QSVBOSVFQyU5RCVCNCVFRCU5NSU5OCVFQiU4QiVBNC4lMjAoJUVDJTlEJTk4JUVDJUExJUI0JUVDJTg0JUIxJTIwJUVDJTk3JUFEJUVDJUEwJTg0KSUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyNEo3bXE2bk5mY1pUJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyWklXNnEycFdIOWJlJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjJEb21haW4lRUElQjMlQkMlMjBEYXRhJTIwTGF5ZXIlMjAlRUIlQTUlQkMlMjAlRUMlOUUlOTglMjAlRUIlQjYlODQlRUIlQTYlQUMlRUQlOTUlOTglRUMlOTclQUMlMjAlRUMlODQlOUMlRUIlQjIlODQlRUMlOUQlOTglMjAlRUMlOUQlOTElRUIlOEIlQjUlRUMlOUQlQjQlMjAlRUIlQjMlODAlRUElQjIlQkQlMjAlRUIlOTAlOTglRUMlOTYlQjQlRUIlOEYlODQlMjAlRUMlODklQkQlRUElQjIlOEMlMjAlRUIlQjAlOTglRUMlOTglODElRUQlOTUlQTAlMjAlRUMlODglOTglMjAlRUMlOUUlODglRUIlOEIlQTQuJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjI3TUoxdnE3dFVUT08lMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJtS3lGc1ZBV3QwRHklMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQyU5RCVCNCVFQSVCMiU4MyVFQiVBNyU4QyUyMCVFQiVCNCU5MCVFQiU4RiU4NCUyMCVFQSVCNSU4OSVFQyU5RSVBNSVFRCU5NSU5QyUyMCVFQyU5RSVBNSVFQyVBMCU5MCVFQyU5RCVCNCVFQiU4QiVBNC4lMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMmFxMFlkYlNCVVpvWiUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMndOS203bnFmeVRmYiUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMmhlYWRpbmctMyUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJUVCJUE5JThCJUVDJUE3JTgwJUVCJThCJUE0JTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjIyQ09MV1pGdmhNQXolMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJYYkdsYmN5M3ViZUIlMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQyU5RCVCQyVFQiU4QiVBOCUyMCVFQiVBRCU5NCVFQSVCMCU4MCUyMCVFQiVBOSU4QiVFQyVBNyU4MCVFQiU4QiVBNC4lMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMjdTcXJXaWFCUTdaQiUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMkxJdUoyWWxqZGpGSSUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJUVEJTgxJUI0JUVCJUE2JUIwJTIwJUVDJUJEJTk0JUVCJTkzJTlDJTIwJUVDJUIxJTg1JUVBJUIzJUJDJTIwJUVCJThEJTk0JUVCJUI2JTg4JUVDJTk2JUI0JTIwJUVEJTgxJUI0JUVCJUE2JUIwJTIwJUVDJTk1JTg0JUVEJTgyJUE0JUVEJTg1JThEJUVDJUIyJTk4JTIwJUVDJUIxJTg1JUVCJThGJTg0JTIwJUVBJUI1JTg5JUVDJTlFJUE1JUVEJTlFJTg4JTIwJUVDJTlEJUI4JUVBJUI4JUIwJUVBJUIwJTgwJTIwJUVCJUE3JThFJUVCJThCJUE0LiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyaEV1cXF2R3R1ZlJzJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyODdqZ0N5cGNNQTlXJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUMlQjElODUlRUMlOUQlQjQlMjAlRUIlQTglQkMlRUMlQTAlODAlRUMlOUQlQjglRUMlQTclODAlMjAlRUMlOTUlODQlRUIlOEIlODglRUIlQTklQjQlMjAlRUMlOTUlODQlRUQlODIlQTQlRUQlODUlOEQlRUMlQjIlOTglMjAlRUMlOUUlOTAlRUMlQjIlQjQlRUElQjAlODAlMjAlRUIlQTglQkMlRUMlQTAlODAlMjAlRUMlOUMlQTAlRUIlQUElODUlRUQlOTUlQjQlRUMlQTclODQlMjAlRUElQjIlODMlRUMlOUQlQjglRUMlQTclODAlRUIlOEElOTQlMjAlRUMlQTQlOTElRUMlOUElOTQlRUQlOTUlOTglRUMlQTclODAlMjAlRUMlOTUlOEElRUIlOEIlQTQuJTIwJUVDJTlEJUJDJUVCJThCJUE4JTIwJUVCJUE5JThCJUVDJUE3JTgwJUVCJThCJUE0LiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyOEVnWU5tTTNtaFZEJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyenFjaWZRN2w3VUY5JTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIyaGVhZGluZy0yJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUQlODElQjQlRUIlQTYlQjAlMjAlRUMlOTUlODQlRUQlODIlQTQlRUQlODUlOEQlRUMlQjIlOTglRUIlOEElOTQlMjAlRUElQjMlQkMlRUMlOTclQjAlMjAlRUIlQUElQTglRUIlOTElOTAlRUMlOTclOTAlRUElQjIlOEMlMjAlRUIlQTklOEIlRUMlQTclODQlRUElQjAlODAlM0YlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMjEyQldmbFJtTWxMSSUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMjFnRnNzSnFqYUg0eiUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJyVFRCU4MSVCNCVFQiVBNiVCMCUyMCVFQyU5NSU4NCVFRCU4MiVBNCVFRCU4NSU4RCVFQyVCMiU5OCVFQSVCMCU4MCUyMCVFQiVBQSVBOCVFQiU5MSU5MCVFQyU5NyU5MCVFQSVCMiU4QyUyMCVFQyU5RSU5OCUyMCVFQyU5NiVCNCVFQyU5QSVCOCVFQiVBNiVBQyVFQiU4QSU5NCUyMCVFQyU5NSU4NCVFRCU4MiVBNCVFRCU4NSU4RCVFQyVCMiU5OCVFQyU5RCVCOCVFQSVCMCU4MCclMjAlRUIlOUQlQkMlRUIlOEElOTQlMjAlRUMlODMlOUQlRUElQjAlODElRUMlOUQlQjQlMjAlRUIlOTMlQTAlRUIlOEIlQTQuJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJiZ2haY1RTOVNBTnglMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJTS1RYcDZRQVBiVlclMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQyVBMCU5NSVFQiVBNyU5MCUyMCVFQyU5RSU5MSVFQyU5RCU4MCUyMCVFQyU5NSVCMSVFQyU5RCU4NCUyMCVFRCU5OSU5NSVFQyU5RSVBNSVFQyU4NCVCMSVFQyU5RCVCNCUyMCVFQiVBNyVBNCVFQyU5QSVCMCUyMCVFQiU5QiVCMCVFQyU5NiVCNCVFQiU4MiU5QyUyMCVFQyU5NSVCMSVFQyU5QyVCQyVFQiVBMSU5QyUyMCVFQiVBNyU4QyVFQiU5MyU5QyVFQiU4QSU5NCUyMCVFQSVCMiU4MyVFQyU5RCVCNCUyMCVFQSVCMyVCQyVFQyU5NyVCMCUyMCVFQyVBMiU4QiVFQyU5RCU4MCUyMCVFQSVCMiU4MyVFQyU5RCVCOCVFQSVCMCU4MCUzRiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyVFhEQ3Nqa0pjbkFSJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIybzlLa0JsaU1tdldVJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUQlODElQjQlRUIlQTYlQjAlMjAlRUMlOTUlODQlRUQlODIlQTQlRUQlODUlOEQlRUMlQjIlOTglRUIlQTUlQkMlMjAlRUIlQjAlOTglRUMlOTglODElRUQlOTUlOTglRUIlOEIlQTQlRUIlQjMlQjQlRUIlQTklQjQlMjAlRUMlQTIlODUlRUMlQTIlODUlMjBVc2VDYXNlJUVBJUIwJTgwJTIwJUVCJThCJUE4JUVDJTg4JTlDJTIwUmVwb3NpdG9yeSVFQyU5NyU5MCUyMCVFQyU5RSU4OCVFQiU4QSU5NCUyMCVFQiU4RCVCMCVFQyU5RCVCNCVFRCU4NCVCMCVFQiVBNSVCQyUyMCVFQiVCMyU4MCVFQSVCMiVCRCVFQiVBNyU4QyUyMCVFRCU5NSVCNCVFQyVBMyVCQyVFQSVCMyVBMCUyMCVFQyU5RSU4OCVFQiU4QiVBNC4lMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMlp1ZWZHM0ozdHhpQiUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMlphMUhWQzJIN2M1aSUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyQVBJJTIwUmVzcG9uc2UlRUElQjAlODAlMjAlRUIlQjMlODAlRUElQjIlQkQlRUMlOUQlQjQlMjAlRUIlOTAlOTglRUIlQTklQjQlMjBFbnRpdHklRUIlOEYlODQlMjAlRUIlQjMlODAlRUElQjIlQkQlRUMlOUQlQjQlMjAlRUIlOTAlOUMlRUIlOEIlQTQuJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJPa3JRTUZ3QXJDOTIlMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJ0T2V2RWpzMVZUVmclMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQyVBNiU4OSUyMCVFRCU4MSVCNCVFQiU5RCVCQyVFQyU5RCVCNCVFQyU5NiVCOCVFRCU4QSVCOC0lRUMlODQlOUMlRUIlQjIlODQlRUMlOUQlOTglMjAlRUElQjQlODAlRUElQjMlODQlRUElQjAlODAlMjAlRUElQjAlOTUlRUQlOTUlOTglRUElQjIlOEMlMjAlRUElQjIlQjAlRUQlOTUlQTklRUMlOUQlQjQlMjAlRUIlOTAlOTglRUMlOTclODglRUIlOEIlQTQlRUIlOEElOTQlMjAlRUMlOUQlOTglRUIlQUYlQjglRUMlOUQlQjQlRUIlOEIlQTQuJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJvRTJuNzJqb3JIVkElMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJVanFRek9PdXZRYmclMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQSVCMyVCQyVFQyU5NyVCMCUyMCVFQyU5RCVCNCVFQiU5RiVCMCUyMCVFQyU4MyU4MSVFRCU5OSVBOSVFQyU5NyU5MCVFQyU4NCU5QyUyMERvbWFpbiUyMExheWVyJUVCJThBJTk0JTIwJUVEJTk1JTg0JUVDJTg4JTk4JUVDJUEwJTgxJUVDJTlDJUJDJUVCJUExJTlDJTIwJUVDJUExJUI0JUVDJTlFJUFDJUVEJTk1JUI0JUVDJTk1JUJDJTIwJUVEJTk1JTk4JUVCJThBJTk0JUVBJUIwJTgwJTNGJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjIyd2c2blB4NWJBenUlMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJXYmdFYVJFUnpSY1MlMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJNeFNQVVRCMFVLZzMlMjIlN0Q=&quot; data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;WbgEaRERzRcS&quot;&gt;
&lt;div data-block-content=&quot;WbgEaRERzRcS&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;2wg6nPx5bAzu&quot;&gt;&lt;span data-offset-key=&quot;2wg6nPx5bAzu:0&quot;&gt;과연 이런 상황에서 Domain Layer는 필수적으로 존재해야 하는가?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-block-content=&quot;WbgEaRERzRcS&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;i5QDHtA30Hsw&quot;&gt;
&lt;div data-block-content=&quot;i5QDHtA30Hsw&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span data-key=&quot;SV5NmTuaXvGE&quot;&gt;&lt;span data-offset-key=&quot;SV5NmTuaXvGE:0&quot;&gt;클린 아키텍처가 필요 없는 경우&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;15KPGkfEvAjB&quot;&gt;
&lt;div data-block-content=&quot;15KPGkfEvAjB&quot;&gt;
&lt;h4 id=&quot;api-response-entity&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span data-key=&quot;DKLJXiVFZ8MW&quot;&gt;&lt;span data-offset-key=&quot;DKLJXiVFZ8MW:0&quot;&gt;API Response가 변경될 때 매번 Entity도 함께 변경되는 경우&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;rzFC9wadT8jM&quot;&gt;
&lt;div data-block-content=&quot;rzFC9wadT8jM&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;OPmLO6vMEOJC&quot;&gt;&lt;span data-offset-key=&quot;OPmLO6vMEOJC:0&quot;&gt;물론 기능이 변경된 경우는 당연히 변경되는 것이 맞지만, 매번 변경이 된다면 이는 과연 필요한 것인가?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div data-block-content=&quot;rzFC9wadT8jM&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;TGRuBLcM9ZTH&quot;&gt;
&lt;div data-block-content=&quot;TGRuBLcM9ZTH&quot;&gt;
&lt;h4 id=&quot;usecase-repository&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span data-key=&quot;UQxSXEylCyst&quot;&gt;&lt;span data-offset-key=&quot;UQxSXEylCyst:0&quot;&gt;UseCase가 단순히 Repository의 결과 값을 전달만 해주는 경우&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;zuca82es5JwW&quot;&gt;
&lt;div data-block-content=&quot;zuca82es5JwW&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;SzzBtBJAA4HE&quot;&gt;&lt;span data-offset-key=&quot;SzzBtBJAA4HE:0&quot;&gt;UseCase에서 아무 로직이 없고 Repository의 결과만 전달해주는 경우 굳이 없어도 되지 않을까?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div data-block-content=&quot;zuca82es5JwW&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;G9LVW0mfne0x&quot;&gt;
&lt;div data-block-content=&quot;G9LVW0mfne0x&quot;&gt;
&lt;h4 id=&quot;usecase-repository-entity-model-dto&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span data-key=&quot;txNH8bOxoXkW&quot;&gt;&lt;span data-offset-key=&quot;txNH8bOxoXkW:0&quot;&gt;그냥 이유 없이 UseCase, Repository, Entity, Model, DTO... 등 나누고 있을 때&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;WwBtdvKSh549&quot;&gt;
&lt;div data-block-content=&quot;WwBtdvKSh549&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;qCok2sGF3inU&quot;&gt;&lt;span data-offset-key=&quot;qCok2sGF3inU:0&quot;&gt;여기서 이유 없이라 함은 클린 아키텍처에 대한 니즈가 없지만 단순히 트렌드를 따라가는 것을 의미한다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;u8D9wdi3jpap&quot;&gt;
&lt;div data-block-content=&quot;u8D9wdi3jpap&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;PKHVJYxSDFJb&quot;&gt;&lt;span data-offset-key=&quot;PKHVJYxSDFJb:0&quot;&gt;모듈화, 테스트 코드 등 해당 아키텍처에 대한 활용이 없다면 단순히 앱을 복잡하게 만드는 것이 아닐까?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div data-block-content=&quot;u8D9wdi3jpap&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;p6PQtirRnsoB&quot;&gt;
&lt;div data-block-content=&quot;p6PQtirRnsoB&quot;&gt;
&lt;h4 id=&quot;undefined-5&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span data-key=&quot;nLOBYJhFPea3&quot;&gt;&lt;span data-offset-key=&quot;nLOBYJhFPea3:0&quot;&gt;개발자가 적을 때&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;wt6cfdQ06x8W&quot;&gt;
&lt;div data-block-content=&quot;wt6cfdQ06x8W&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;uptiC5ysFZSY&quot;&gt;&lt;span data-offset-key=&quot;uptiC5ysFZSY:0&quot;&gt;전체적인 개발자가 적을 때는 굳이 복잡한 아키텍처를 선택할 필요가 없다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;1OzhglI4nwh6&quot;&gt;
&lt;div data-block-content=&quot;1OzhglI4nwh6&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;3kecswPJeUte&quot;&gt;&lt;span data-offset-key=&quot;3kecswPJeUte:0&quot;&gt;어차피 내가 개발하거나 내 옆에 사람이 개발할 것인데 굳이 복잡하게 나눌 필요가 있을까?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-slate-fragment=&quot;JTdCJTIyb2JqZWN0JTIyJTNBJTIyZG9jdW1lbnQlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJoZWFkaW5nLTIlMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFRCU4MSVCNCVFQiVBNiVCMCUyMCVFQyU5NSU4NCVFRCU4MiVBNCVFRCU4NSU4RCVFQyVCMiU5OCVFQSVCMCU4MCUyMCVFRCU5NSU4NCVFQyU5QSU5NCVFQyU5NyU4NiVFQiU4QSU5NCUyMCVFQSVCMiVCRCVFQyU5QSVCMCUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIya3RmUTNvREUyWUNwJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyMjJhZVVoa0U4c3YyJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIyaGVhZGluZy0zJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjJBUEklMjBSZXNwb25zZSVFQSVCMCU4MCUyMCVFQiVCMyU4MCVFQSVCMiVCRCVFQiU5MCVBMCUyMCVFQiU5NSU4QyUyMCVFQiVBNyVBNCVFQiVCMiU4OCUyMEVudGl0eSVFQiU4RiU4NCUyMCVFRCU5NSVBOCVFQSVCQiU5OCUyMCVFQiVCMyU4MCVFQSVCMiVCRCVFQiU5MCU5OCVFQiU4QSU5NCUyMCVFQSVCMiVCRCVFQyU5QSVCMCUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyREtMSlhpVkZaOE1XJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyMTVLUEdrZkV2QWpCJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUIlQUMlQkMlRUIlQTElQTAlMjAlRUElQjglQjAlRUIlOEElQTUlRUMlOUQlQjQlMjAlRUIlQjMlODAlRUElQjIlQkQlRUIlOTAlOUMlMjAlRUElQjIlQkQlRUMlOUElQjAlRUIlOEElOTQlMjAlRUIlOEIlQjklRUMlOTclQjAlRUQlOUUlODglMjAlRUIlQjMlODAlRUElQjIlQkQlRUIlOTAlOTglRUIlOEElOTQlMjAlRUElQjIlODMlRUMlOUQlQjQlMjAlRUIlQTclOUUlRUMlQTclODAlRUIlQTclOEMlMkMlMjAlRUIlQTclQTQlRUIlQjIlODglMjAlRUIlQjMlODAlRUElQjIlQkQlRUMlOUQlQjQlMjAlRUIlOTAlOUMlRUIlOEIlQTQlRUIlQTklQjQlMjAlRUMlOUQlQjQlRUIlOEElOTQlMjAlRUElQjMlQkMlRUMlOTclQjAlMjAlRUQlOTUlODQlRUMlOUElOTQlRUQlOTUlOUMlMjAlRUElQjIlODMlRUMlOUQlQjglRUElQjAlODAlM0YlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMk9QbUxPNnZNRU9KQyUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMnJ6RkM5d2FkVDhqTSUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMmhlYWRpbmctMyUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyVXNlQ2FzZSVFQSVCMCU4MCUyMCVFQiU4QiVBOCVFQyU4OCU5QyVFRCU5RSU4OCUyMFJlcG9zaXRvcnklRUMlOUQlOTglMjAlRUElQjIlQjAlRUElQjMlQkMlMjAlRUElQjAlOTIlRUMlOUQlODQlMjAlRUMlQTAlODQlRUIlOEIlQUMlRUIlQTclOEMlMjAlRUQlOTUlQjQlRUMlQTMlQkMlRUIlOEElOTQlMjAlRUElQjIlQkQlRUMlOUElQjAlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMlVReFNYRXlsQ3lzdCUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMlRHUnVCTGNNOVpUSCUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyVXNlQ2FzZSVFQyU5NyU5MCVFQyU4NCU5QyUyMCVFQyU5NSU4NCVFQiVBQyVCNCUyMCVFQiVBMSU5QyVFQyVBNyU4MSVFQyU5RCVCNCUyMCVFQyU5NyU4NiVFQSVCMyVBMCUyMFJlcG9zaXRvcnklRUMlOUQlOTglMjAlRUElQjIlQjAlRUElQjMlQkMlRUIlQTclOEMlMjAlRUMlQTAlODQlRUIlOEIlQUMlRUQlOTUlQjQlRUMlQTMlQkMlRUIlOEElOTQlMjAlRUElQjIlQkQlRUMlOUElQjAlMjAlRUElQjUlQjMlRUMlOUQlQjQlMjAlRUMlOTclODYlRUMlOTYlQjQlRUIlOEYlODQlMjAlRUIlOTAlOTglRUMlQTclODAlMjAlRUMlOTUlOEElRUMlOUQlODQlRUElQjklOEMlM0YlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMlN6ekJ0QkpBQTRIRSUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMnp1Y2E4MmVzNUp3VyUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMmhlYWRpbmctMyUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJUVBJUI3JUI4JUVCJTgzJUE1JTIwJUVDJTlEJUI0JUVDJTlDJUEwJTIwJUVDJTk3JTg2JUVDJTlEJUI0JTIwVXNlQ2FzZSUyQyUyMFJlcG9zaXRvcnklMkMlMjBFbnRpdHklMkMlMjBNb2RlbCUyQyUyMERUTy4uLiUyMCVFQiU5MyVCMSUyMCVFQiU4MiU5OCVFQiU4OCU4NCVFQSVCMyVBMCUyMCVFQyU5RSU4OCVFQyU5RCU4NCUyMCVFQiU5NSU4QyUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIydHhOSDhiT3hvWGtXJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyRzlMVlcwbWZuZTB4JTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUMlOTclQUMlRUElQjglQjAlRUMlODQlOUMlMjAlRUMlOUQlQjQlRUMlOUMlQTAlMjAlRUMlOTclODYlRUMlOUQlQjQlRUIlOUQlQkMlMjAlRUQlOTUlQTglRUMlOUQlODAlMjAlRUQlODElQjQlRUIlQTYlQjAlMjAlRUMlOTUlODQlRUQlODIlQTQlRUQlODUlOEQlRUMlQjIlOTglRUMlOTclOTAlMjAlRUIlOEMlODAlRUQlOTUlOUMlMjAlRUIlOEIlODglRUMlQTYlODglRUElQjAlODAlMjAlRUMlOTclODYlRUMlQTclODAlRUIlQTclOEMlMjAlRUIlOEIlQTglRUMlODglOUMlRUQlOUUlODglMjAlRUQlOEElQjglRUIlQTAlOEMlRUIlOTMlOUMlRUIlQTUlQkMlMjAlRUIlOTQlQjAlRUIlOUQlQkMlRUElQjAlODAlRUIlOEElOTQlMjAlRUElQjIlODMlRUMlOUQlODQlMjAlRUMlOUQlOTglRUIlQUYlQjglRUQlOTUlOUMlRUIlOEIlQTQuJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJxQ29rMnNHRjNpblUlMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJXd0J0ZHZLU2g1NDklMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQiVBQSVBOCVFQiU5MyU4OCVFRCU5OSU5NCUyQyUyMCVFRCU4NSU4QyVFQyU4QSVBNCVFRCU4QSVCOCUyMCVFQyVCRCU5NCVFQiU5MyU5QyUyMCVFQiU5MyVCMSUyMCVFRCU5NSVCNCVFQiU4QiVCOSUyMCVFQyU5NSU4NCVFRCU4MiVBNCVFRCU4NSU4RCVFQyVCMiU5OCVFQyU5NyU5MCUyMCVFQiU4QyU4MCVFRCU5NSU5QyUyMCVFRCU5OSU5QyVFQyU5QSVBOSVFQyU5RCVCNCUyMCVFQyU5NyU4NiVFQiU4QiVBNCVFQiVBOSVCNCUyMCVFQiU4QiVBOCVFQyU4OCU5QyVFRCU5RSU4OCUyMCVFQyU5NSVCMSVFQyU5RCU4NCUyMCVFQiVCMyVCNSVFQyU5RSVBMSVFRCU5NSU5OCVFQSVCMiU4QyUyMCVFQiVBNyU4QyVFQiU5MyU5QyVFQiU4QSU5NCUyMCVFQSVCMiU4MyVFQyU5RCVCNCUyMCVFQyU5NSU4NCVFQiU4QiU5MCVFQSVCOSU4QyUzRiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyUEtIVkpZeFNERkpiJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIydThEOXdkaTNqcGFwJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIyaGVhZGluZy0zJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUElQjAlOUMlRUIlQjAlOUMlRUMlOUUlOTAlRUElQjAlODAlMjAlRUMlQTAlODElRUMlOUQlODQlMjAlRUIlOTUlOEMlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMm5MT0JZSmhGUGVhMyUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMnA2UFF0aXJSbnNvQiUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJUVDJUEwJTg0JUVDJUIyJUI0JUVDJUEwJTgxJUVDJTlEJUI4JTIwJUVBJUIwJTlDJUVCJUIwJTlDJUVDJTlFJTkwJUVBJUIwJTgwJTIwJUVDJUEwJTgxJUVDJTlEJTg0JTIwJUVCJTk1JThDJUVCJThBJTk0JTIwJUVBJUI1JUIzJUVDJTlEJUI0JTIwJUVCJUIzJUI1JUVDJTlFJUExJUVEJTk1JTlDJTIwJUVDJTk1JTg0JUVEJTgyJUE0JUVEJTg1JThEJUVDJUIyJTk4JUVCJUE1JUJDJTIwJUVDJTg0JUEwJUVEJTgzJTlEJUVEJTk1JUEwJTIwJUVEJTk1JTg0JUVDJTlBJTk0JUVBJUIwJTgwJTIwJUVDJTk3JTg2JUVCJThCJUE0LiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIydXB0aUM1eXNGWlNZJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyd3Q2Y2ZkUTA2eDhXJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUMlOTYlQjQlRUMlQjAlQTglRUQlOTQlQkMlMjAlRUIlODIlQjQlRUElQjAlODAlMjAlRUElQjAlOUMlRUIlQjAlOUMlRUQlOTUlOTglRUElQjElQjAlRUIlODIlOTglMjAlRUIlODIlQjQlMjAlRUMlOTglODYlRUMlOTclOTAlMjAlRUMlODIlQUMlRUIlOUUlOEMlRUMlOUQlQjQlMjAlRUElQjAlOUMlRUIlQjAlOUMlRUQlOTUlQTAlMjAlRUElQjIlODMlRUMlOUQlQjglRUIlOEQlQjAlMjAlRUElQjUlQjMlRUMlOUQlQjQlMjAlRUIlQjMlQjUlRUMlOUUlQTElRUQlOTUlOTglRUElQjIlOEMlMjAlRUIlODIlOTglRUIlODglOEMlMjAlRUQlOTUlODQlRUMlOUElOTQlRUElQjAlODAlMjAlRUMlOUUlODglRUMlOUQlODQlRUElQjklOEMlM0YlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMjNrZWNzd1BKZVV0ZSUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMjFPemhnbEk0bndoNiUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJUVDJTg2JThDJUVDJTg4JTk4JUVDJTlEJTk4JTIwJUVDJTlEJUI4JUVDJTlCJTkwJUVDJTlEJUI0JUVCJTlEJUJDJUVCJUE5JUI0JTIwJUVBJUI3JUI4JUVCJTkzJUE0JUVCJUE3JThDJUVDJTlEJTk4JTIwJUVCJUEzJUIwJUVDJTlEJTg0JTIwJUVCJUE3JThDJUVCJTkzJUE0JUVBJUIzJUEwJTIwJUVDJUI2JTk0JUVEJTlCJTg0JTIwJUVDJTlDJUEwJUVDJUE3JTgwJUVCJUIzJUI0JUVDJTg4JTk4JUVCJUE3JThDJTIwJUVDJTgzJTlEJUVBJUIwJTgxJUVEJTk1JTk4JUVCJUE5JUI0JTIwJUVBJUI0JTlDJUVDJUIwJUFFJUVDJUE3JTgwJTIwJUVDJTk1JThBJUVDJTlEJTg0JUVBJUI5JThDJTIwJUVDJThCJUI2JUVCJThCJUE0LiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyZ1pvelFUSjY2Q3FUJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIybGh1QTAyZFZEMXZaJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIySGVSeFB3eHc2YjRIJTIyJTdE&quot; data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;lhuA02dVD1vZ&quot;&gt;
&lt;div data-block-content=&quot;lhuA02dVD1vZ&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;gZozQTJ66CqT&quot;&gt;&lt;span data-offset-key=&quot;gZozQTJ66CqT:0&quot;&gt;소수의 인원이라면 그들만의 룰을 만들고 추후 유지보수만 생각하면 괜찮지 않을까 싶다.&lt;/span&gt;&lt;/span&gt;&lt;/span&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&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;LfTtB4FzG4iA&quot;&gt;
&lt;div data-block-content=&quot;LfTtB4FzG4iA&quot;&gt;
&lt;h3 id=&quot;undefined-6&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span data-key=&quot;yXQnK3Qmyz7k&quot;&gt;&lt;span data-offset-key=&quot;yXQnK3Qmyz7k:0&quot;&gt;그냥 주저리 주저리&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;20LXqY1vlmhB&quot;&gt;
&lt;div data-block-content=&quot;20LXqY1vlmhB&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;nyNnlYH7CTKs&quot;&gt;&lt;span data-offset-key=&quot;nyNnlYH7CTKs:0&quot;&gt;클린 아키텍처를 사용해야만 확장이 가능하며 테스트가 가능한 것이 아니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;vqeJ6hVm3S0c&quot;&gt;
&lt;div data-block-content=&quot;vqeJ6hVm3S0c&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;Hz3gb3l1Xlln&quot;&gt;&lt;span data-offset-key=&quot;Hz3gb3l1Xlln:0&quot;&gt;의존성 주입을 잘하고, 필요에 따라 Helper 객체를 주입해주면 잘 분리되지 않을까?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;TVDa8IjgfdNI&quot;&gt;
&lt;div data-block-content=&quot;TVDa8IjgfdNI&quot;&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span&gt;&lt;span data-key=&quot;qXiGCxC0ISe5&quot;&gt;&lt;span data-offset-key=&quot;qXiGCxC0ISe5:0&quot;&gt;&lt;span data-slate-zero-width=&quot;n&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;usMCO9tDr1og&quot;&gt;
&lt;div data-block-content=&quot;usMCO9tDr1og&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;SeiLATj893b2&quot;&gt;&lt;span data-offset-key=&quot;SeiLATj893b2:0&quot;&gt;근래에 자꾸 클린 아키텍처를 신봉하는 사람이 많아져서 반발 심리가 도진다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;Q1TXtrrNhzsq&quot;&gt;
&lt;div data-block-content=&quot;Q1TXtrrNhzsq&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;O9Rqz4uhkTez&quot;&gt;&lt;span data-offset-key=&quot;O9Rqz4uhkTez:0&quot;&gt;그러나 결국 회사에서는 클린 아키텍처로 설계하고 있는 내 모습  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;KXLNLZySlBBY&quot;&gt;
&lt;div data-block-content=&quot;KXLNLZySlBBY&quot;&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span&gt;&lt;span data-key=&quot;WAdGy5KjVQdu&quot;&gt;&lt;span data-offset-key=&quot;WAdGy5KjVQdu:0&quot;&gt;&lt;span data-slate-zero-width=&quot;n&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;RY7xkwwuPYHH&quot;&gt;
&lt;div data-block-content=&quot;RY7xkwwuPYHH&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;0ALTS3koT1Fw&quot;&gt;&lt;span data-offset-key=&quot;0ALTS3koT1Fw:0&quot;&gt;개인적으로 앱에 있는 기능이 꽤 오래 살아서 새로운 기능이 덕지덕지 붙을 가능성이 있으면 클린 아키텍처&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;KlE7gcJ3290u&quot;&gt;
&lt;div data-block-content=&quot;KlE7gcJ3290u&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;nY67mjxRAeSQ&quot;&gt;&lt;span data-offset-key=&quot;nY67mjxRAeSQ:0&quot;&gt;진짜 너무 린해서 기능을 업데이트하기 보다 새로 만든다면 그냥 테스트나 확장 가능성 버리고 빨리 만드는 것도 하나의 방법 같다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;qGD1YKrQ6CA5&quot;&gt;
&lt;div data-block-content=&quot;qGD1YKrQ6CA5&quot;&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span&gt;&lt;span data-key=&quot;MttMaesAXhup&quot;&gt;&lt;span data-offset-key=&quot;MttMaesAXhup:0&quot;&gt;&lt;span data-slate-zero-width=&quot;n&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;ylcJg8kGQtBe&quot;&gt;
&lt;div data-block-content=&quot;ylcJg8kGQtBe&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;SbO1kf3JGnzv&quot;&gt;&lt;span data-offset-key=&quot;SbO1kf3JGnzv:0&quot;&gt;그럼 다들 이렇게 말하는 사람도 있겠지? '테스트 코드를 작성해야 오히려 개발이 더 빠르다'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;TnLrMrFqoIhL&quot;&gt;
&lt;div data-block-content=&quot;TnLrMrFqoIhL&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;lPV0wRuAHr2s&quot;&gt;&lt;span data-offset-key=&quot;lPV0wRuAHr2s:0&quot;&gt;어느정도 동의는 하는데 전제조건이 필요하다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;S33uNUi8sJ8S&quot;&gt;
&lt;div data-block-content=&quot;S33uNUi8sJ8S&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;OKS8qmcMfcdD&quot;&gt;&lt;span data-offset-key=&quot;OKS8qmcMfcdD:0&quot;&gt;일단 사용자가 많아야 된다. (보통 QA 팀이 다 걸러주더라  )&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;VwLizYoAzX42&quot;&gt;
&lt;div data-block-content=&quot;VwLizYoAzX42&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;umCvQJAd9NJo&quot;&gt;&lt;span data-offset-key=&quot;umCvQJAd9NJo:0&quot;&gt;또한 기능을 금방 버리는데 테스트 코드를 빡세게 짜면 그냥 테스트 코드를 짠 시간을 버리는 느낌이 든다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;5bZnPK6Jf4Hs&quot;&gt;
&lt;div data-block-content=&quot;5bZnPK6Jf4Hs&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;gfj3Kcp04NP9&quot;&gt;&lt;span data-offset-key=&quot;gfj3Kcp04NP9:0&quot;&gt;기능이 변경이 된다면, 테스트 코드도 바꿔줘야 한다. TC가 많다면? 그냥 가끔 현타온다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;t1fX2nXvCb7y&quot;&gt;
&lt;div data-block-content=&quot;t1fX2nXvCb7y&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;WCzpkqNhVxlV&quot;&gt;&lt;span data-offset-key=&quot;WCzpkqNhVxlV:0&quot;&gt;코드에 애정을 주지 말라는 얘기가 있는데 나는 사랑쟁이인가보다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;fJD1LM4YF2SS&quot;&gt;
&lt;div data-block-content=&quot;fJD1LM4YF2SS&quot;&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;span&gt;&lt;span data-key=&quot;DW69A294EAig&quot;&gt;&lt;span data-offset-key=&quot;DW69A294EAig:0&quot;&gt;&lt;span data-slate-zero-width=&quot;n&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;0FXCnspBgUUH&quot;&gt;
&lt;div data-block-content=&quot;0FXCnspBgUUH&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;cBqShgvLhgcf&quot;&gt;&lt;span data-offset-key=&quot;cBqShgvLhgcf:0&quot;&gt;그래도 테스트 코드는 작성한다. 안그러면 나중에 변경사항이 있을 때 너무 헬이다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;g6D49bXarz5B&quot;&gt;
&lt;div data-block-content=&quot;g6D49bXarz5B&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;draRAetYje5S&quot;&gt;&lt;span data-offset-key=&quot;draRAetYje5S:0&quot;&gt;이 얘기가 테스트 코드가 생산성을 증가 시킨다는 의미인가?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;Qb4bkaTpCSyH&quot;&gt;
&lt;div data-block-content=&quot;Qb4bkaTpCSyH&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;w2LB7U4ZY2IU&quot;&gt;&lt;span data-offset-key=&quot;w2LB7U4ZY2IU:0&quot;&gt;그냥 미래 (추후 변경사항) 를 생각해서 현재 노력하는 느낌이다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-slate-fragment=&quot;JTdCJTIyb2JqZWN0JTIyJTNBJTIyZG9jdW1lbnQlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJoZWFkaW5nLTIlMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQSVCNyVCOCVFQiU4MyVBNSUyMCVFQyVBMyVCQyVFQyVBMCU4MCVFQiVBNiVBQyUyMCVFQyVBMyVCQyVFQyVBMCU4MCVFQiVBNiVBQyUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyb1pQUjd2bHBMdDFJJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyY25KRm9kUmhPNUsxJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUQlODElQjQlRUIlQTYlQjAlMjAlRUMlOTUlODQlRUQlODIlQTQlRUQlODUlOEQlRUMlQjIlOTglRUIlQTUlQkMlMjAlRUMlODIlQUMlRUMlOUElQTklRUQlOTUlQjQlRUMlOTUlQkMlRUIlQTclOEMlMjAlRUQlOTklOTUlRUMlOUUlQTUlRUMlOUQlQjQlMjAlRUElQjAlODAlRUIlOEElQTUlRUQlOTUlOTglRUIlQTklQjAlMjAlRUQlODUlOEMlRUMlOEElQTQlRUQlOEElQjglRUElQjAlODAlMjAlRUElQjAlODAlRUIlOEElQTUlRUQlOTUlOUMlMjAlRUElQjIlODMlRUMlOUQlQjQlMjAlRUMlOTUlODQlRUIlOEIlODglRUIlOEIlQTQuJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJueU5ubFlIN0NUS3MlMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjIyMExYcVkxdmxtaEIlMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQyU5RCU5OCVFQyVBMSVCNCVFQyU4NCVCMSUyMCVFQyVBMyVCQyVFQyU5RSU4NSVFQyU5RCU4NCUyMCVFQyU5RSU5OCVFRCU5NSU5OCVFQSVCMyVBMCUyQyUyMCVFRCU5NSU4NCVFQyU5QSU5NCVFQyU5NyU5MCUyMCVFQiU5NCVCMCVFQiU5RCVCQyUyMEhlbHBlciUyMCVFQSVCMCU5RCVFQyVCMiVCNCVFQiVBNSVCQyUyMCVFQyVBMyVCQyVFQyU5RSU4NSVFRCU5NSVCNCVFQyVBMyVCQyVFQiVBOSVCNCUyMCVFQyU5RSU5OCUyMCVFQiVCNiU4NCVFQiVBNiVBQyVFQiU5MCU5OCVFQyVBNyU4MCUyMCVFQyU5NSU4QSVFQyU5RCU4NCVFQSVCOSU4QyUzRiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIySHozZ2IzbDFYbGxuJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIydnFlSjZoVm0zUzBjJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMnFYaUdDeEMwSVNlNSUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMlRWRGE4SWpnZmROSSUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJUVBJUI3JUJDJUVCJTlFJTk4JUVDJTk3JTkwJTIwJUVDJTlFJTkwJUVBJUJFJUI4JTIwJUVEJTgxJUI0JUVCJUE2JUIwJTIwJUVDJTk1JTg0JUVEJTgyJUE0JUVEJTg1JThEJUVDJUIyJTk4JUVCJUE1JUJDJTIwJUVDJThCJUEwJUVCJUI0JTg5JUVEJTk1JTk4JUVCJThBJTk0JTIwJUVDJTgyJUFDJUVCJTlFJThDJUVDJTlEJUI0JTIwJUVCJUE3JThFJUVDJTk1JTg0JUVDJUEwJUI4JUVDJTg0JTlDJTIwJUVCJUIwJTk4JUVCJUIwJTlDJTIwJUVDJThCJUFDJUVCJUE2JUFDJUVBJUIwJTgwJTIwJUVCJThGJTg0JUVDJUE3JTg0JUVCJThCJUE0LiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyU2VpTEFUajg5M2IyJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIydXNNQ085dERyMW9nJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUElQjclQjglRUIlOUYlQUMlRUIlODIlOTglMjAlRUElQjIlQjAlRUElQjUlQUQlMjAlRUQlOUElOEMlRUMlODIlQUMlRUMlOTclOTAlRUMlODQlOUMlRUIlOEElOTQlMjAlRUQlODElQjQlRUIlQTYlQjAlMjAlRUMlOTUlODQlRUQlODIlQTQlRUQlODUlOEQlRUMlQjIlOTglRUIlQTElOUMlMjAlRUMlODQlQTQlRUElQjMlODQlRUQlOTUlOTglRUElQjMlQTAlMjAlRUMlOUUlODglRUIlOEElOTQlMjAlRUIlODIlQjQlMjAlRUIlQUElQTglRUMlOEElQjUlMjAlRjAlOUYlQTUlQjIlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMk85UnF6NHVoa1RleiUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMlExVFh0cnJOaHpzcSUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJXQWRHeTVLalZRZHUlMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJLWExOTFp5U2xCQlklMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQSVCMCU5QyVFQyU5RCVCOCVFQyVBMCU4MSVFQyU5QyVCQyVFQiVBMSU5QyUyMCVFQyU5NSVCMSVFQyU5NyU5MCUyMCVFQyU5RSU4OCVFQiU4QSU5NCUyMCVFQSVCOCVCMCVFQiU4QSVBNSVFQyU5RCVCNCUyMCVFQSVCRCVBNCUyMCVFQyU5OCVBNCVFQiU5RSU5OCUyMCVFQyU4MiVCNCVFQyU5NSU4NCVFQyU4NCU5QyUyMCVFQyU4MyU4OCVFQiVBMSU5QyVFQyU5QSVCNCUyMCVFQSVCOCVCMCVFQiU4QSVBNSVFQyU5RCVCNCUyMCVFQiU4RCU5NSVFQyVBNyU4MCVFQiU4RCU5NSVFQyVBNyU4MCUyMCVFQiVCNiU5OSVFQyU5RCU4NCUyMCVFQSVCMCU4MCVFQiU4QSVBNSVFQyU4NCVCMSVFQyU5RCVCNCUyMCVFQyU5RSU4OCVFQyU5QyVCQyVFQiVBOSVCNCUyMCVFRCU4MSVCNCVFQiVBNiVCMCUyMCVFQyU5NSU4NCVFRCU4MiVBNCVFRCU4NSU4RCVFQyVCMiU5OCUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyMEFMVFMza29UMUZ3JTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyUlk3eGt3d3VQWUhIJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUMlQTclODQlRUMlQTclOUMlMjAlRUIlODQlODglRUIlQUMlQjQlMjAlRUIlQTYlQjAlRUQlOTUlQjQlRUMlODQlOUMlMjAlRUElQjglQjAlRUIlOEElQTUlRUMlOUQlODQlMjAlRUMlOTclODUlRUIlOEQlQjAlRUMlOUQlQjQlRUQlOEElQjglRUQlOTUlOTglRUElQjglQjAlMjAlRUIlQjMlQjQlRUIlOEIlQTQlMjAlRUMlODMlODglRUIlQTElOUMlMjAlRUIlQTclOEMlRUIlOTMlQTAlRUIlOEIlQTQlRUIlQTklQjQlMjAlRUElQjclQjglRUIlODMlQTUlMjAlRUQlODUlOEMlRUMlOEElQTQlRUQlOEElQjglRUIlODIlOTglMjAlRUQlOTklOTUlRUMlOUUlQTUlMjAlRUElQjAlODAlRUIlOEElQTUlRUMlODQlQjElMjAlRUIlQjIlODQlRUIlQTYlQUMlRUElQjMlQTAlMjAlRUIlQjklQTglRUIlQTYlQUMlMjAlRUIlQTclOEMlRUIlOTMlOUMlRUIlOEElOTQlMjAlRUElQjIlODMlRUIlOEYlODQlMjAlRUQlOTUlOTglRUIlODIlOTglRUMlOUQlOTglMjAlRUIlQjAlQTklRUIlQjIlOTUlMjAlRUElQjAlOTklRUIlOEIlQTQuJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJuWTY3bWp4UkFlU1ElMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJLbEU3Z2NKMzI5MHUlMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyTXR0TWFlc0FYaHVwJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIycUdEMVlLclE2Q0E1JTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUElQjclQjglRUIlOUYlQkMlMjAlRUIlOEIlQTQlRUIlOTMlQTQlMjAlRUMlOUQlQjQlRUIlQTAlODclRUElQjIlOEMlMjAlRUIlQTclOTAlRUQlOTUlOTglRUIlOEElOTQlMjAlRUMlODIlQUMlRUIlOUUlOEMlRUIlOEYlODQlMjAlRUMlOUUlODglRUElQjIlQTAlRUMlQTclODAlM0YlMjAnJUVEJTg1JThDJUVDJThBJUE0JUVEJThBJUI4JTIwJUVDJUJEJTk0JUVCJTkzJTlDJUVCJUE1JUJDJTIwJUVDJTlFJTkxJUVDJTg0JUIxJUVEJTk1JUI0JUVDJTk1JUJDJTIwJUVDJTk4JUE0JUVEJTlFJTg4JUVCJUEwJUE0JTIwJUVBJUIwJTlDJUVCJUIwJTlDJUVDJTlEJUI0JTIwJUVCJThEJTk0JTIwJUVCJUI5JUEwJUVCJUE1JUI0JUVCJThCJUE0JyUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyU2JPMWtmM0pHbnp2JTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyeWxjSmc4a0dRdEJlJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUMlOTYlQjQlRUIlOEElOTAlRUMlQTAlOTUlRUIlOEYlODQlMjAlRUIlOEYlOTklRUMlOUQlOTglRUIlOEElOTQlMjAlRUQlOTUlOTglRUIlOEElOTQlRUIlOEQlQjAlMjAlRUMlQTAlODQlRUMlQTAlOUMlRUMlQTElQjAlRUElQjElQjQlRUMlOUQlQjQlMjAlRUQlOTUlODQlRUMlOUElOTQlRUQlOTUlOTglRUIlOEIlQTQuJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJsUFYwd1J1QUhyMnMlMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJUbkxyTXJGcW9JaEwlMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQyU5RCVCQyVFQiU4QiVBOCUyMCVFQyU4MiVBQyVFQyU5QSVBOSVFQyU5RSU5MCVFQSVCMCU4MCUyMCVFQiVBNyU4RSVFQyU5NSU4NCVFQyU5NSVCQyUyMCVFQiU5MCU5QyVFQiU4QiVBNC4lMjAoJUVCJUIzJUI0JUVEJTg2JUI1JTIwUUElMjAlRUQlOEMlODAlRUMlOUQlQjQlMjAlRUIlOEIlQTQlMjAlRUElQjElQjglRUIlOUYlQUMlRUMlQTMlQkMlRUIlOEQlOTQlRUIlOUQlQkMlMjAlRjAlOUYlOTElOEQpJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJPS1M4cW1jTWZjZEQlMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJTMzN1TlVpOHNKOFMlMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQiU5OCU5MCVFRCU5NSU5QyUyMCVFQSVCOCVCMCVFQiU4QSVBNSVFQyU5RCU4NCUyMCVFQSVCOCU4OCVFQiVCMCVBOSUyMCVFQiVCMiU4NCVFQiVBNiVBQyVFQiU4QSU5NCVFQiU4RCVCMCUyMCVFRCU4NSU4QyVFQyU4QSVBNCVFRCU4QSVCOCUyMCVFQyVCRCU5NCVFQiU5MyU5QyVFQiVBNSVCQyUyMCVFQiVCOSVBMSVFQyU4NCVCOCVFQSVCMiU4QyUyMCVFQyVBNyU5QyVFQiVBOSVCNCUyMCVFQSVCNyVCOCVFQiU4MyVBNSUyMCVFRCU4NSU4QyVFQyU4QSVBNCVFRCU4QSVCOCUyMCVFQyVCRCU5NCVFQiU5MyU5QyVFQiVBNSVCQyUyMCVFQyVBNyVBMCUyMCVFQyU4QiU5QyVFQSVCMCU4NCVFQyU5RCU4NCUyMCVFQiVCMiU4NCVFQiVBNiVBQyVFQiU4QSU5NCUyMCVFQiU4QSU5MCVFQiU4MiU4QyVFQyU5RCVCNCUyMCVFQiU5MyVBMCVFQiU4QiVBNC4lMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMnVtQ3ZRSkFkOU5KbyUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMlZ3TGl6WW9Belg0MiUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJUVBJUI4JUIwJUVCJThBJUE1JUVDJTlEJUI0JTIwJUVCJUIzJTgwJUVBJUIyJUJEJUVDJTlEJUI0JTIwJUVCJTkwJTlDJUVCJThCJUE0JUVCJUE5JUI0JTJDJTIwJUVEJTg1JThDJUVDJThBJUE0JUVEJThBJUI4JTIwJUVDJUJEJTk0JUVCJTkzJTlDJUVCJThGJTg0JTIwJUVCJUIwJTk0JUVBJUJGJTk0JUVDJUE0JTk4JUVDJTk1JUJDJTIwJUVEJTk1JTlDJUVCJThCJUE0LiUyMFRDJUVBJUIwJTgwJTIwJUVCJUE3JThFJUVCJThCJUE0JUVCJUE5JUI0JTNGJTIwJUVBJUI3JUI4JUVCJTgzJUE1JTIwJUVBJUIwJTgwJUVCJTgxJTk0JTIwJUVEJTk4JTg0JUVEJTgzJTgwJUVDJTk4JUE4JUVCJThCJUE0LiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyZ2ZqM0tjcDA0TlA5JTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyNWJablBLNkpmNEhzJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUMlQkQlOTQlRUIlOTMlOUMlRUMlOTclOTAlMjAlRUMlOTUlQTAlRUMlQTAlOTUlRUMlOUQlODQlMjAlRUMlQTMlQkMlRUMlQTclODAlMjAlRUIlQTclOTAlRUIlOUQlQkMlRUIlOEElOTQlMjAlRUMlOTYlOTglRUElQjglQjAlRUElQjAlODAlMjAlRUMlOUUlODglRUIlOEElOTQlRUIlOEQlQjAlMjAlRUIlODIlOTglRUIlOEElOTQlMjAlRUMlODIlQUMlRUIlOUUlOTElRUMlOUYlODElRUMlOUQlQjQlRUMlOUQlQjglRUElQjAlODAlRUIlQjMlQjQlRUIlOEIlQTQuJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJXQ3pwa3FOaFZ4bFYlMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJ0MWZYMm5YdkNiN3klMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyRFc2OUEyOTRFQWlnJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyZkpEMUxNNFlGMlNTJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUElQjclQjglRUIlOUUlOTglRUIlOEYlODQlMjAlRUQlODUlOEMlRUMlOEElQTQlRUQlOEElQjglMjAlRUMlQkQlOTQlRUIlOTMlOUMlRUIlOEElOTQlMjAlRUMlOUUlOTElRUMlODQlQjElRUQlOTUlOUMlRUIlOEIlQTQuJTIwJUVDJTk1JTg4JUVBJUI3JUI4JUVCJTlGJUFDJUVCJUE5JUI0JTIwJUVCJTgyJTk4JUVDJUE0JTkxJUVDJTk3JTkwJTIwJUVCJUIzJTgwJUVBJUIyJUJEJUVDJTgyJUFDJUVEJTk1JUFEJUVDJTlEJUI0JTIwJUVDJTlFJTg4JUVDJTlEJTg0JTIwJUVCJTk1JThDJTIwJUVCJTg0JTg4JUVCJUFDJUI0JTIwJUVEJTk3JUFDJUVDJTlEJUI0JUVCJThCJUE0LiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyY0JxU2hndkxoZ2NmJTIyJTdEJTVEJTJDJTIya2V5JTIyJTNBJTIyMEZYQ25zcEJnVVVIJTIyJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRUMlOUQlQjQlMjAlRUMlOTYlOTglRUElQjglQjAlRUElQjAlODAlMjAlRUQlODUlOEMlRUMlOEElQTQlRUQlOEElQjglMjAlRUMlQkQlOTQlRUIlOTMlOUMlRUElQjAlODAlMjAlRUMlODMlOUQlRUMlODIlQjAlRUMlODQlQjElRUMlOUQlODQlMjAlRUMlQTYlOUQlRUElQjAlODAlMjAlRUMlOEIlOUMlRUQlODIlQTglRUIlOEIlQTQlRUIlOEElOTQlMjAlRUMlOUQlOTglRUIlQUYlQjglRUMlOUQlQjglRUElQjAlODAlM0YlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMmRyYVJBZXRZamU1UyUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMmc2RDQ5Ylhhcno1QiUyMiU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmJsb2NrJTIyJTJDJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmlzVm9pZCUyMiUzQWZhbHNlJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJUVBJUI3JUI4JUVCJTgzJUE1JTIwJUVCJUFGJUI4JUVCJTlFJTk4JTIwKCVFQyVCNiU5NCVFRCU5QiU4NCUyMCVFQiVCMyU4MCVFQSVCMiVCRCVFQyU4MiVBQyVFRCU5NSVBRCklMjAlRUIlQTUlQkMlMjAlRUMlODMlOUQlRUElQjAlODElRUQlOTUlQjQlRUMlODQlOUMlMjAlRUQlOTglODQlRUMlOUUlQUMlMjAlRUIlODUlQjglRUIlQTAlQTUlRUQlOTUlOTglRUIlOEElOTQlMjAlRUIlOEElOTAlRUIlODIlOEMlRUMlOUQlQjQlRUIlOEIlQTQuJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJ3MkxCN1U0WlkySVUlMjIlN0QlNUQlMkMlMjJrZXklMjIlM0ElMjJRYjRia2FUcENTeUglMjIlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFQyU4OSVCRCVFQSVCMiU4QyUyMCVFQiVBNyU5MCVFRCU5NSU5OCVFQiVBOSVCNCUyMCVFQiVCMyVCNCVFRCU5NyU5OCVFQiVBMyU4QyVFQiVBNSVCQyUyMCVFQiU4MiVCNCVFQiU4QSU5NCUyMCVFQSVCMiU4MyVFQyU5RCVCNCVFQiU4QiVBNC4lMjAlRUIlODIlOTglRUMlQTQlOTElRUMlOTclOTAlMjAlRUMlOTUlODQlRUQlOTQlODQlRUElQjMlQTAlMjAlRUIlODIlOTglRUIlQTklQjQlMjAlRUIlOEYlODglRUMlOUQlQjQlMjAlRUIlQTclOEUlRUMlOUQlQjQlMjAlRUIlOTMlOUMlRUIlOEIlODglRUElQjklOEMlMjAlRUMlQTclODAlRUElQjglODglMjAlRUMlOTUlQkMlRUElQjglODglRUMlOTUlQkMlRUElQjglODglMjAlRUIlODIlQjQlRUIlOEElOTQlMjAlRUIlOEElOTAlRUIlODIlOEMlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMlB2bDhZUHJQZjV5NyUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMjJWYlpVM0RPbHg2cyUyMiU3RCU1RCUyQyUyMmtleSUyMiUzQSUyMmZ1MG9mTWU0eFNuSSUyMiU3RA==&quot; data-virtualparent=&quot;true&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-key=&quot;2VbZU3DOlx6s&quot;&gt;
&lt;div data-block-content=&quot;2VbZU3DOlx6s&quot;&gt;&lt;span&gt;&lt;span data-key=&quot;Pvl8YPrPf5y7&quot;&gt;&lt;span data-offset-key=&quot;Pvl8YPrPf5y7:0&quot;&gt;쉽게 말하면 보험료를 내는 것이다. 나중에 아프고 나면 돈이 많이 드니까 지금 야금야금 내는 느낌&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>잡담</category>
      <category>Clean Architecture</category>
      <category>IOS</category>
      <category>오블완</category>
      <category>클린 아키텍처</category>
      <category>클린 아키텍쳐</category>
      <category>티스토리챌린지</category>
      <author>호구마츄</author>
      <guid isPermaLink="true">https://hogumachu.tistory.com/43</guid>
      <comments>https://hogumachu.tistory.com/43#entry43comment</comments>
      <pubDate>Mon, 18 Nov 2024 09:46:29 +0900</pubDate>
    </item>
    <item>
      <title>미라클 모닝 후기</title>
      <link>https://hogumachu.tistory.com/42</link>
      <description>&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;최근 미라클 모닝을 실천하고 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아래 게시글에서 매우 일찍 출근하기를 언급한 적이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hogumachu.tistory.com/41&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2024.05.12 - [잡담] - 탑다운 회사에서 개발자로 잘 자라기&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1717303255650&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;개요시드 단계(+ 시리즈 A)의 스타트업에서 재직을 했을 때는 정말 빠르게 움직였습니다.소수의 인원으로 행동하다보니 많은 역할을 담당하였습니다.이때 배운 것은 매우 소중했습니다.&amp;nbsp;그러나&quot; data-og-host=&quot;hogumachu.tistory.com&quot; data-og-source-url=&quot;https://hogumachu.tistory.com/41&quot; data-og-url=&quot;https://hogumachu.tistory.com/41&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/boWGoW/hyWdenNEmM/842cIk6sKHgDplkXE8Wh90/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bPLiQs/hyWg7UQ0sg/2px5zUDjU7PjVyEkkyR7j0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://hogumachu.tistory.com/41&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hogumachu.tistory.com/41&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/boWGoW/hyWdenNEmM/842cIk6sKHgDplkXE8Wh90/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bPLiQs/hyWg7UQ0sg/2px5zUDjU7PjVyEkkyR7j0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&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;개요시드 단계(+ 시리즈 A)의 스타트업에서 재직을 했을 때는 정말 빠르게 움직였습니다.소수의 인원으로 행동하다보니 많은 역할을 담당하였습니다.이때 배운 것은 매우 소중했습니다.&amp;nbsp;그러나&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hogumachu.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미라클 모닝에 대한 저의 생각은 다음과 같습니다.&lt;/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;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;이동 시간이 줄어든다&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지하철만 이용한다면 관계는 없겠지만 버스를 이용하는 입장에서 확실히 차가 막히지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 새벽에 버스를 타면 1시간 20분 정도 걸립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적인 출근을 하게 되면 최소 2시간이 걸립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실상 40분 이상을 세이브 하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;업무 집중력이 올라간다&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출근하자마자 바로 컴퓨터에서 앉아서 일하는 것은 쉽지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와서 커피도 내리고 더우면 에어컨, 선풍기를 통해 조금 식혀줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일찍 출근하게 되면 위의 일은 이미 다 진행한 상황이며 이미 개인 공부를 하고 있었기 때문에 업무 시간에 더 높은 집중력을 발휘할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;퇴근 후에 놀아도 된다&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저 같은 경우에는 퇴근 후에는 보통 방전이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일찍 출근하나 늦게 출근하나 방전되는 것이 똑같아서 퇴근 후에 공부하는 것을 출근 전으로 당겨서 썼습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 퇴근해서 띵가띵가 놀아도 마음이 편하더라고요&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;단점&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;야근하면 큰일&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;야근하면 진짜 치명적입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 보통 11시~12시쯤 취침하는데 이 시간을 넘어가면 다음날 영향이 너무 크게 옵니다&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;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 퇴근하고 자기 계발에 열심히 한다면 똑같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 퇴근 시간의 지옥철을 경험하면 쉽지 않더라고요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-06-02 오후 1.38.46.png&quot; data-origin-width=&quot;1760&quot; data-origin-height=&quot;1384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kR7iU/btsHMAYsjAB/xAUk2e5TvRtbIT8LUCg9X1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kR7iU/btsHMAYsjAB/xAUk2e5TvRtbIT8LUCg9X1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kR7iU/btsHMAYsjAB/xAUk2e5TvRtbIT8LUCg9X1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkR7iU%2FbtsHMAYsjAB%2FxAUk2e5TvRtbIT8LUCg9X1%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;1760&quot; height=&quot;1384&quot; data-filename=&quot;스크린샷 2024-06-02 오후 1.38.46.png&quot; data-origin-width=&quot;1760&quot; data-origin-height=&quot;1384&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;5월 동안은 출근해서 책을 읽었는데 대략 2권 정도 읽을 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조용하다 보니 책을 읽을 때 집중도가 확실히 올라가더라고요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;집이 멀거나, 퇴근 후에 자기 계발이 어렵거나 하시면 미라클 모닝 추천드립니다!&lt;/p&gt;</description>
      <category>잡담</category>
      <category>IOS</category>
      <category>미라클 모닝</category>
      <category>자기계발</category>
      <author>호구마츄</author>
      <guid isPermaLink="true">https://hogumachu.tistory.com/42</guid>
      <comments>https://hogumachu.tistory.com/42#entry42comment</comments>
      <pubDate>Sun, 2 Jun 2024 14:00:19 +0900</pubDate>
    </item>
    <item>
      <title>탑다운 회사에서 개발자로 잘 자라기</title>
      <link>https://hogumachu.tistory.com/41</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;개요&lt;/b&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;시드 단계(+ 시리즈 A)의 스타트업에서 재직을 했을 때는 정말 빠르게 움직였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소수의 인원으로 행동하다보니 많은 역할을 담당하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 배운 것은 매우 소중했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 최근 이에 비해 많이 경직된(부정적인 것이 아닌, 탑다운 의사결정) 회사에 입사하게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 잘 성장할 지에 대한 생각을 나열한 글입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Case 1. 회사의 업무는 경직되지 않았을 때&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제 생각에 &lt;b&gt;가장 최고의 케이스&lt;/b&gt;라고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신이 하고 싶은 일, 추가하고 싶은 기능 등 여러 요소를 비교적 편안하게 선택할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 프로젝트를 처음 시작할 때 React, Vue 등 어떤 것을 사용할지 선택하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 선택을 하기 전에 각 &lt;b&gt;선택지에 따른 장단점과 선택하며 얻는 것을 작성&lt;/b&gt;하기를 바랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;ADR(Architectural Decision Records) 방식으로 문서화하는 것을 추천&lt;/b&gt;&lt;/u&gt;드립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://swalloow.github.io/feat-adr/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://swalloow.github.io/feat-adr/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1715475018369&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;개발자가 의사결정을 기록하는 방법 (feat. ADR)&quot; data-og-description=&quot;개발자들에게는 항상 다양한 선택지 중에 하나를 골라야 하는 상황이 주어집니다. 가장 간단한 예시로는 어떤 언어/프레임워크를 사용할지, 어느 버전을 사용할지에 대한 결정입니다. 오늘은 &quot; data-og-host=&quot;swalloow.github.io&quot; data-og-source-url=&quot;https://swalloow.github.io/feat-adr/&quot; data-og-url=&quot;https://swalloow.github.io/feat-adr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/psPv4/hyV2x1SK7u/YnTuXHHv0kJSElN68EVl6k/img.jpg?width=1800&amp;amp;height=1200&amp;amp;face=0_0_1800_1200,https://scrap.kakaocdn.net/dn/dCd3og/hyV2s7krF8/9KTSLOdfKJPithjhexgyV1/img.jpg?width=1800&amp;amp;height=1200&amp;amp;face=0_0_1800_1200&quot;&gt;&lt;a href=&quot;https://swalloow.github.io/feat-adr/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://swalloow.github.io/feat-adr/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/psPv4/hyV2x1SK7u/YnTuXHHv0kJSElN68EVl6k/img.jpg?width=1800&amp;amp;height=1200&amp;amp;face=0_0_1800_1200,https://scrap.kakaocdn.net/dn/dCd3og/hyV2s7krF8/9KTSLOdfKJPithjhexgyV1/img.jpg?width=1800&amp;amp;height=1200&amp;amp;face=0_0_1800_1200');&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;개발자가 의사결정을 기록하는 방법 (feat. ADR)&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;swalloow.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Case 2. 회사의 업무가 경직되었을 때&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 작업이 주어지고 이를 그냥 해결하면 되는 상황입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서 &quot;React 말고 Vue 사용하고 결제는 Toss SDK 써&quot; 라고 말합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(만약 내가 ADR을 잘 작성해서 보고하여 바뀐다면 Case 1에 해당합니다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴 때는 &lt;b&gt;회사에서 선택한 기술에 대한 ADR을 작성&lt;/b&gt;합니다. 마치 내가 의사결정을 내린 것처럼 말이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 좋은 부분이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 스스로 세뇌를 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React가 Vue 보다 좋은데, Kotlin이 Java보다 좋은데, SwiftUI가 UIKit보다 좋은데...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 생각을 가지고 있어도 각자의 좋은 부분을 찾게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 역효과가 발생할 가능성도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 ADR을 작성하는데 도저히 장점을 못 찾을 때입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Case 3. 회사가 진짜 별로인 선택을 할 때&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(당연히 설득을 해봤지만 통하지 않을 때라고 가정합니다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 쉬운 방법은 런(이직)입니다 ( )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 &lt;b&gt;힘 빼기&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아, 회사에서 내가 일을 하며 발전하는 것은 어렵겠구나라고 생각해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴 때는 정말 회사에서 원하는 업무의 양과 힘을 주어 &lt;b&gt;퇴근 후에 스스로 성장하기 위한 노력&lt;/b&gt;을 더욱 해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기본적인 것들&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 문서화하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신입 이후에 이직을 하며 느낀 것이 바로 일하면서 문서화를 바로바로하자입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 어떤 업무를 하였고 그 업무로 인해서 어떠한 결과가 있었는 지를 반드시 작성해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나중에 이력서 쓸 때 있고 없고 차이가 너무 컸습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 매우 일찍 출근하기 (선택)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매우 일찍 출근하여 일찍 퇴근이 가능하면 빠르게 하는 것도 좋습니다 (빨리 퇴근하고 집에서 자기 계발)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 일찍 퇴근이 불가능하다면 출근 시간 이전에 개인 공부를 하고 출근 시간부터 업무를 시작합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 되면 업무 집중도 또한 늘어서 예상보다 빠르게 회사 업무를 마무리할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저도 7시 이전에 출근하여 개인 프로젝트나 책을 읽고 있는데 꽤 만족스럽습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 블로그 (또는 아카이빙)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서화와 비슷합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 생각이나 경험을 사내의 규정에 어긋나지 않은 선에서 게시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글을 쓰면 장점이 어쩌고저쩌고... 가 있지만 일단 뭔가 한 것 같습니다 (성취감)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 어떤 사람인지 표현하기 쉽습니다 (자기 PR 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 &lt;b&gt;&lt;u&gt;이력서에 활용하기 좋습&lt;/u&gt;&lt;/b&gt;니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 저는 개발을 사랑하며... 이렇게 얘기하면 설득력이 적습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;저는 SOLID 원칙의 장단점을 파악하여 프로젝트를  설계하였습니다. (&lt;a href=&quot;https://hogumachu.tistory.com/38&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://hogumachu.tistory.com/38&lt;/a&gt;)&amp;nbsp;&lt;/li&gt;
&lt;li&gt;또한 최근에는 테스트 코드의 중요성을 뼈저리게 느껴 테스트 작성을 열심히 하고 있습니다. (&lt;a href=&quot;https://hogumachu.tistory.com/36&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://hogumachu.tistory.com/36&lt;/a&gt;, &lt;a href=&quot;https://hogumachu.tistory.com/37&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://hogumachu.tistory.com/37&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;개인 프로젝트에서 테스트 자동화 및 커버리지를 80%로 올려 기능 추가 및 변경에 안정성을 부여하도록 노력하고 있습니다 (&lt;a href=&quot;https://github.com/hogumachu/InMyMemory&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/hogumachu/InMyMemory&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 &lt;b&gt;글을 남기지 않는다는 것&lt;/b&gt;은 자신이 한 행동이 &lt;b&gt;팩트인지 아닌지 확인하기 어렵게 만드는 것&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결론&lt;/b&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 내용 정리를 하여 내 머리에 한 번 더 각인시키며 이직 시 어느 정도 설득력을 얻게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다 작성하고 보니 커리어 향상보다는 글 써라 라는 내용이 되었습니다 (ㅋㅋㅋ)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 진짜 중요한 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;귀찮아도 언젠가는 '아 저 때 뭐였더라', '아 그때 뭐 했는데'라는 순간이 찾아옵니다.&lt;/p&gt;</description>
      <category>잡담</category>
      <category>ㅇㅅㅇ</category>
      <category>개발자</category>
      <category>글쓰기</category>
      <category>꼰대</category>
      <category>블로그</category>
      <category>커리어</category>
      <category>회사</category>
      <author>호구마츄</author>
      <guid isPermaLink="true">https://hogumachu.tistory.com/41</guid>
      <comments>https://hogumachu.tistory.com/41#entry41comment</comments>
      <pubDate>Sun, 12 May 2024 10:48:16 +0900</pubDate>
    </item>
    <item>
      <title>[iOS] SwiftUI, TCA 모듈화 그리고 RIBs</title>
      <link>https://hogumachu.tistory.com/40</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;개요&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt; 최근에 SwiftUI와 TCA 조합으로 개인 프로젝트를 진행하고 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사내 새로운 서비스도 TCA를 사용할 것 같은데 아마 설계까지 해야 할 것 같습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그런데 TCA로 제대로된 모듈화가 너무 어렵더라고요..&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이에 대한 트러블 슈팅과 생각 정리를 좀 해봤습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;  TCA에 대해 깊게 알고 작성한 글이 아니므로 잘 걸러서 들어주세요!  &lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다른 좋은 방법이 있다면 말씀해 주시면 조언 부탁드리겠습니다.  &amp;zwj;♂️ &amp;zwj;♂️&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; SwiftUI, 모듈화가 어려운 이유&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SwiftUI의 장점&lt;/b&gt;은 너무 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 &lt;u&gt;선언형&lt;/u&gt;이라 직관적이며 UIKit에 비해 &lt;u&gt;적은 코드로 UI를 그릴 수 있고&lt;/u&gt; 등등... 아주 많습니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러나 제 생각에는 &lt;b&gt;단점도 꽤나 치명적&lt;/b&gt;입니다. 바로 &lt;b&gt;View에서 내비게이션(라우팅)을 관장&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;물론 View를 Builder 패턴으로 주입하는 것도 가능은 하겠으나 결국 Builder가 반환하는 View의 구체 타입을 알아야 합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;왜냐하면 View의 body 내부에는 'any View'가 들어갈 수 없기 때문입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-04 오후 11.56.04.png&quot; data-origin-width=&quot;1756&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/trO8E/btsHdwh04BO/EaqWNFKJZ2dgDCOuGbsmT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/trO8E/btsHdwh04BO/EaqWNFKJZ2dgDCOuGbsmT1/img.png&quot; data-alt=&quot;Body 내부에 구체 타입 주세요&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/trO8E/btsHdwh04BO/EaqWNFKJZ2dgDCOuGbsmT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtrO8E%2FbtsHdwh04BO%2FEaqWNFKJZ2dgDCOuGbsmT1%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;1756&quot; height=&quot;326&quot; data-filename=&quot;스크린샷 2024-05-04 오후 11.56.04.png&quot; data-origin-width=&quot;1756&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Body 내부에 구체 타입 주세요&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/hogumachu/Laboratory/tree/master/Builder%2BSwiftUI&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;샘플 코드&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 되면 결국 View는 다른 모듈의 구체 타입인 View를 알고 있게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 모듈끼리 강한 연결이 된다는 의미입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 결국 반쪽짜리 모듈화가 된다는 의미기도 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;TCA 모듈화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCA도 똑같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Reducer에서 다른 Reducer의 State, Action을 알아야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 연결될 수밖에 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Reducer에서 ifLet, Path 등을 활용하여 다른 Reducer와 연결이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; 해결 방법 (시도만 함)&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/hogumachu/RIBs-TCA&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/hogumachu/RIBs-TCA&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1714835425654&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - hogumachu/RIBs-TCA: Combination of RIBs and TCA.&quot; data-og-description=&quot;Combination of RIBs and TCA. Contribute to hogumachu/RIBs-TCA development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/hogumachu/RIBs-TCA&quot; data-og-url=&quot;https://github.com/hogumachu/RIBs-TCA&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/sR70G/hyVZowWe6Y/mFarPXM5EMPySTZDhDoMzk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/hogumachu/RIBs-TCA&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/hogumachu/RIBs-TCA&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/sR70G/hyVZowWe6Y/mFarPXM5EMPySTZDhDoMzk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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;GitHub - hogumachu/RIBs-TCA: Combination of RIBs and TCA.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Combination of RIBs and TCA. Contribute to hogumachu/RIBs-TCA development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시 익숙한 것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자주 사용했던 RIBs를 통해 시도했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 있던 문제는 사실 &lt;b&gt;UIKit의 계층 구조를 따르면 쉽게 해결&lt;/b&gt;됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(자세한 내용은 해당 링크를 확인해 주세요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SwiftUI의 UI 그리는 방식 사용 가능&lt;/li&gt;
&lt;li&gt;TCA의 좋은 기능 (@Dependency, 단방향 데이터 흐름 기타 등등) 사용 가능&lt;/li&gt;
&lt;li&gt;내비게이션 로직 분리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RIBs에서 &lt;u&gt;View 영역을 SwiftUI로 대체&lt;/u&gt;했으며 &lt;u&gt;Interactor 내부의 동작을 TCA의 Reducer와 합친 것입니다.&lt;/u&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 생각했던 SwiftUI의 장점인 선언형과 빠른 UI 구성을 활용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 단점이라 생각한 View에서의 내비게이션도 제거하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TCA의 좋은 기능을 사용하지 못함 (내비게이션)&lt;/li&gt;
&lt;li&gt;러닝커브 2배 (RIBs, TCA)&lt;/li&gt;
&lt;li&gt;불필요한 RxSwift에 대한 의존성 (RIBs는 RxSwift 의존성이 있음, ModernRIBs를 사용하면 해결되긴 함)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; 결론&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt; &lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다른 좋은 해결 방법이 있을 것 같은데 SwiftUI와 TCA에 대한 이해도가 낮아 다른 방식으로 풀어봤습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기존에 RIBs를 사용했다면 부분적으로 SwiftUI (굳이 TCA가 없어도)를 추가하여 해결해도 좋을 것 같습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 RIBs를 아키텍처로 알고 있었는데 프레임워크라고 하더라고요 ㅋㅋ..&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결국 RIBs로 프레임워크를 구성하고 내부의 아키텍처를 TCA로 하는 거라 어울리는 것 같기도 합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3줄 요약&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;SwiftUI는 View에서 내비게이션 역할을 하기 때문에 인터페이스/구현체 구조의 모듈화가 어렵다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;UIKit의 View 계층 구조를 활용하면 이를 해결할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;RIBs+TCA로 시도해 봤는데 잘 되었다.&lt;/p&gt;</description>
      <category>스위프트</category>
      <category>composablearchitecture</category>
      <category>microfeature</category>
      <category>microfeaturesarchitecture</category>
      <category>Ribs</category>
      <category>SwiftUI</category>
      <category>TCA</category>
      <category>uikit</category>
      <category>모듈화</category>
      <category>아키텍처</category>
      <author>호구마츄</author>
      <guid isPermaLink="true">https://hogumachu.tistory.com/40</guid>
      <comments>https://hogumachu.tistory.com/40#entry40comment</comments>
      <pubDate>Sun, 5 May 2024 00:34:03 +0900</pubDate>
    </item>
    <item>
      <title>[OOP] SOLID 원칙 for iOS</title>
      <link>https://hogumachu.tistory.com/38</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;개요&lt;/b&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;학부 시절에 SOLID 원칙에 대해 열심히 암기했던 기억이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예전에 SOLID 원칙에 대해 잘 지키고 있나요?라는 질문을 받았는데 '네'라는 답을 하기가 꽤 어려웠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iOS 앱을 만들며 느꼈던 SOLID 원칙을 잘 지키고 있는 지 함께 알아봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SOLID 원칙이란?&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;로버트 마틴이 2000년대 초반에 명명한 객체 지향 프로그래밍 및 설계의 다섯 가지 기본 원칙&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;유지 보수와 확장이 쉬운 시스템을 만들고자 할 때 이 원칙들을 함께 적용할 수 있습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;(출처: 위키백과)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 핵심적인 부분은 &lt;u&gt;&lt;b&gt;유지 보수&lt;/b&gt;&lt;/u&gt;와&lt;b&gt;&lt;/b&gt;&lt;u&gt;&lt;b&gt; 확장이 쉬운 시스템&lt;/b&gt;&lt;/u&gt;인 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S: 단일 책임 원칙&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;i&gt;&lt;b&gt;Single Responsibility Principle&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;한 클래스는 하나의 책임만 가져야 한다&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 원칙은 핵심은 &lt;u&gt;&lt;b&gt;복잡성을 줄이는 것&lt;/b&gt;&lt;/u&gt; 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iOS 개발을 하다 보면 MVC, MVVM 등 여러 아키텍처를 접하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(아키텍처에 대한 설명은 따로 하지 않고 진행하겠습니다)&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;MVC&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVC의 ViewController는 정말 많은 역할을 하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자의 이벤트를 받고, 이벤트에 대한 동작을 진행하고, 라우팅도 진행하고...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 일을 하고 있죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 단일 책임 원칙을 위반하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ViewController&lt;/b&gt;는 UI 로직, 비즈니스 로직, 라우팅 로직 등 &lt;b&gt;많은 책임&lt;/b&gt;을 지고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;338&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/853wF/btsFlQdIu6X/cUKPRRuAkyvmPMPxLeY5Y0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/853wF/btsFlQdIu6X/cUKPRRuAkyvmPMPxLeY5Y0/img.png&quot; data-alt=&quot;ViewController의 역할&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/853wF/btsFlQdIu6X/cUKPRRuAkyvmPMPxLeY5Y0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F853wF%2FbtsFlQdIu6X%2FcUKPRRuAkyvmPMPxLeY5Y0%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;338&quot; height=&quot;426&quot; data-origin-width=&quot;338&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ViewController의 역할&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;MVVM&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVVM은 비즈니스 로직을 ViewModel로 이전하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewController는 UI 로직, 라우팅 로직을 책임집니다.&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;이것에 만족하지 않고 MVVM-C라는 Coordinator 패턴이 들어간 아키텍처도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Coordinator가 라우팅 로직을 책임지며 많은 부분이 분리되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;338&quot; data-origin-height=&quot;790&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/betI42/btsFspyvXVY/idfyWeFmgjKItps5SbV8DK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/betI42/btsFspyvXVY/idfyWeFmgjKItps5SbV8DK/img.png&quot; data-alt=&quot;MVVM-C의 역할&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/betI42/btsFspyvXVY/idfyWeFmgjKItps5SbV8DK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbetI42%2FbtsFspyvXVY%2FidfyWeFmgjKItps5SbV8DK%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;338&quot; height=&quot;790&quot; data-origin-width=&quot;338&quot; data-origin-height=&quot;790&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MVVM-C의 역할&lt;/figcaption&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;이처럼 단일 책임 원칙은 아키텍처뿐만 아니라 앱 개발을 하며 Custom View를 만들어 Custom View 끼리 합치는 것 또한 단일 책임 원칙을 지키는 것이라 볼 수 있습니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;O: 개방/폐쇄 원칙&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;i&gt;&lt;b&gt;Open/Closed Principle&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.&lt;/b&gt;&lt;/u&gt;&lt;span style=&quot;background-color: #f8f9fa; color: #202122; text-align: left;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 &lt;u&gt;&lt;b&gt;새로운 기능을 추가할 때 작성된 코드가 깨지지 않아야&lt;/b&gt;&lt;/u&gt; 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱 개발을 하며 개방/폐쇄 원칙을 가장 어겼던 부분이 바로 enum을 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 부분에서만 enum을 사용하면 상관이 없으나 많은 부분에서 enum을 사용하게 되면 케이스가 추가/제거될 때 연관된 코드가 모두 깨지게 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1709364282696&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;enum Fruit {
  case apple
  case banana
}

func calculate(fruit: Fruit) -&amp;gt; Double {
    switch fruit {
    case .apple:
      return 1_000 * 1.1
    case .banana:
      return 2_000 * 1.1
    }
}

func store(fruit: Fruit) {
    switch fruit {
    case .apple:
      storageA.append(fruit)
    case .banana:
      storageB.append(fruit)
    }
}&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;예시 코드처럼 작성되었을 때 만약 Fruit에 새로운 과일이 추가되면 어떻게 될까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 Fruit과 연관된 코드는 모두 깨지게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bi5h6S/btsFnY27nqW/A0zLudfhpdoHM2AvMoZKnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi5h6S/btsFnY27nqW/A0zLudfhpdoHM2AvMoZKnK/img.png&quot; data-alt=&quot;Fruit 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi5h6S/btsFnY27nqW/A0zLudfhpdoHM2AvMoZKnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbi5h6S%2FbtsFnY27nqW%2FA0zLudfhpdoHM2AvMoZKnK%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;886&quot; height=&quot;528&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fruit 예시&lt;/figcaption&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;이러한 경우에는 Protocol을 이용하여 해결할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1709364424892&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;protocol Vegetable {
  var cost: Int { get }
  var storageType: Int { get }
}

func calculate(vegetable: Vegetable) -&amp;gt; Double {
    return Double(vegetable.cost) * 1.2
}

func store(vegetable: Vegetable) {
    if let storage = storages[vegetable.storageType] {
      storages[vegetable.storageType] = storage + [vegetable]
    } else {
      storages[vegetable.storageType] = [vegetable]
    }
}&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;이렇게 해결할 수 있다고 enum 대신 Protocol만을 활용하는 것은 좋지 못한 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;i&gt;현재 상황에서 가장 적절한 것을 사용하는 게 중요&lt;/i&gt;&lt;/b&gt;하다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;L: 리스코프 치환 원칙&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;Liskov Substitution Principle&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 &lt;u&gt;&lt;b&gt;부모 클래스 대신에 자식 클래스를 넣어도 잘 동작&lt;/b&gt;&lt;/u&gt;해야 한다는 의미입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 자식 클래스가 부모의 동작을 깨뜨리면 안 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iOS 개발을 하며 아래와 같은 코드를 많이 보셨을 겁니다.&lt;/p&gt;
&lt;pre id=&quot;code_1709364776720&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;required init?(coder: NSCoder) {
    fatalError(&quot;init(coder:) has not been implemented&quot;)
}&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;NSCoder를 이용한 초기화를 막는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 부모 클래스 동작을 제한하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709364804719&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;required init?(coder: NSCoder) {
    super.init(coder: coder)
}&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709364975765&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;protocol Animal {
  var age: Int { get }
  var isMale: Bool { get }
}

class Hospital {
  func doSomething(animal: Animal) {
    if animal.age &amp;gt; 10 {
      print(&quot;old&quot;)
    } else {
      print(&quot;young&quot;)
    }
  }
}

class MyHospital: Hospital {
  override func doSomething(animal: Animal) {
    // 사전 조건 강화
    if animal.isMale {
      return
    }
    super.doSomething(animal: animal)
  }
}&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Hospital과 다르게 MyHospital은 출력문이 호출되지 않겠죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;I: 인터페이스 분리 원칙&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;i&gt;&lt;b&gt;Interface Segregation Principle&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신이 &lt;u&gt;&lt;b&gt;사용하지 않는 메서드가 있으면 안 됩니다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709365212345&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;protocol HomeUseCase {
  func requestValues() -&amp;gt; [String]
  func addSomething(value: String)
  func removeSomething(value: String)
}

final class HomeDetailViewModel {
  private let useCase: HomeUseCase
  
  init(useCase: HomeUseCase) {
    self.useCase = useCase
  }
  
  // 모두 접근 가능
  func doSomething() {
    useCase.requestValues()
    useCase.addSomething(value: &quot;A&quot;)
    useCase.removeSomething(value: &quot;A&quot;)
  }
}&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;홈 상세 화면에서는 requestValues만 필요한데 위와 같이 UseCase를 사용하면 addSomething, removeSomething과 같이 사용하지 않는 메서드도 사용할 수 있게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 그냥 '사용 안 하면 되지 않나?'라고 생각할 수 있지만 &lt;u&gt;의도와 다르게 다른 개발자가&lt;/u&gt; 홈 상세 화면에서 &lt;u&gt;해당 기능을 사용할 수도 있습니다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;u&gt;&lt;b&gt;의도대로 특정 부분만 열어주어야 합니다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709365363258&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;typealias MyUseCase = MyProfileUseCase &amp;amp; FriendUseCase

protocol MyProfileUseCase {
  func requestName() -&amp;gt; String
  func requestAge() -&amp;gt; Int
}

protocol FriendUseCase {
  func requestFriends() -&amp;gt; [String]
}&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;위와 같은 방식으로 인터페이스를 분리하여 typealias로 선언하는 방식도 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709365414390&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;final class MyUseCaseImp: MyUseCase {
  
  func requestName() -&amp;gt; String {
    return &quot;A&quot;
  }
  
  func requestAge() -&amp;gt; Int {
    return 1
  }
  
  func requestFriends() -&amp;gt; [String] {
    return [&quot;B&quot;, &quot;C&quot;]
  }
  
}

let friendUseCase: FriendUseCase = MyUseCaseImp()
let profileUseCase: MyProfileUseCase = MyUseCaseImp()&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;/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;D: 의존관계 역전 원칙&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;Dependency Inversion Principle&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;프로그래머는 &quot;추상화에 의존해야지, 구체화에 의존하면 안 된다&quot;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709365601843&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;final class Repository {
  func create(value: Int) { /* 생략 */ }
  func read(value: Int) -&amp;gt; Int {  1 }
  func update(value: Int) { /* 생략 */ }
  func delete(value: Int) { /* 생략 */ }
}

final class ViewModel {
  private let repository: Repository
  
  init(repository: Repository) {
    self.repository = repository
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpMUJT/btsFlVTqslE/cj7IDtzxWAUGmPymVQmGC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpMUJT/btsFlVTqslE/cj7IDtzxWAUGmPymVQmGC0/img.png&quot; data-alt=&quot;ViewModel이 Repository 구현체를 의존&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpMUJT/btsFlVTqslE/cj7IDtzxWAUGmPymVQmGC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpMUJT%2FbtsFlVTqslE%2Fcj7IDtzxWAUGmPymVQmGC0%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;870&quot; height=&quot;360&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ViewModel이 Repository 구현체를 의존&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 코드가 있다고 가정할 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 ViewModel에 있는 Repository가 CoreData나 SwiftData 또는 Realm으로 변경된다면 어떻게 해결해야 할까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Repository 자체를 변경한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. ViewModel 전용 새로운 Repository를 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 Repository가 다른 곳에서도 사용될 수 있으므로 1번보다는 2번이 적합해 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 이 방법이 과연 옳은 것일까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 새롭게 변경되는 것은 Repository 부분인데 이로 인해 ViewModel이 깨지는 상황입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 개방/폐쇄 원칙을 위반하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한&amp;nbsp;개발을 할 때 실제 데이터베이스를 사용하기 때문에 옳지 않은 방법입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2만 개 정도의 데이터를 보여주고 싶다면 데이터베이스에 2만 개의 데이터를 하나하나 추가해야 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709365887605&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;protocol MyRepository {
  func create(value: Int)
  func read(value: Int) -&amp;gt; Int
  func update(value: Int)
  func delete(value: Int)
}

final class CoreDataRepository: MyRepository {
  func create(value: Int) { /* 생략 */ }
  func read(value: Int) -&amp;gt; Int {  1 }
  func update(value: Int) { /* 생략 */ }
  func delete(value: Int) { /* 생략 */ }
}

final class MemoryRepository: MyRepository {
  func create(value: Int) { /* 생략 */ }
  func read(value: Int) -&amp;gt; Int {  1 }
  func update(value: Int) { /* 생략 */ }
  func delete(value: Int) { /* 생략 */ }
}

final class MyViewModel {
  private let repository: MyRepository // 인터페이스 의존
  
  init(repository: MyRepository) {
    self.repository = repository
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1294&quot; data-origin-height=&quot;794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I2aDi/btsFqMHF97X/asPgkUk1BhG50M3mLE00x0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I2aDi/btsFqMHF97X/asPgkUk1BhG50M3mLE00x0/img.png&quot; data-alt=&quot;ViewModel이 Repository 인터페이스에 의존&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I2aDi/btsFqMHF97X/asPgkUk1BhG50M3mLE00x0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI2aDi%2FbtsFqMHF97X%2FasPgkUk1BhG50M3mLE00x0%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;1294&quot; height=&quot;794&quot; data-origin-width=&quot;1294&quot; data-origin-height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ViewModel이 Repository 인터페이스에 의존&lt;/figcaption&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;u&gt;&lt;b&gt;인터페이스에 의존&lt;/b&gt;&lt;/u&gt;하게 하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 인터페이스를 생성하여 청사진을 그리고 그것에 대한 구현체를 만들면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 MyViewModel에 상황에 적합한 Repository 구현체를 만들어 주입해 주면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 MyViewModel과 MyRepository의 의존성이 역전이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SOLID 원칙의 목적은 유지 보수와&lt;span&gt;&amp;nbsp;&lt;/span&gt;확장이 쉬운 시스템이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iOS 개발에도 SOLID 원칙을 녹이면 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다고 모든 부분에 강요하는 것은 좋지 못하다. 상황에 따라 잘 사용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 게시글의 전체 소스 코드는 아래 링크에서 보실 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/hogumachu/Laboratory/tree/master/SOLIDSample&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/hogumachu/Laboratory/tree/master/SOLIDSample&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1709367982499&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;SOLID (객체 지향 설계) - 위키백과, 우리 모두의 백과사전&quot; data-og-description=&quot;위키백과, 우리 모두의 백과사전. 컴퓨터 프로그래밍에서 SOLID란 로버트 마틴[1][2]이 2000년대 초반[3]에 명명한 객체 지향 프로그래밍 및 설계의 다섯 가지 기본 원칙을 마이클 페더스가 두문자어&quot; data-og-host=&quot;ko.wikipedia.org&quot; data-og-source-url=&quot;https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)&quot; data-og-url=&quot;https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SOLID (객체 지향 설계) - 위키백과, 우리 모두의 백과사전&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;위키백과, 우리 모두의 백과사전. 컴퓨터 프로그래밍에서 SOLID란 로버트 마틴[1][2]이 2000년대 초반[3]에 명명한 객체 지향 프로그래밍 및 설계의 다섯 가지 기본 원칙을 마이클 페더스가 두문자어&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ko.wikipedia.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>객체지향프로그래밍</category>
      <category>IOS</category>
      <category>Solid</category>
      <category>swift</category>
      <category>객체지향프로그래밍</category>
      <author>호구마츄</author>
      <guid isPermaLink="true">https://hogumachu.tistory.com/38</guid>
      <comments>https://hogumachu.tistory.com/38#entry38comment</comments>
      <pubDate>Sat, 2 Mar 2024 17:34:51 +0900</pubDate>
    </item>
    <item>
      <title>[iOS] ViewController 테스트 작성하기</title>
      <link>https://hogumachu.tistory.com/37</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;1048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnSz9P/btsD09Fs9Oy/gemeRdPDI3yuxBYkuvNsk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnSz9P/btsD09Fs9Oy/gemeRdPDI3yuxBYkuvNsk0/img.png&quot; data-alt=&quot;ViewController-ViewModel-Service&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnSz9P/btsD09Fs9Oy/gemeRdPDI3yuxBYkuvNsk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnSz9P%2FbtsD09Fs9Oy%2FgemeRdPDI3yuxBYkuvNsk0%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;1510&quot; height=&quot;1048&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;1048&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ViewController-ViewModel-Service&lt;/figcaption&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;보통 테스트를 할 때 비즈니스 로직만 테스트를 하고 ViewController(UI)에 대한 테스트 작성은 미흡합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 테스트가 미흡했고 어떻게 테스트를 작성할 수 있는지에 대해 알아봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;테스트하기 어려운 이유 - 객체지향프로그래밍&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전에 객체지향프로그래밍(OOP)에 대해 글을 작성했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hogumachu.tistory.com/32&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2023.08.13 - [객체지향프로그래밍] - [OOP] 객체지향프로그래밍 기초&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1706425538143&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;[OOP] 객체지향프로그래밍 기초&quot; data-og-description=&quot;OOP의 개념 객체지향 프로그래밍 (Object Oriented Programming)은 프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라, 프로그램을 수많은 '객체(object)'라는 기본 단위로 나누고 이들의 상호&quot; data-og-host=&quot;hogumachu.tistory.com&quot; data-og-source-url=&quot;https://hogumachu.tistory.com/32&quot; data-og-url=&quot;https://hogumachu.tistory.com/32&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/i6gHD/hyU8Ymxp8d/F72KtqOwzrtsPjq0d3BfXk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/dXa4t5/hyVb5Ekvi9/iBPx2AAkKeQnmqxiy9Nqqk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bJhAXp/hyU8PQDJTM/hVhFthbN0gGNYMWKjOvN7k/img.png?width=1364&amp;amp;height=956&amp;amp;face=0_0_1364_956&quot;&gt;&lt;a href=&quot;https://hogumachu.tistory.com/32&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hogumachu.tistory.com/32&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/i6gHD/hyU8Ymxp8d/F72KtqOwzrtsPjq0d3BfXk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/dXa4t5/hyVb5Ekvi9/iBPx2AAkKeQnmqxiy9Nqqk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bJhAXp/hyU8PQDJTM/hVhFthbN0gGNYMWKjOvN7k/img.png?width=1364&amp;amp;height=956&amp;amp;face=0_0_1364_956');&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;[OOP] 객체지향프로그래밍 기초&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;OOP의 개념 객체지향 프로그래밍 (Object Oriented Programming)은 프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라, 프로그램을 수많은 '객체(object)'라는 기본 단위로 나누고 이들의 상호&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hogumachu.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewController를 테스트하기 어려운 이유는 바로 &lt;b&gt;캡슐화&lt;/b&gt; 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더하기 버튼을 누르면 값이 증가하고 빼기 버튼을 누르면 값이 감소하는 화면이 있다고 가정하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ca7KuU/btsD3mD5kWQ/XzroOnP6AUM4spU3YsEvr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ca7KuU/btsD3mD5kWQ/XzroOnP6AUM4spU3YsEvr0/img.png&quot; data-alt=&quot;테스트 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ca7KuU/btsD3mD5kWQ/XzroOnP6AUM4spU3YsEvr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fca7KuU%2FbtsD3mD5kWQ%2FXzroOnP6AUM4spU3YsEvr0%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;966&quot; height=&quot;593&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;테스트 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;캡슐화&lt;/b&gt;는 말 그대로 캡슐 안에 &lt;u&gt;내용을 숨기는 것&lt;/u&gt; 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(알약 안에 있는 성분을 하나하나 확인하지 않고 우리는 그냥 알약을 먹습니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 캡슐화를 하지 않았다면 위 예시를 테스트하는 것은 매우 간단합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1706425777409&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 은닉화 하지 않은 ViewController

final class ViewController {
    let scoreLabel = UILabel()
    let plusButton = UIButton()
    let minusButton = UIButton()
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1706425868626&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func test_plus_button을_누르면_score가_1_증가한다() {
    // given
    let sut = ViewController()
    
    // when
    sut.plusButton.sendActions(for: .touchUpInside)
    
    // then
    XCTAssertEqual(sut.scoreLabel.text, &quot;1&quot;)
}&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;캡슐화(은닉화) 하지 않으면 외부에 의해 변경될 수 있으므로 캡슐화를 반드시 해야 합니다.&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AyvzA/btsD2950Nkx/QPavQ2zzK1ylOT8NzVItg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AyvzA/btsD2950Nkx/QPavQ2zzK1ylOT8NzVItg1/img.png&quot; data-alt=&quot;은닉화&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AyvzA/btsD2950Nkx/QPavQ2zzK1ylOT8NzVItg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAyvzA%2FbtsD2950Nkx%2FQPavQ2zzK1ylOT8NzVItg1%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;1056&quot; height=&quot;688&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;은닉화&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;접근성 식별자를 사용하자&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Accessibility identifier를 사용하면 은닉화된 상태에도 UI Test가 가능해집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiaccessibilityidentification/1623132-accessibilityidentifier&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.apple.com/documentation/uikit/uiaccessibilityidentification/1623132-accessibilityidentifier&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1706426509923&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;accessibilityIdentifier | Apple Developer Documentation&quot; data-og-description=&quot;A string that identifies the element.&quot; data-og-host=&quot;developer.apple.com&quot; data-og-source-url=&quot;https://developer.apple.com/documentation/uikit/uiaccessibilityidentification/1623132-accessibilityidentifier&quot; data-og-url=&quot;https://docs.developer.apple.com/documentation/uikit/uiaccessibilityidentification/1623132-accessibilityidentifier&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/NFjD1/hyU81p2iiB/nzoESsTlIt7W7RaQSLPG00/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bq8ATr/hyVcaTaGC3/sIKcyzkBIpSK3YAZK2xSGk/img.jpg?width=1024&amp;amp;height=512&amp;amp;face=0_0_1024_512&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiaccessibilityidentification/1623132-accessibilityidentifier&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.apple.com/documentation/uikit/uiaccessibilityidentification/1623132-accessibilityidentifier&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/NFjD1/hyU81p2iiB/nzoESsTlIt7W7RaQSLPG00/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bq8ATr/hyVcaTaGC3/sIKcyzkBIpSK3YAZK2xSGk/img.jpg?width=1024&amp;amp;height=512&amp;amp;face=0_0_1024_512');&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;accessibilityIdentifier | Apple Developer Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A string that identifies the element.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.apple.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;모든 UI에는 접근성 식별자가 존재하여 이를 통해 은닉화된 값을 가져올 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1706426586822&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;extension UIView {
    
    func search&amp;lt;T: UIView&amp;gt;(type: T.Type, accessibilityIdentifier: String) -&amp;gt; T? {
        for subview in subviews {
            if subview.accessibilityIdentifier == accessibilityIdentifier {
                return subview as? T
            } else {
                if let view = subview.search(type: type, accessibilityIdentifier: accessibilityIdentifier) {
                    return view
                }
            }
        }
        return nil
    }
    
}&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1706426644134&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;enum UITestError: Error {
    case emptyAccessibilityIdentifier
}

extension UIViewController {
    
    func search&amp;lt;T: UIView&amp;gt;(type: T.Type, accessibilityIdentifier: String) throws -&amp;gt; T {
        if let result = view.search(type: type, accessibilityIdentifier: accessibilityIdentifier) {
            return result
        } else {
            throw UITestError.emptyAccessibilityIdentifier
        }
    }
    
}&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;이런 식으로 UIViewController에도 메서드를 추가해 주면 사용하기 편리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ViewController 테스트 작성하기&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1706426781523&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;final class ViewController {
    private let scoreLabel = UILabel()
    private let plusButton = UIButton()
    private let minusButton = UIButton()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        scoreLabel.accessibilityIdentifier = &quot;score_label&quot;
        plusButton.accessibilityIdentifier = &quot;plus_button&quot;
        minusButton.accessibilityIdentifier = &quot;minus_button&quot;
    }
}&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1706426875324&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func test_plus_button을_누르면_값이_1_증가한다() throws {
    // given
    let sut = ViewController()
    let button = try sut.search(type: UIButton.self, accessibilityIdentifier: &quot;plus_button&quot;)
    let label = try sut.search(type: UILabel.self, accessibilityIdentifier: &quot;score_label&quot;)

    // when
    button.sendActions(for: .touchUpInside)

    // then
    XCTAssertEqual(label.text, &quot;1&quot;)
}&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;끝&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 캡슐화(은닉화)로 인해 ViewController 테스트하기 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. AccessibilityIdentifier를 활용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;a title=&quot;좋은 라이브러리&quot; href=&quot;https://github.com/lyft/Hammer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;좋은 라이브러리&lt;/a&gt;가 많으니 골라서 사용하면 더욱 쉽게 테스트할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 게시글의 소스 코드는 아래 링크에서 보실 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/hogumachu/Laboratory/tree/master/UITestSampleApp&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/hogumachu/Laboratory/tree/master/UITestSampleApp&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>스위프트</category>
      <category>Accessibility Identifier</category>
      <category>AccessibilityIdentifier</category>
      <category>IOS</category>
      <category>swift</category>
      <category>UI test</category>
      <category>UITest</category>
      <category>ViewController Test</category>
      <category>ViewController 테스트</category>
      <category>접근성 식별자</category>
      <category>캡슐화</category>
      <author>호구마츄</author>
      <guid isPermaLink="true">https://hogumachu.tistory.com/37</guid>
      <comments>https://hogumachu.tistory.com/37#entry37comment</comments>
      <pubDate>Sun, 28 Jan 2024 16:40:16 +0900</pubDate>
    </item>
    <item>
      <title>[iOS] 테스트를 작성해야 하는 이유</title>
      <link>https://hogumachu.tistory.com/36</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1532&quot; data-origin-height=&quot;684&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqQu6f/btsDNscc2mh/7ajZvCdwByT3LkSC4YQIgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqQu6f/btsDNscc2mh/7ajZvCdwByT3LkSC4YQIgK/img.png&quot; data-alt=&quot;테스트 코드 왜 작성?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqQu6f/btsDNscc2mh/7ajZvCdwByT3LkSC4YQIgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqQu6f%2FbtsDNscc2mh%2F7ajZvCdwByT3LkSC4YQIgK%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;1532&quot; height=&quot;684&quot; data-origin-width=&quot;1532&quot; data-origin-height=&quot;684&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;테스트 코드 왜 작성?&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 면접을 보는데 테스트 코드를 작성해야 하는 이유에 대해 질문이 들어왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 내가 작성한 코드가 안전하다는 것을 보장한다는 답을 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 이후에 꼬리 질문이 들어오니 면접관의 질문과 답변에 털리고 왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;테스트 코드를 작성하지 않아야 하는 상황?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 생각을 해보기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 2가지 정도를 생각했는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;유지 보수를 전혀 하지 않을 생각일 때&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기억력이 굉장&lt;/b&gt;해서 기존 코드를 수정할 때 어디에서 &lt;b&gt;어떤 결과가 나올지 알고 있을 때&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번 케이스는 잘 없을 것 같고..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각보다 1번 케이스는 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;짧은 기간동안 하는 프로젝트 경우에는 테스트 코드를 작성하는 것보다 빠르게 기능 개발을 우선으로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스타트업에서 재직할 때는 위 상황과는 달랐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 추가한 기능이 유지될 가능성이 굉장히 낮았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 상황일 때 나는 이렇게 합리화했다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;코드 생명 주기가 짧으니 기존 코드 개선보다는 아예 새로 만드는 것이 더 빠를 것이다.&lt;/li&gt;
&lt;li&gt;그냥 빠르게 기능 개발이나 하자.&lt;/li&gt;
&lt;li&gt;테스트 코드를 쓰면 오래 걸린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 반대로 추가한 기능이 오래 유지되는 경우도 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 아무리 내가 작성한 코드라도 몇개월이 지난 후에 다시 슬쩍 봐도 이해가 되지 않을 때가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 내가 작성한 코드라도 기억력은 완전하지 않기 때문에 언젠가는 남이 작성한 코드가 되는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;테스트 코드를 작성해야 하는 이유&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;u&gt;테스트 코드는 일종의 거름망이다.&lt;/u&gt;&lt;/i&gt; 라는 이야기를 인터넷에서 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 코드가 있어야 수정을 했을 때 어떤 상황인지 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 테스트 코드를 작성하지 않았다면 아래와 같은 상황이 생길 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;특정 코드가 수정이 되었을 때 이에 대한 영향을 받는 것들이 생긴다.&lt;/li&gt;
&lt;li&gt;영향받는 것들을 하나하나 확인한다.&lt;/li&gt;
&lt;li&gt;컴파일 에러가 난다면 좋지만 예상하지 않은 동작이 발생한다면 큰일이다.&lt;/li&gt;
&lt;li&gt;만약 잘 동작한다고 생각하고 배포했지만 이미 배포한 상태에서 에러를 발생할 수 있다.&lt;/li&gt;
&lt;li&gt;기존 기능 개발을 멈추고 핫픽스를 나간다.&lt;/li&gt;
&lt;li&gt;핫픽스가 나갔지만 또 어디선가 사이드 이펙트가 생겼다.&lt;/li&gt;
&lt;li&gt;(반복)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1812&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GQVHQ/btsDGYqUveP/0aKrhtDBaa3iKJgAigfhZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GQVHQ/btsDGYqUveP/0aKrhtDBaa3iKJgAigfhZ1/img.png&quot; data-alt=&quot;테스트 코드가 없을 때 상황&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GQVHQ/btsDGYqUveP/0aKrhtDBaa3iKJgAigfhZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGQVHQ%2FbtsDGYqUveP%2F0aKrhtDBaa3iKJgAigfhZ1%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;1812&quot; height=&quot;668&quot; data-origin-width=&quot;1812&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;테스트 코드가 없을 때 상황&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2148&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SY53p/btsDKKYLrGr/OdJx1LJEgnXnCHaWa5hfk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SY53p/btsDKKYLrGr/OdJx1LJEgnXnCHaWa5hfk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SY53p/btsDKKYLrGr/OdJx1LJEgnXnCHaWa5hfk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSY53p%2FbtsDKKYLrGr%2FOdJx1LJEgnXnCHaWa5hfk0%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;2148&quot; height=&quot;668&quot; data-origin-width=&quot;2148&quot; data-origin-height=&quot;668&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;p data-ke-size=&quot;size16&quot;&gt;위의 이미지를 보면 결국 똑같은 것 아닌가? 하는 생각이 들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;완벽한 테스트는 존재할 수 없기에 버그 발생 가능성이 0이 되는 것은 불가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 테스트 코드가 잘 작성이 되어있다면 버그 발생이 줄어든다는 것은 명확한 사실이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;테스트 자동화를 해야 하는 이유&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 코드 자동화는 필수라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트의 크기가 커질수록 더욱 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 모든 테스트 케이스를 돌려도 오래 걸리지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 몇초면 뚝딱하면서 테스트가 성공되고 PR을 올리면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 프로젝트가 커질수록 내가 작성한 테스트 코드만 돌리고 프로젝트 전체 테스트 코드를 돌리지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 되면 결국 테스트 코드를 작성한 이유가 사라지는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자동화를 통해서 반드시 테스트 케이스를 통과하도록 어느 정도 강제가 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;요약하자면...&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Q&lt;/b&gt;. 테스트 코드를 왜 작성해야 하나요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;A&lt;/b&gt;. 코드를 변경하는 것에 안전성을 부여하는 것 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Q&lt;/b&gt;. 안전하게 코드를 변경하는 것은 무슨 의미인가요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;A&lt;/b&gt;. 코드가 되었을 때 영향을 받는 다른 코드가 정상적으로 결과가 잘 나오는지 확인을 해야 합니다. 테스트 코드는 정상적으로 결과가 잘 나오는 지 확인 시켜주는 것이라고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 코드 작성에 대한 개인적인 생각입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 의견 있으시면 댓글 달아주시면 감사하겠습니다!  &amp;zwj;♂️ &lt;/p&gt;</description>
      <category>스위프트</category>
      <category>IOS</category>
      <category>swift</category>
      <category>test</category>
      <category>test code</category>
      <category>unittest</category>
      <category>테스트</category>
      <category>테스트 코드</category>
      <author>호구마츄</author>
      <guid isPermaLink="true">https://hogumachu.tistory.com/36</guid>
      <comments>https://hogumachu.tistory.com/36#entry36comment</comments>
      <pubDate>Sun, 21 Jan 2024 18:43:33 +0900</pubDate>
    </item>
    <item>
      <title>[iOS] 모듈화를 해야 하는 이유</title>
      <link>https://hogumachu.tistory.com/35</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발을 하면서 왜 모듈화를 해야 하는지에 대한 개인적인 이유입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 의견 있으시면 댓글 달아주시면 감사하겠습니다!  &amp;zwj;♂️ &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;캡슐화&lt;/b&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hogumachu.tistory.com/32&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2023.08.13 - [객체지향프로그래밍] - [OOP] 객체지향프로그래밍 기초&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1705214034379&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;[OOP] 객체지향프로그래밍 기초&quot; data-og-description=&quot;OOP의 개념 객체지향 프로그래밍 (Object Oriented Programming)은 프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라, 프로그램을 수많은 '객체(object)'라는 기본 단위로 나누고 이들의 상호&quot; data-og-host=&quot;hogumachu.tistory.com&quot; data-og-source-url=&quot;https://hogumachu.tistory.com/32&quot; data-og-url=&quot;https://hogumachu.tistory.com/32&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/BCa0Y/hyU2qXCagQ/aKpbbRSii9WbmOpGVBYkB0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/dgKBgg/hyU2ebOlzg/VmhoR528Rk2lFuKxyUhLx1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bcKayd/hyU5UCKwsR/gufut7uAxVIVuoWrk0ddLK/img.png?width=1564&amp;amp;height=1136&amp;amp;face=0_0_1564_1136&quot;&gt;&lt;a href=&quot;https://hogumachu.tistory.com/32&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hogumachu.tistory.com/32&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/BCa0Y/hyU2qXCagQ/aKpbbRSii9WbmOpGVBYkB0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/dgKBgg/hyU2ebOlzg/VmhoR528Rk2lFuKxyUhLx1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bcKayd/hyU5UCKwsR/gufut7uAxVIVuoWrk0ddLK/img.png?width=1564&amp;amp;height=1136&amp;amp;face=0_0_1564_1136');&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;[OOP] 객체지향프로그래밍 기초&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;OOP의 개념 객체지향 프로그래밍 (Object Oriented Programming)은 프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라, 프로그램을 수많은 '객체(object)'라는 기본 단위로 나누고 이들의 상호&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hogumachu.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캡슐화에 대한 자세한 내용은 위에 링크를 참조해 주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈 수준에서도 캡슐화가 진행되어야 한다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 진행하지 않는다면 외부에서 마음대로 접근할 수 있겠죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 ViewController, ViewModel, UseCase 등 마음대로 생성할 수 있고 설정 값을 변경할 수 있겠죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기능을 다 쓰지 않고 있다.&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈로 나누지 않는다면 주어진 기능을 다 사용하지 않는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Swift에서는 open, public, internal, fileprivate, private 이렇게 5개의 접근 제어자를 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈로 나누지 않는다면 open과 public을 버리고 있는 거죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pDaSz/btsDqhDeJmT/fqLt6sjeozRatIZRrRTQKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pDaSz/btsDqhDeJmT/fqLt6sjeozRatIZRrRTQKk/img.png&quot; data-alt=&quot;모듈화 안하면 기능 제대로 안쓰고 있는 것&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pDaSz/btsDqhDeJmT/fqLt6sjeozRatIZRrRTQKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpDaSz%2FbtsDqhDeJmT%2FfqLt6sjeozRatIZRrRTQKk%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;744&quot; height=&quot;384&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;모듈화 안하면 기능 제대로 안쓰고 있는 것&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;단일 책임 원칙&lt;/b&gt;&lt;/h2&gt;
&lt;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;MVC 아키텍처의 단점이 ViewController가 많은 기능을 담당하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희는 이것을 비즈니스 로직을 처리하는 ViewModel을 만들어 역할을 분리했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈 또한 마찬가지입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요한 역할을 할 수 있도록 나눠야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UIKit, SwiftUI 등 여러 모듈이 하나에 모여있다면 굉장히 무겁고 개발하기도 어려울 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;584&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqQTG4/btsDogSBPyW/TQrjbtuULFzxXgFeN42lr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqQTG4/btsDogSBPyW/TQrjbtuULFzxXgFeN42lr0/img.png&quot; data-alt=&quot;MVC &amp;amp;amp; MVVM&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqQTG4/btsDogSBPyW/TQrjbtuULFzxXgFeN42lr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqQTG4%2FbtsDogSBPyW%2FTQrjbtuULFzxXgFeN42lr0%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;1100&quot; height=&quot;584&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;584&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MVC &amp;amp; MVVM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;482&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5Dwtc/btsDuvmLhwm/Wf8k4x1S169Jrzwq5byra1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5Dwtc/btsDuvmLhwm/Wf8k4x1S169Jrzwq5byra1/img.png&quot; data-alt=&quot;Single/Multi Module&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5Dwtc/btsDuvmLhwm/Wf8k4x1S169Jrzwq5byra1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5Dwtc%2FbtsDuvmLhwm%2FWf8k4x1S169Jrzwq5byra1%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;1420&quot; height=&quot;482&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;482&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Single/Multi Module&lt;/figcaption&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;b&gt;독립적으로 만들 수 있다.&lt;/b&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;b&gt;모듈화를 진행&lt;/b&gt;했다면 인터페이스/구현체 구조로 나누어 느슨하게 연결하여 모듈에서도 &lt;b&gt;의존성 역전 원칙&lt;/b&gt;을 지킬 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모듈에 데모앱을 적용할 수 있게 된다.&lt;/li&gt;
&lt;li&gt;온전히 자신의 기능 개발을 할 수 있는 환경이 제공되므로 빠른 개발이 가능하다.&lt;/li&gt;
&lt;li&gt;버그가 발생했을 때 무엇이 문제인지 파악하기 쉬워진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 프로젝트를 진행하며 팀원들 모두 동일하게 겪었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 이에 대한 단점도 존재했는데 하단에 서술하도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;독립적으로 만들어진 상황에서 개발했을 때 느낀 점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능이 모두 독립적으로 만들어진 상황에서 개발했을 때 경험은 매우 좋았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 부분을 크게 신경 쓰지 않고 나만 잘하면 되는 상황이므로 속도는 매우 빨랐습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 이러한 상황 때문에 느낀 점이 몇몇 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 이해도 차이가 굉장히 심해진다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;독립적이라 내가 개발한 기능 외에는 이해도가 현저히 떨어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이로 인해 추후 유지보수할 때 내 기능을 제외하고는 건드리기 어려워집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 해결하기 위해 2가지 방법을 사용했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;코드 리뷰를 꼼꼼하게 한다.&lt;/li&gt;
&lt;li&gt;자주 서로 개발하던 기능을  바꾼다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 코드 리뷰를 꼼꼼하게 하는 것만으로는 해결이 불가능했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능 개발이 바빠 꼼꼼하게 하는 것도 어려웠지만 꼼꼼하게 하더라도 이해도 차이가 있을 수밖에 없었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 서로 개발하던 기능을 자주 바꾸는 것인데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 미처 빼먹고 갔던 부분도 파악하고 코드 리뷰를 하면서 왜 이런 식으로 개발했는 지 이해가 안 갔던 부분에 대한 히스토리를 직접 경험을 통해 이해가 되는 등 해당 문제는 해결이 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 이 방식을 사용하며 개발 속도가 많이 줄어드는 단점이 존재하긴 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 옳게 성장하고 있는 것인가에 대한 의구심&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;독립적으로 진행하니 사실상 특정 모듈만 공유하는 반쪽짜리 협업이 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스를 만드는 입장에서는 굉장히 빠르게 개발이 가능하므로 많은 장점이 존재했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 배우는 입장에서는 아쉬운 부분이 부분이 많았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 각 모듈별 연결하기, 공용으로 사용하는 모듈 제작하기 등 많지 않은 부분만 연관되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 각 모듈이 인터페이스로 느슨하게 연결된 것처럼 개발자끼리도 느슨하게 연결이 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 1번에서 작성한 방법으로 이해도 간격은 줄일 수 있었지만 팀과의 의사결정 방식 등 여러 부분에서는 아쉬운 부분이 많았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 해결할 수 있는 방법이 무엇이 있나 고민해봤습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;페어 프로그래밍을 진행한다.&lt;/li&gt;
&lt;li&gt;자주 상황 공유를 진행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페어 프로그래밍을 진행해 봤는데 꽤 좋았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 부분에서 비슷한 의사 결정을 하게 되었지만 그렇지 않은 부분도 많았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 과연 얼마나 페어 프로그래밍을 진행을 해야 하는가에 대한 고민도 생겼습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자주 상황 공유를 진행해봤는데 사람에 따라 불필요하다는 의견이 있어 오래가지 못했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;꽤나 길어지는 경우도 있었기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 경우는 결국 성장 중심으로 느꼈던 것이라 일할 때는 크게 반영되지 않는 부분 같습니다.&lt;/p&gt;</description>
      <category>스위프트</category>
      <category>IOS</category>
      <category>module</category>
      <category>OOP</category>
      <category>swift</category>
      <category>tuist</category>
      <category>객체지향프로그래밍</category>
      <category>단일 책임 원칙</category>
      <category>모듈화</category>
      <category>의존성 역전 원칙</category>
      <category>캡슐화</category>
      <author>호구마츄</author>
      <guid isPermaLink="true">https://hogumachu.tistory.com/35</guid>
      <comments>https://hogumachu.tistory.com/35#entry35comment</comments>
      <pubDate>Sun, 14 Jan 2024 16:50:10 +0900</pubDate>
    </item>
    <item>
      <title>[iOS] ViewController Life Cycle (+ ViewIsAppearing)</title>
      <link>https://hogumachu.tistory.com/34</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Overview&lt;/b&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;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;ViewController에 새로운 viewIsAppearing(_:) 메소드가 추가되었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;새로워진 ViewController의 생명 주기와 레이아웃은 어떤 방식으로 설정이 되는 지 알아봅시다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ViewController Life Cycle&lt;/b&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;ViewController에도 생명 주기가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리에 적재되어 레이아웃을 잡고 사용자에게 시각적으로 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 더이상 필요 없다면 사라집니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1173&quot; data-origin-height=&quot;2404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctA9w9/btssTp5JqS8/OaIKTLkVF5FwHZQsRmos6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctA9w9/btssTp5JqS8/OaIKTLkVF5FwHZQsRmos6k/img.png&quot; data-alt=&quot;ViewController 생명 주기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctA9w9/btssTp5JqS8/OaIKTLkVF5FwHZQsRmos6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctA9w9%2FbtssTp5JqS8%2FOaIKTLkVF5FwHZQsRmos6k%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;300&quot; height=&quot;615&quot; data-origin-width=&quot;1173&quot; data-origin-height=&quot;2404&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ViewController 생명 주기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;b&gt;init&lt;/b&gt;&lt;/b&gt;&lt;b&gt;&lt;b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 알고 있는 객체의 init 메소드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 먼저 호출이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;loadView&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewController가 관리하는 View를 만드는 메소드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;View를 로드하거나 생성하여 View Property에 할당합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플 문서에 따르면 해당 메소드는 직접 호출하지 말라고 작성되어있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;viewDidLoad&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewController가 View 계층 구조를 메모리에 로드한 후 호출됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;loadView 메소드를 통해 호출되었는지&amp;nbsp; nib 파일에서 로드되었는 지 관계없이 호출됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 메소드를 override 하여 View에 대한 추가적인 설정을 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;viewDidLoad는 한 번만 호출되므로 초기 설정을 하기 좋은 메소드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;viewWillAppear&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewController의 View가 View 계층 구조에 추가될 예정임을 알리는 메소드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;viewIsAppearing&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(iOS 13.0 이상 그리고 Xcode 15 (작성일 기준 베타 버전) 에서 ViewController에 viewIsAppearing이라는 메소드가 추가되었습니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewController의 View를 View 계층 구조에 추가하고 있음을 ViewController에게 알리는 메소드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;b&gt;viewDidAppear&lt;/b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewController의 View가 계층 구조에 추가되었음을 ViewController에 알리는 메소드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;viewWillDisappear&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewController의 View가 View 계층 구조에서 제거될 예정임을 알리는 메소드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;viewDidDisappear&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewController의 View가 View 계층 구조에서 제거되었음을 ViewController에 알리는 메소드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;deinit&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스가 메모리에서 해제될 때 호출되는 메소드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;화면에 View를 표시하는 방법&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;1394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mV0df/btssN0TpygF/OIxOBYF1XJlSK86lTofIK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mV0df/btssN0TpygF/OIxOBYF1XJlSK86lTofIK1/img.png&quot; data-alt=&quot;화면에 View를 표시하는 방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mV0df/btssN0TpygF/OIxOBYF1XJlSK86lTofIK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmV0df%2FbtssN0TpygF%2FOIxOBYF1XJlSK86lTofIK1%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;500&quot; height=&quot;651&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;1394&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;화면에 View를 표시하는 방법&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플 공식 문서에서는 viewIsAppearing(_:) 메소드에서 View에 대한 Content를 업데이트하라고 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이미 View는 View 계층 구조에 추가되어있기 때문&lt;/li&gt;
&lt;li&gt;frame, bounds, margin 그리고 inset이 정의되었기 때문&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;viewIsAppearing(_:) 메소드에 작성한 코드는 View가 화면에 처음 보여질 때 반영이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1693638728289&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;override func viewIsAppearing(_ animated: Bool) {
    super.viewIsAppearing(animated)
    print(&quot; &quot;, #function)
    print(&quot;SafeAreaInsets:&quot;, view.safeAreaInsets, #function)
    print(&quot;ViewFrame:&quot;, view.frame, #function)
    print(&quot;SomeViewFrame:&quot;, someView.frame, #function)
}&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;1758&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NHz7l/btssULmUXT7/5z7iddxIDtAmLxjpFMqEoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NHz7l/btssULmUXT7/5z7iddxIDtAmLxjpFMqEoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NHz7l/btssULmUXT7/5z7iddxIDtAmLxjpFMqEoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNHz7l%2FbtssULmUXT7%2F5z7iddxIDtAmLxjpFMqEoK%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;1758&quot; height=&quot;384&quot; data-origin-width=&quot;1758&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;viewIsAppearing(_:) 메소드에서는 ViewController의 View와 ViewController의 여러 값들은 잘 반영이 되어있으나 SubView에 대한 값은 아직 반영이 되지 않음을 알 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1693638930038&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    print(&quot; &quot;, #function)
    print(&quot;SomeViewFrame:&quot;, someView.frame, #function)
}&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;1758&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9bwfF/btssOuAhbXa/J7lcLng2cl2yCzkGd0DkkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9bwfF/btssOuAhbXa/J7lcLng2cl2yCzkGd0DkkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9bwfF/btssOuAhbXa/J7lcLng2cl2yCzkGd0DkkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9bwfF%2FbtssOuAhbXa%2FJ7lcLng2cl2yCzkGd0DkkK%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;1758&quot; height=&quot;288&quot; data-origin-width=&quot;1758&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;viewDidLayoutSubViews() 메소드를 통해 SubView에 대한 frame 값을 얻을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2개의 ViewController에서의 Life Cycle (NavigationController 사용)&lt;/b&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;754&quot; data-origin-height=&quot;946&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xCRvO/btssNjyUpm5/JW80LvZZ4hCHIaoAtIbDh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xCRvO/btssNjyUpm5/JW80LvZZ4hCHIaoAtIbDh1/img.png&quot; data-alt=&quot;ViewController Life Cycle&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xCRvO/btssNjyUpm5/JW80LvZZ4hCHIaoAtIbDh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxCRvO%2FbtssNjyUpm5%2FJW80LvZZ4hCHIaoAtIbDh1%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;500&quot; height=&quot;627&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;946&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ViewController Life Cycle&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewController의 생명 주기를 다시 살펴보면 위와 같습니다. (deinit이 빠져있군요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;748&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nAtha/btssVVW7uYd/768e6rIIXJeDPIuOqIfea1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nAtha/btssVVW7uYd/768e6rIIXJeDPIuOqIfea1/img.png&quot; data-alt=&quot;NavigationController를 활용하여 ViewController 이동&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nAtha/btssVVW7uYd/768e6rIIXJeDPIuOqIfea1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnAtha%2FbtssVVW7uYd%2F768e6rIIXJeDPIuOqIfea1%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;600&quot; height=&quot;575&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;748&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;NavigationController를 활용하여 ViewController 이동&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초록색 ViewController 에서 붉은색 ViewController 로 이동하고 다시 돌아올 때 ViewController가 호출하는 메소드를 살펴봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1108&quot; data-origin-height=&quot;1612&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3AXND/btssVMMHi8U/9O80kmWuzvnQQrSer9q6o1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3AXND/btssVMMHi8U/9O80kmWuzvnQQrSer9q6o1/img.png&quot; data-alt=&quot;2개의 ViewController Life Cycle&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3AXND/btssVMMHi8U/9O80kmWuzvnQQrSer9q6o1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3AXND%2FbtssVMMHi8U%2F9O80kmWuzvnQQrSer9q6o1%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;600&quot; height=&quot;873&quot; data-origin-width=&quot;1108&quot; data-origin-height=&quot;1612&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;2개의 ViewController Life Cycle&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초록색 ViewController (aka. &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;GVC&lt;/b&gt;&lt;/span&gt;) 에서 붉은색 ViewController (aka. &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;RVC&lt;/b&gt;&lt;/span&gt;)로 이동할 때를 살펴봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;RVC&lt;/b&gt;&lt;/span&gt;가 init, loadView 그리고 viewDidLoad까지 진행된 후에&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;GVC&lt;/b&gt;&lt;/span&gt;의 viewWillDisappear 메소드가 호출됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;2. &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;RVC&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;의 viewIsAppearing 메소드가 호출된 후에&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;GVC&lt;/b&gt;&lt;/span&gt;가 사라지고&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;RVC&lt;/b&gt;&lt;/span&gt;가 등장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;RVC&lt;/b&gt;&lt;/span&gt;에서&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;GVC&lt;/b&gt;&lt;/span&gt;로 돌아올 때,&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;RVC&lt;/b&gt;&lt;/span&gt;가 먼저 자신이 사라진다고 알린 후&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;GVC&lt;/b&gt;&lt;/span&gt;는 viewWillAppear, viewIsAppearing 메소드를 호출하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;RVC&lt;/b&gt;&lt;/span&gt;가 사라지고난 후&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;GVC&lt;/b&gt;&lt;/span&gt;는 나타나고 그 후&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;RVC&lt;/b&gt;&lt;/span&gt;는 deinit이 되어 메모리에서 해제됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;1982&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dC637E/btssVHkizyS/kkL12C73r4NNSZatDIZP21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dC637E/btssVHkizyS/kkL12C73r4NNSZatDIZP21/img.png&quot; data-alt=&quot;2개 ViewController의 메소드들을 print로 출력한 것&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dC637E/btssVHkizyS/kkL12C73r4NNSZatDIZP21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdC637E%2FbtssVHkizyS%2FkkL12C73r4NNSZatDIZP21%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;500&quot; height=&quot;1314&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;1982&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;2개 ViewController의 메소드들을 print로 출력한 것&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;마무리&lt;/b&gt;&lt;/h2&gt;
&lt;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;간략하게 추가된 viewIsAppearing과 다른 메소드에 대해 살펴봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;viewIsAppearing 메소드가 한 번만 호출되는 줄 알았지만 여러 번 호출되더라구요. (viewWillAppear -&amp;gt; viewIsAppearing)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;viewIsAppearing 에 초기 설정을 하면 다시 돌아왔을 때 초기 설정으로 돌아옵니다. 따라서 잘 확인하고 사용해야할 것 같아요.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;읽어 주셔서 감사합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;참고&lt;/b&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;a href=&quot;https://developer.apple.com/documentation/uikit/uiviewcontroller/1621454-loadview&quot;&gt;https://developer.apple.com/documentation/uikit/uiviewcontroller/1621454-loadview&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiviewcontroller/1621495-viewdidload&quot;&gt;https://developer.apple.com/documentation/uikit/uiviewcontroller/1621495-viewdidload&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiviewcontroller/1621510-viewwillappear&quot;&gt;https://developer.apple.com/documentation/uikit/uiviewcontroller/1621510-viewwillappear&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiviewcontroller/4195485-viewisappearing&quot;&gt;https://developer.apple.com/documentation/uikit/uiviewcontroller/4195485-viewisappearing&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiviewcontroller/1621423-viewdidappear&quot;&gt;https://developer.apple.com/documentation/uikit/uiviewcontroller/1621423-viewdidappear&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiviewcontroller/1621485-viewwilldisappear&quot;&gt;https://developer.apple.com/documentation/uikit/uiviewcontroller/1621485-viewwilldisappear&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiviewcontroller/1621477-viewdiddisappear&quot;&gt;https://developer.apple.com/documentation/uikit/uiviewcontroller/1621477-viewdiddisappear&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/uikit/view_controllers/displaying_and_managing_views_with_a_view_controller#3370691&quot;&gt;https://developer.apple.com/documentation/uikit/view_controllers/displaying_and_managing_views_with_a_view_controller#3370691&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2023/10055/?time=128&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.apple.com/videos/play/wwdc2023/10055/?time=128&lt;/a&gt;&lt;/p&gt;</description>
      <category>스위프트</category>
      <category>IOS</category>
      <category>LifeCycle</category>
      <category>swift</category>
      <category>Viewcontroller</category>
      <category>ViewControllerLifeCycle</category>
      <category>ViewIsAppearing</category>
      <category>WWDC23</category>
      <author>호구마츄</author>
      <guid isPermaLink="true">https://hogumachu.tistory.com/34</guid>
      <comments>https://hogumachu.tistory.com/34#entry34comment</comments>
      <pubDate>Sat, 2 Sep 2023 16:58:12 +0900</pubDate>
    </item>
  </channel>
</rss>