<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>휘뚜루 마뚜루-TJ</title>
    <link>https://developer-tj.tistory.com/</link>
    <description>공부하고 있는 내용을 정리하는 블로그입니다.</description>
    <language>ko</language>
    <pubDate>Sat, 11 Apr 2026 11:31:36 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>developer-tj</managingEditor>
    <item>
      <title>Wireshark(와이어샤크)로 TLS로 암호화된 패킷 복호화 하기</title>
      <link>https://developer-tj.tistory.com/60</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크&amp;nbsp;트래픽을&amp;nbsp;모니터링하고&amp;nbsp;분석하는데&amp;nbsp;널리&amp;nbsp;사용되는&amp;nbsp;Wireshark는&amp;nbsp;TLS(Transport&amp;nbsp;Layer&amp;nbsp;Security)와&amp;nbsp;같은&amp;nbsp;암호화&amp;nbsp;프로토콜을&amp;nbsp;사용하여&amp;nbsp;보호된&amp;nbsp;패킷을&amp;nbsp;캡처할&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만&amp;nbsp;TLS로&amp;nbsp;암호화된&amp;nbsp;패킷을&amp;nbsp;캡처했다고&amp;nbsp;해서&amp;nbsp;패킷의&amp;nbsp;내용을&amp;nbsp;쉽게&amp;nbsp;이해할&amp;nbsp;수는&amp;nbsp;없습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한&amp;nbsp;암호화된&amp;nbsp;패킷을&amp;nbsp;복호화하여&amp;nbsp;내용을&amp;nbsp;확인하려면&amp;nbsp;Wireshark에서&amp;nbsp;몇&amp;nbsp;가지&amp;nbsp;추가&amp;nbsp;설정이&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;TLS로&amp;nbsp;암호화된&amp;nbsp;패킷을&amp;nbsp;복호화하는&amp;nbsp;방법을&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;TLS로 암호화된 패킷을 복호화 하기&lt;/h3&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. C:\SSLKEYLOGFILE 폴더를 생성합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4o3F0/btsGUNzx8Fi/p0yk8GkOGTTbgNAsdZg5N1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4o3F0/btsGUNzx8Fi/p0yk8GkOGTTbgNAsdZg5N1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4o3F0/btsGUNzx8Fi/p0yk8GkOGTTbgNAsdZg5N1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4o3F0%2FbtsGUNzx8Fi%2Fp0yk8GkOGTTbgNAsdZg5N1%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;801&quot; height=&quot;273&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;273&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;2. 찾기에서 &quot;시스템 환경 변수 편집&quot; 으로 들어갑니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;680&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zU2sv/btsGXjDucra/cKwFLwQjJHOCUlEGnzi7OK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zU2sv/btsGXjDucra/cKwFLwQjJHOCUlEGnzi7OK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zU2sv/btsGXjDucra/cKwFLwQjJHOCUlEGnzi7OK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzU2sv%2FbtsGXjDucra%2FcKwFLwQjJHOCUlEGnzi7OK%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;784&quot; height=&quot;680&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;680&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;3. &quot;환경 변수&quot; -&amp;gt; 시스템 변수 &quot;새로 만들기&quot; 를 클릭합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 새 시스템 변수에 변수 이름을 SSLKEYLOGFILE 로 입력하고, 변수 값을 C:\SSLKEYLOGFILE\sslkey.log 로 입력 후 확인 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;589&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvYU2V/btsGT8cKW5x/bl0FhzMM21AFHmHvuyjJ6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvYU2V/btsGT8cKW5x/bl0FhzMM21AFHmHvuyjJ6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvYU2V/btsGT8cKW5x/bl0FhzMM21AFHmHvuyjJ6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvYU2V%2FbtsGT8cKW5x%2Fbl0FhzMM21AFHmHvuyjJ6k%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;1098&quot; height=&quot;589&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;589&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. 크롬으로 &lt;a href=&quot;http://www.google.com&quot;&gt;www.google.com&lt;/a&gt; 에 접속합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. C:\SSLKEYLOGFILE 폴더에 sslkey.log 파일이 생성된 것을 확인합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1222&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2V0vL/btsGVdY63TR/ACoIUkeiENkGEKMEKD0pf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2V0vL/btsGVdY63TR/ACoIUkeiENkGEKMEKD0pf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2V0vL/btsGVdY63TR/ACoIUkeiENkGEKMEKD0pf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2V0vL%2FbtsGVdY63TR%2FACoIUkeiENkGEKMEKD0pf0%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;1222&quot; height=&quot;571&quot; data-origin-width=&quot;1222&quot; data-origin-height=&quot;571&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;7. Wireshark를 실행하고 &quot;편집&quot; -&amp;gt; &quot;설정&quot; 으로 들어갑니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;913&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Lpndw/btsGUXaZHUh/Felk7jhCNQVVPQezZybHQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Lpndw/btsGUXaZHUh/Felk7jhCNQVVPQezZybHQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Lpndw/btsGUXaZHUh/Felk7jhCNQVVPQezZybHQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLpndw%2FbtsGUXaZHUh%2FFelk7jhCNQVVPQezZybHQK%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;913&quot; height=&quot;632&quot; data-origin-width=&quot;913&quot; data-origin-height=&quot;632&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;8. &quot;protocols&quot; -&amp;gt; &quot;TLS&quot; 를 선택합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9. (Pre)-Master-Secret log filename 에 C:\SSLKEYLOGFILE\sslkey.log 경로를 입력 후 확인합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uMOhV/btsGVLuiq01/vMSKc4T2PybsqzXxPLAsSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uMOhV/btsGVLuiq01/vMSKc4T2PybsqzXxPLAsSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uMOhV/btsGVLuiq01/vMSKc4T2PybsqzXxPLAsSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuMOhV%2FbtsGVLuiq01%2FvMSKc4T2PybsqzXxPLAsSK%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;723&quot; height=&quot;571&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;571&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;10. 패킷 캡처 시작을 하고 네이버에서 test 란 문구로 검색을 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;11. 복호화 된 패킷를 확인합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1194&quot; data-origin-height=&quot;716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byGVfo/btsGWQobt22/rk5nUyEYTeKG6DK5HNIrKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byGVfo/btsGWQobt22/rk5nUyEYTeKG6DK5HNIrKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byGVfo/btsGWQobt22/rk5nUyEYTeKG6DK5HNIrKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyGVfo%2FbtsGWQobt22%2Frk5nUyEYTeKG6DK5HNIrKK%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;1194&quot; height=&quot;716&quot; data-origin-width=&quot;1194&quot; data-origin-height=&quot;716&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;12. 설정에서 .&quot;protocols&quot; -&amp;gt; &quot;TLS&quot;&amp;nbsp; -&amp;gt; (Pre)-Master-Secret log filename 항목을 삭제하고 다시 해당 패킷을 확인합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dsv2uv/btsGXqvKVkn/uAxArW8cA0qIjjyLlla950/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dsv2uv/btsGXqvKVkn/uAxArW8cA0qIjjyLlla950/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dsv2uv/btsGXqvKVkn/uAxArW8cA0qIjjyLlla950/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdsv2uv%2FbtsGXqvKVkn%2FuAxArW8cA0qIjjyLlla950%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;723&quot; height=&quot;571&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;571&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;13. 다시 암호화 된 패킷을 확인 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1199&quot; data-origin-height=&quot;732&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ldrAM/btsGUKv6AzA/qEXIbnnffkKKAAxUamls3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ldrAM/btsGUKv6AzA/qEXIbnnffkKKAAxUamls3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ldrAM/btsGUKv6AzA/qEXIbnnffkKKAAxUamls3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FldrAM%2FbtsGUKv6AzA%2FqEXIbnnffkKKAAxUamls3k%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;1199&quot; height=&quot;732&quot; data-origin-width=&quot;1199&quot; data-origin-height=&quot;732&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;a href=&quot;https://developer-tj.tistory.com/59&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Wireshark(와이어샤크)&amp;nbsp;설치&amp;nbsp;방법&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타</category>
      <category>decrypt tls packets</category>
      <category>tls</category>
      <category>tls decrypt</category>
      <category>tls 패킷 복호화</category>
      <category>wireshark tls decrypt</category>
      <author>developer-tj</author>
      <guid isPermaLink="true">https://developer-tj.tistory.com/60</guid>
      <comments>https://developer-tj.tistory.com/60#entry60comment</comments>
      <pubDate>Thu, 25 Apr 2024 19:36:38 +0900</pubDate>
    </item>
    <item>
      <title>Wireshark(와이어샤크) 설치 방법</title>
      <link>https://developer-tj.tistory.com/59</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;WireShark란 무엇인가요?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WireShark는 네트워크 패킷 분석 도구로, 네트워크 트래픽을 캡처하고 분석하는 데 사용됩니다. 이 도구는 개발자, 시스템 관리자, 보안 전문가 및 네트워크 엔지니어들 사이에서 널리 사용되며, 다양한 용도로 활용됩니다.&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;WireShark의 중요성&lt;/b&gt;&lt;/h3&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;: 악의적인 트래픽을 감지하고 네트워크 보안 위협을 식별하는 데 사용됩니다. WireShark를 사용하여 네트워크에서 이상한 활동을 모니터링하고 보안 이벤트를 탐지할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프로토콜 분석&lt;/b&gt;: 다양한 네트워크 프로토콜을 지원하며, 프로토콜의 동작을 이해하고 문제를 해결하는 데 도움이 됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;네트워크 성능 튜닝&lt;/b&gt;: 네트워크 성능을 개선하기 위해 트래픽 패턴을 분석하고 최적화할 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;WireShark의 기능&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다양한 네트워크 프로토콜 지원: Ethernet, TCP/IP, UDP, HTTP, SSL 등 다양한 프로토콜을 지원합니다.&lt;/li&gt;
&lt;li&gt;실시간 패킷 캡처: 네트워크 트래픽을 실시간으로 캡처하여 분석할 수 있습니다.&lt;/li&gt;
&lt;li&gt;패킷 필터링: 원하는 프로토콜이나 주소로 패킷을 필터링하여 원하는 정보만 볼 수 있습니다.&lt;/li&gt;
&lt;li&gt;패킷 분석 및 통계: 패킷을 분석하고 통계를 생성하여 네트워크 동작을 이해하고 문제를 해결할 수 있습니다.&lt;/li&gt;
&lt;/ul&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;WireShark 설치 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;a href=&quot;https://www.wireshark.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.wireshark.org&lt;/a&gt; 에 접속합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1858&quot; data-origin-height=&quot;975&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwQmW3/btsGNt788oY/oawjsrkARGvpgmYTmjyeyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwQmW3/btsGNt788oY/oawjsrkARGvpgmYTmjyeyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwQmW3/btsGNt788oY/oawjsrkARGvpgmYTmjyeyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwQmW3%2FbtsGNt788oY%2FoawjsrkARGvpgmYTmjyeyk%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;1858&quot; height=&quot;975&quot; data-origin-width=&quot;1858&quot; data-origin-height=&quot;975&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;2. &quot;Get started&quot; 를 클릭합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1858&quot; data-origin-height=&quot;975&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MIfK7/btsGPpQ8Lkt/Jwdms2tI7rl0lctSp1kd81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MIfK7/btsGPpQ8Lkt/Jwdms2tI7rl0lctSp1kd81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MIfK7/btsGPpQ8Lkt/Jwdms2tI7rl0lctSp1kd81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMIfK7%2FbtsGPpQ8Lkt%2FJwdms2tI7rl0lctSp1kd81%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;1858&quot; height=&quot;975&quot; data-origin-width=&quot;1858&quot; data-origin-height=&quot;975&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;3. &quot;Windows x64 Installer&quot; 선택하여 다운로드 받습니다. (자신의 OS에 맞는 버전을 선택합니다.)&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;805&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lW8R8/btsGNZS2uk3/vUgTwu4EbzzNC2pd0k5jbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lW8R8/btsGNZS2uk3/vUgTwu4EbzzNC2pd0k5jbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lW8R8/btsGNZS2uk3/vUgTwu4EbzzNC2pd0k5jbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlW8R8%2FbtsGNZS2uk3%2FvUgTwu4EbzzNC2pd0k5jbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;805&quot; height=&quot;312&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;312&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;4. 다운받은 Wireshark-4.2.4-x64.exe 파일을 실행합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfLtKL/btsGPpp4FCt/3PsEYt4HHtjKhykD0BsI91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfLtKL/btsGPpp4FCt/3PsEYt4HHtjKhykD0BsI91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfLtKL/btsGPpp4FCt/3PsEYt4HHtjKhykD0BsI91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfLtKL%2FbtsGPpp4FCt%2F3PsEYt4HHtjKhykD0BsI91%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Next 클릭&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; 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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjsqnF/btsGNz1uyCv/f3PvgB7VFWggcsO8lurFnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjsqnF/btsGNz1uyCv/f3PvgB7VFWggcsO8lurFnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjsqnF/btsGNz1uyCv/f3PvgB7VFWggcsO8lurFnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjsqnF%2FbtsGNz1uyCv%2Ff3PvgB7VFWggcsO8lurFnk%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Next 클릭&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; 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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9C3oW/btsGMHTBwd3/MaTAhGcFU9MxdSH3prGzq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9C3oW/btsGMHTBwd3/MaTAhGcFU9MxdSH3prGzq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9C3oW/btsGMHTBwd3/MaTAhGcFU9MxdSH3prGzq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9C3oW%2FbtsGMHTBwd3%2FMaTAhGcFU9MxdSH3prGzq0%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Next 클릭&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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjI3y5/btsGNuzenDT/gPoD3rt1lWTktZCi1FkEQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjI3y5/btsGNuzenDT/gPoD3rt1lWTktZCi1FkEQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjI3y5/btsGNuzenDT/gPoD3rt1lWTktZCi1FkEQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjI3y5%2FbtsGNuzenDT%2FgPoD3rt1lWTktZCi1FkEQ0%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Next 클릭&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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJqi8b/btsGNFgcF0e/1xO3qAjRQiPwrIP1Mqbgv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJqi8b/btsGNFgcF0e/1xO3qAjRQiPwrIP1Mqbgv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJqi8b/btsGNFgcF0e/1xO3qAjRQiPwrIP1Mqbgv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJqi8b%2FbtsGNFgcF0e%2F1xO3qAjRQiPwrIP1Mqbgv1%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Next 클릭&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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cobbhM/btsGMCEVsxa/sJJYWa56gDzk2fKINWWH51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cobbhM/btsGMCEVsxa/sJJYWa56gDzk2fKINWWH51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cobbhM/btsGMCEVsxa/sJJYWa56gDzk2fKINWWH51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcobbhM%2FbtsGMCEVsxa%2FsJJYWa56gDzk2fKINWWH51%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Next 클릭&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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8nAg8/btsGO822z7O/AuiSMkzESyJBrnm6tN88z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8nAg8/btsGO822z7O/AuiSMkzESyJBrnm6tN88z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8nAg8/btsGO822z7O/AuiSMkzESyJBrnm6tN88z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8nAg8%2FbtsGO822z7O%2FAuiSMkzESyJBrnm6tN88z0%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Next 클릭&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;( Npcap를 설치하기 위한 확인 내용입니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Npcap은 네트워크 패킷 캡처 및 인젝션 라이브러리입니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이는&amp;nbsp;윈도우&amp;nbsp;운영&amp;nbsp;체제에서&amp;nbsp;네트워크&amp;nbsp;트래픽을&amp;nbsp;캡처하고&amp;nbsp;분석하기&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위한&amp;nbsp;도구와&amp;nbsp;애플리케이션에서&amp;nbsp;사용됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Npcap은 WireShark와 같은 네트워크 분석 도구에서&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; 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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m6rmi/btsGPSZXpU8/8DZ5Prq0rgmzD5bGgIepnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m6rmi/btsGPSZXpU8/8DZ5Prq0rgmzD5bGgIepnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m6rmi/btsGPSZXpU8/8DZ5Prq0rgmzD5bGgIepnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm6rmi%2FbtsGPSZXpU8%2F8DZ5Prq0rgmzD5bGgIepnK%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Install 클릭&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;( &lt;span style=&quot;color: #333333; text-align: center;&quot;&gt;&lt;span&gt; USBPcap &lt;/span&gt;를 설치하기 위한 확인 내용입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;USBPcap은 USB 데이터를 캡처하고 분석하기 위한 도구입니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; 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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfJdQJ/btsGN05uouR/rnRyTJ6TPGH9JHToNnxOtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfJdQJ/btsGN05uouR/rnRyTJ6TPGH9JHToNnxOtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfJdQJ/btsGN05uouR/rnRyTJ6TPGH9JHToNnxOtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfJdQJ%2FbtsGN05uouR%2FrnRyTJ6TPGH9JHToNnxOtK%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;설치 도중 Npcap 설치 화면이 별도로 뜹니다.&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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3VEDv/btsGPbeoiOs/4xE38jAooolvMF6W4Q5uT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3VEDv/btsGPbeoiOs/4xE38jAooolvMF6W4Q5uT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3VEDv/btsGPbeoiOs/4xE38jAooolvMF6W4Q5uT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3VEDv%2FbtsGPbeoiOs%2F4xE38jAooolvMF6W4Q5uT1%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;I Agree 클릭&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; 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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V49jT/btsGO9t5J6H/OaLTKn45ZtnuXekk6g95Sk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V49jT/btsGO9t5J6H/OaLTKn45ZtnuXekk6g95Sk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V49jT/btsGO9t5J6H/OaLTKn45ZtnuXekk6g95Sk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV49jT%2FbtsGO9t5J6H%2FOaLTKn45ZtnuXekk6g95Sk%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Install 클릭&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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uDoOX/btsGM322YCZ/FA7eLc23GH2O6nb06SKzDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uDoOX/btsGM322YCZ/FA7eLc23GH2O6nb06SKzDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uDoOX/btsGM322YCZ/FA7eLc23GH2O6nb06SKzDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuDoOX%2FbtsGM322YCZ%2FFA7eLc23GH2O6nb06SKzDk%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Next 클릭&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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UkW2N/btsGPoEHwKN/LDVH24frKoGYskj2HYk8yK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UkW2N/btsGPoEHwKN/LDVH24frKoGYskj2HYk8yK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UkW2N/btsGPoEHwKN/LDVH24frKoGYskj2HYk8yK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUkW2N%2FbtsGPoEHwKN%2FLDVH24frKoGYskj2HYk8yK%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Next 클릭&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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvshFC/btsGMMtMrjm/XkxWfairAX0QfkvpMUcbMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvshFC/btsGMMtMrjm/XkxWfairAX0QfkvpMUcbMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvshFC/btsGMMtMrjm/XkxWfairAX0QfkvpMUcbMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvshFC%2FbtsGMMtMrjm%2FXkxWfairAX0QfkvpMUcbMk%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Finish 클릭&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;( &lt;span style=&quot;color: #333333; text-align: center;&quot;&gt;Npcap&lt;span&gt; 설치가 끝나고 Wireshark 설치가 이어서 진행됩니다.)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PWKAV/btsGM3PwLsj/nqxHbKJFMUDMeKCuEZGBC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PWKAV/btsGM3PwLsj/nqxHbKJFMUDMeKCuEZGBC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PWKAV/btsGM3PwLsj/nqxHbKJFMUDMeKCuEZGBC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPWKAV%2FbtsGM3PwLsj%2FnqxHbKJFMUDMeKCuEZGBC0%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Next 클릭&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;499&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvfuoW/btsGMgB0yLx/WUwGkCyL2rccky2BQOi151/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvfuoW/btsGMgB0yLx/WUwGkCyL2rccky2BQOi151/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvfuoW/btsGMgB0yLx/WUwGkCyL2rccky2BQOi151/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdvfuoW%2FbtsGMgB0yLx%2FWUwGkCyL2rccky2BQOi151%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;499&quot; height=&quot;388&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Finish 클릭&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. 설치된&amp;nbsp; Wireshark를 실행합니다. (설치 경로 &quot;C:\Program Files\Wireshark\Wireshark.exe&quot; )&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9k8w1/btsGMFass0H/hUe1KspiMnKuvorGfUK4J1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9k8w1/btsGMFass0H/hUe1KspiMnKuvorGfUK4J1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9k8w1/btsGMFass0H/hUe1KspiMnKuvorGfUK4J1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9k8w1%2FbtsGMFass0H%2FhUe1KspiMnKuvorGfUK4J1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;805&quot; height=&quot;512&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;512&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;6. 실행된 Wireshark를 확인합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;752&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm4nxi/btsGMDKDTbx/jpQMPAuMlfkjL32HWfJW6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm4nxi/btsGMDKDTbx/jpQMPAuMlfkjL32HWfJW6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm4nxi/btsGMDKDTbx/jpQMPAuMlfkjL32HWfJW6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm4nxi%2FbtsGMDKDTbx%2FjpQMPAuMlfkjL32HWfJW6K%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;752&quot; height=&quot;582&quot; data-origin-width=&quot;752&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>기타</category>
      <category>wireshark</category>
      <category>Wireshark install</category>
      <category>Wireshark 설치</category>
      <category>와이어샤크</category>
      <category>와이어샤크 설치</category>
      <author>developer-tj</author>
      <guid isPermaLink="true">https://developer-tj.tistory.com/59</guid>
      <comments>https://developer-tj.tistory.com/59#entry59comment</comments>
      <pubDate>Sun, 21 Apr 2024 14:21:36 +0900</pubDate>
    </item>
    <item>
      <title>냄새 14. 성의 없는 요소(Lazy Element)</title>
      <link>https://developer-tj.tistory.com/58</link>
      <description>&lt;p&gt;성의 없는 요소(Lazy Element)는 프로그램에서 사용하지 않는 코드 또는 기능을 가리키는 코드 냄새 중 하나입니다.&lt;br&gt;이러한 코드는 작성 시 개발자가 과거 또는 현재의 개발자가 아닌 미래의 다른 개발자들을 위해 만드는 것이 좋습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;성의없는 요소는 코드의 복잡도를 증가시키고, 유지보수와 확장성을 어렵게 만듭니다.&lt;br&gt;또한 이러한 코드는 프로그램의 실행 속도를 늦출 수 있습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;성의없는 요소를 제거하는 방법 중 하나는, 불필요한 코드를 제거하고 단순하게 유지보수할 수 있는 코드로 수정하는 것입니다.&lt;br&gt;이러한 작업은 코드 리팩터링 과정에서 수행됩니다.&lt;br&gt;예를 들어, 사용하지 않는 변수나 함수를 제거하거나, 중복된 코드를 제거하거나, 불필요한 주석을 제거하는 등의 작업이 이에 해당합니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;또 다른 방법으로는, 불필요한 기능을 가진 코드를 주석 처리하거나, 디버깅을 위해 남겨두는 것입니다.&lt;br&gt;이 경우에도, 코드를 정리하고 주석을 추가하여 코드의 가독성을 높일 필요가 있습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;성의없는 요소를 제거하면 코드의 가독성과 유지보수성을 향상시키고, 불필요한 코드 실행으로 인한 성능 저하를 방지할 수 있습니다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;적용 가능한 리팩터링 기법&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer-tj.tistory.com/42&quot; target=&quot;_blank&quot;&gt;함수 인라인(Inline Function)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer-tj.tistory.com/47&quot; target=&quot;_blank&quot;&gt;클래스 인라인(Inline Class)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;계층 합치기(Collapse Hierarchy)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>리팩터링/냄새 (리팩터링할 시점)</category>
      <category>Code Smell</category>
      <category>Lazy Element</category>
      <category>Refactoring</category>
      <category>리팩터링</category>
      <category>리팩토링</category>
      <category>성의 없는 요소</category>
      <category>코드 냄새</category>
      <author>developer-tj</author>
      <guid isPermaLink="true">https://developer-tj.tistory.com/58</guid>
      <comments>https://developer-tj.tistory.com/58#entry58comment</comments>
      <pubDate>Sat, 8 Apr 2023 12:00:44 +0900</pubDate>
    </item>
    <item>
      <title>리팩터링 기법. 반복문을 파이프라인으로 바꾸기(Replace Loop with Pipeline)</title>
      <link>https://developer-tj.tistory.com/57</link>
      <description>&lt;p&gt;반복문을 파이프라인으로 바꾸기(Replace Loop with Pipeline)는 컬렉션을 다루는 로직에서 특히 효과적인 기법입니다.&lt;br&gt;기존에는 반복문을 사용하여 컬렉션의 원소를 하나씩 처리했지만, 이를 파이프라인으로 변경하여 더욱 간결하고 가독성이 좋은 코드로 만드는 것입니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;파이프라인은 입력 데이터를 처리하고 출력 데이터를 생성하는 여러 단계로 나누어져 있는 프로세스를 의미합니다.&lt;br&gt;각 단계는 이전 단계의 출력을 입력으로 받아 다음 단계의 출력을 생성합니다.&lt;br&gt;이러한 구조를 활용하여 컬렉션을 처리하는 코드를 구현할 수 있습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;예를 들어, 다음과 같은 반복문 코드가 있다고 가정해 봅시다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
std::vector&lt;int&gt; numbers = {1, 2, 3, 4, 5};
std::vector&lt;int&gt; doubledNumbers;
for (int number : numbers) {
    doubledNumbers.push_back(number * 2);
}
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;위 코드는 벡터 numbers의 모든 원소를 순회하며 각 원소에 2를 곱한 결과를 doubledNumbers 벡터에 추가하는 코드입니다.&lt;br&gt;하지만 이를 파이프라인으로 변경하면 다음과 같이 더 간결하고 가독성이 좋은 코드를 구현할 수 있습니다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
std::vector&lt;int&gt; numbers = {1, 2, 3, 4, 5};
std::transform(numbers.begin(), numbers.end(), std::back_inserter(doubledNumbers), [](int number) { return number * 2; });
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;위 코드에서는 std::transform() 함수를 사용하여 벡터 numbers의 모든 원소에 2를 곱한 결과를 doubledNumbers 벡터에 추가하고 있습니다.&lt;br&gt;std::transform() 함수는 STL의 알고리즘 중 하나로, 입력 범위와 출력 범위를 지정하고 변환 함수를 지정하여 입력 범위의 모든 요소를 변환한 결과를 출력 범위에 저장합니다.&lt;br&gt;이렇게 변환된 데이터를 다시 다른 함수에 입력으로 넘겨 파이프라인을 구성할 수 있습니다.&lt;br&gt;이 코드는 반복문을 사용한 기존 코드보다 더 간결하고 가독성이 좋습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;반복문을 파이프라인으로 변경하는 것은 코드의 가독성과 유지보수성을 향상시키는 데 큰 도움이 됩니다.&lt;br&gt;특히 컬렉션을 다루는 코드에서는 파이프라인을 활용하여 불필요한 반복문을 제거하고 간결하고 명확한 코드를 구현하는 것이 좋습니다.&lt;/p&gt;</description>
      <category>리팩터링/리팩터링 기법</category>
      <category>Refactoring</category>
      <category>Replace Loop with Pipeline</category>
      <category>리팩터링</category>
      <category>리팩터링 기법</category>
      <category>리팩토링</category>
      <category>리팩토링 기법</category>
      <category>반복문을 파이프라인으로 바꾸기</category>
      <author>developer-tj</author>
      <guid isPermaLink="true">https://developer-tj.tistory.com/57</guid>
      <comments>https://developer-tj.tistory.com/57#entry57comment</comments>
      <pubDate>Fri, 7 Apr 2023 12:00:29 +0900</pubDate>
    </item>
    <item>
      <title>std::variant</title>
      <link>https://developer-tj.tistory.com/56</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;std::variant는 C++17에서 추가된 표준 라이브러리 클래스로, 여러 타입 중 하나를 저장할 수 있는 유연한 클래스입니다. &lt;br /&gt;이전에는&amp;nbsp;유사한&amp;nbsp;기능을&amp;nbsp;하는&amp;nbsp;std::any를&amp;nbsp;사용해왔으나,&amp;nbsp;std::variant는&amp;nbsp;더욱&amp;nbsp;타입&amp;nbsp;안전하고&amp;nbsp;간결하게&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있습니다. &lt;br /&gt;std::variant는&amp;nbsp;일반적으로&amp;nbsp;union과&amp;nbsp;비슷한&amp;nbsp;방식으로&amp;nbsp;작동합니다.&amp;nbsp;즉,&amp;nbsp;저장된&amp;nbsp;값은&amp;nbsp;선택한&amp;nbsp;타입의&amp;nbsp;크기와&amp;nbsp;정렬&amp;nbsp;요구&amp;nbsp;사항을&amp;nbsp;따릅니다. &lt;br /&gt;&lt;br /&gt;std::variant는&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;특징을&amp;nbsp;갖습니다. &lt;br /&gt;-&amp;nbsp;여러&amp;nbsp;타입&amp;nbsp;중&amp;nbsp;하나를&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;유연한&amp;nbsp;클래스 &lt;br /&gt;-&amp;nbsp;저장된&amp;nbsp;값은&amp;nbsp;선택한&amp;nbsp;타입의&amp;nbsp;크기와&amp;nbsp;정렬&amp;nbsp;요구&amp;nbsp;사항을&amp;nbsp;따름 &lt;br /&gt;-&amp;nbsp;선언할&amp;nbsp;때&amp;nbsp;모든&amp;nbsp;가능한&amp;nbsp;타입을&amp;nbsp;정의해야&amp;nbsp;하며,&amp;nbsp;선언&amp;nbsp;후에는&amp;nbsp;해당&amp;nbsp;타입들&amp;nbsp;중&amp;nbsp;하나의&amp;nbsp;값만&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;-&amp;nbsp;switch문과&amp;nbsp;함께&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;visit&amp;nbsp;함수를&amp;nbsp;제공하여,&amp;nbsp;저장된&amp;nbsp;값의&amp;nbsp;타입에&amp;nbsp;따라&amp;nbsp;다른&amp;nbsp;작업을&amp;nbsp;수행할&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;-&amp;nbsp;참조,&amp;nbsp;배열&amp;nbsp;또는&amp;nbsp;void&amp;nbsp;타입은&amp;nbsp;보유할&amp;nbsp;수&amp;nbsp;없음 &lt;br /&gt;-&amp;nbsp;동일한&amp;nbsp;타입을&amp;nbsp;한&amp;nbsp;번&amp;nbsp;이상&amp;nbsp;보유하고,&amp;nbsp;동일한&amp;nbsp;타입의&amp;nbsp;다르게&amp;nbsp;cv-qualified&amp;nbsp;된&amp;nbsp;버전을&amp;nbsp;보유할&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&lt;br /&gt;std::variant는&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;선언할&amp;nbsp;수&amp;nbsp;있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1680668349875&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;std::variant&amp;lt;int, double, std::string&amp;gt; v;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;위&amp;nbsp;코드는&amp;nbsp;int,&amp;nbsp;double,&amp;nbsp;std::string&amp;nbsp;중&amp;nbsp;하나를&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;std::variant를&amp;nbsp;선언하는&amp;nbsp;것입니다. &lt;br /&gt;선언&amp;nbsp;후에는&amp;nbsp;v에&amp;nbsp;int,&amp;nbsp;double,&amp;nbsp;std::string&amp;nbsp;중&amp;nbsp;하나의&amp;nbsp;값을&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있습니다. &lt;br /&gt;&lt;br /&gt;std::variant의&amp;nbsp;값을&amp;nbsp;가져오기&amp;nbsp;위해서는&amp;nbsp;std::get&amp;nbsp;함수를&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있습니다. &lt;/p&gt;
&lt;pre id=&quot;code_1680668373604&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;std::variant&amp;lt;int, double, std::string&amp;gt; v;
v = 42;
int i = std::get&amp;lt;int&amp;gt;(v); // v에 저장된 int 값을 가져옴&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 v에 int 값 42를 저장하고, std::get&amp;lt;int&amp;gt;(v)를 사용하여 v에 저장된 int 값을 가져오는 것입니다. &lt;br /&gt;&lt;br /&gt;std::variant를&amp;nbsp;switch문과&amp;nbsp;함께&amp;nbsp;사용하려면,&amp;nbsp;visit&amp;nbsp;함수를&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있습니다. &lt;br /&gt;visit&amp;nbsp;함수는&amp;nbsp;각&amp;nbsp;타입에&amp;nbsp;대해&amp;nbsp;작업을&amp;nbsp;수행하는&amp;nbsp;함수&amp;nbsp;객체를&amp;nbsp;인수로&amp;nbsp;받습니다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1680668384771&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;std::variant&amp;lt;int, double, std::string&amp;gt; v;
v = 3.14;

std::visit([](auto&amp;amp;&amp;amp; arg) {
    using T = std::decay_t&amp;lt;decltype(arg)&amp;gt;;
    if constexpr (std::is_same_v&amp;lt;T, int&amp;gt;) {
        std::cout &amp;lt;&amp;lt; &quot;v contains an int: &quot; &amp;lt;&amp;lt; arg &amp;lt;&amp;lt; '\n';
    } else if constexpr (std::is_same_v&amp;lt;T, double&amp;gt;) {
        std::cout &amp;lt;&amp;lt; &quot;v contains a double: &quot; &amp;lt;&amp;lt; arg &amp;lt;&amp;lt; '\n';
    } else if constexpr (std::is_same_v&amp;lt;T, std::string&amp;gt;) {
        std::cout &amp;lt;&amp;lt; &quot;v contains a string: &quot; &amp;lt;&amp;lt; arg &amp;lt;&amp;lt; '\n';
    }
}, v);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;위&amp;nbsp;코드는&amp;nbsp;v에&amp;nbsp;double&amp;nbsp;값&amp;nbsp;3.14를&amp;nbsp;저장하고,&amp;nbsp;visit&amp;nbsp;함수를&amp;nbsp;사용하여&amp;nbsp;v에&amp;nbsp;저장된&amp;nbsp;값의&amp;nbsp;타입에&amp;nbsp;따라&amp;nbsp;다른&amp;nbsp;작업을&amp;nbsp;수행하는&amp;nbsp;것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 서로 다른 타입의 메시지를 큐에 입력받는 샘플 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1680668440024&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;queue&amp;gt;
#include &amp;lt;variant&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;iostream&amp;gt;

struct MessageA {
    int type;
    double data;
};

struct MessageB {
    int type;
    char data[20];
};

struct MessageC {
    int type;
    std::string data;
};

using Message = std::variant&amp;lt;MessageA, MessageB, MessageC&amp;gt;;

int main() {
    std::queue&amp;lt;Message&amp;gt; messageQueue;
    
    messageQueue.push(MessageA{1, 3.14});
    messageQueue.push(MessageB{2, &quot;hello world&quot;});
    messageQueue.push(MessageC{3, &quot;foo bar&quot;});
    
    while (!messageQueue.empty()) {
        const auto&amp;amp; message = messageQueue.front();
        
        std::visit([](const auto&amp;amp; msg) {
            using MsgType = std::decay_t&amp;lt;decltype(msg)&amp;gt;;
            if constexpr (std::is_same_v&amp;lt;MsgType, MessageA&amp;gt;) {
                std::cout &amp;lt;&amp;lt; &quot;MessageA received with data: &quot; &amp;lt;&amp;lt; msg.data &amp;lt;&amp;lt; std::endl;
            } else if constexpr (std::is_same_v&amp;lt;MsgType, MessageB&amp;gt;) {
                std::cout &amp;lt;&amp;lt; &quot;MessageB received with data: &quot; &amp;lt;&amp;lt; msg.data &amp;lt;&amp;lt; std::endl;
            } else if constexpr (std::is_same_v&amp;lt;MsgType, MessageC&amp;gt;) {
                std::cout &amp;lt;&amp;lt; &quot;MessageC received with data: &quot; &amp;lt;&amp;lt; msg.data &amp;lt;&amp;lt; std::endl;
            }
        }, message);
        
        messageQueue.pop();
    }
    
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>C++</category>
      <category>C++17</category>
      <category>std::variant</category>
      <category>std::variant C++</category>
      <category>std::variant examples</category>
      <category>std::variant sample</category>
      <category>std::variant 샘플코드</category>
      <category>std::variant 예제 코드</category>
      <category>VARIANT</category>
      <author>developer-tj</author>
      <guid isPermaLink="true">https://developer-tj.tistory.com/56</guid>
      <comments>https://developer-tj.tistory.com/56#entry56comment</comments>
      <pubDate>Thu, 6 Apr 2023 12:00:49 +0900</pubDate>
    </item>
    <item>
      <title>냄새 13. 반복문(Loops)</title>
      <link>https://developer-tj.tistory.com/55</link>
      <description>&lt;p&gt;반복문(Loops)을 사용하는 것이 코드 작성의 효율성을 높일 수 있지만, 반복문이 중첩되거나 복잡한 조건문과 함께 사용되는 경우 코드의 복잡성이 증가하고 코드를 이해하기 어려워질 수 있습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;반복문의 문제점 중 하나는 다른 로직과 함께 사용되는 경우 유지보수성이 낮아질 수 있다는 것입니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;예를 들어, 아래의 코드에서 반복문은 사이즈를 계산하고, 각 색상의 평균값을 계산하는 두 가지 다른 로직과 함께 사용됩니다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
int size = 0;
double redSum = 0.0;
double greenSum = 0.0;
double blueSum = 0.0;
for (int i = 0; i &lt; pixels.size(); ++i) {
    size++;
    redSum += pixels[i].red();
    greenSum += pixels[i].green();
    blueSum += pixels[i].blue();
}
double redAverage = redSum / size;
double greenAverage = greenSum / size;
double blueAverage = blueSum / size;
&lt;/code&gt;
&lt;/pre&gt;
&lt;br/&gt;

&lt;p&gt;위 코드를 아래와 같이 수정한다면 반복문을 포함하지 않고도 코드의 가독성과 유지보수성을 높일 수 있습니다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
int size = pixels.size();
double redSum = std::accumulate(pixels.begin(), pixels.end(), 0.0,
    [](double sum, const Pixel&amp; p) { return sum + p.red(); });
double greenSum = std::accumulate(pixels.begin(), pixels.end(), 0.0,
    [](double sum, const Pixel&amp; p) { return sum + p.green(); });
double blueSum = std::accumulate(pixels.begin(), pixels.end(), 0.0,
    [](double sum, const Pixel&amp; p) { return sum + p.blue(); });
double redAverage = redSum / size;
double greenAverage = greenSum / size;
double blueAverage = blueSum / size;
&lt;/code&gt;
&lt;/pre&gt;
&lt;br/&gt;

&lt;p&gt;위 코드에서는 std::accumulate()를 사용하여 반복문 없이 요소의 합을 계산할 수 있습니다.&lt;br&gt;이렇게 하면 코드의 가독성이 높아지고, 필요한 로직을 분리할 수 있으며, 재사용성도 높아집니다.&lt;br&gt;이와 같은 방식으로 반복문을 대체하여 코드를 개선할 수 있습니다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;적용 가능한 리팩터링 기법&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;반복문을 파이프라인으로 바꾸기(Replace Loop with Pipeline)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>리팩터링/냄새 (리팩터링할 시점)</category>
      <category>Code Smell</category>
      <category>loops</category>
      <category>Refactoring</category>
      <category>리팩터링</category>
      <category>리팩토링</category>
      <category>반복문</category>
      <category>코드 냄새</category>
      <author>developer-tj</author>
      <guid isPermaLink="true">https://developer-tj.tistory.com/55</guid>
      <comments>https://developer-tj.tistory.com/55#entry55comment</comments>
      <pubDate>Wed, 5 Apr 2023 12:00:14 +0900</pubDate>
    </item>
    <item>
      <title>냄새 12. 반복되는 switch문(Repeated Switches)</title>
      <link>https://developer-tj.tistory.com/54</link>
      <description>&lt;p&gt;반복되는 switch문(Repeated Switches)은 여러 개의 switch 문이 동일한 조건식을 검사하는 경우를 말합니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;예를 들어, 다음과 같은 코드를 생각해보겠습니다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
void processAnimalSound(Animal* animal) {
    switch (animal-&gt;getType()) {
        case AnimalType::CAT:
            // process cat sound
            break;
        case AnimalType::DOG:
            // process dog sound
            break;
        case AnimalType::COW:
            // process cow sound
            break;
        default:
            // process default sound
            break;
    }
}

void processAnimalMovement(Animal* animal) {
    switch (animal-&gt;getType()) {
        case AnimalType::CAT:
            // process cat movement
            break;
        case AnimalType::DOG:
            // process dog movement
            break;
        case AnimalType::COW:
            // process cow movement
            break;
        default:
            // process default movement
            break;
    }
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;br/&gt;

&lt;p&gt;위 코드에서 processAnimalSound()와 processAnimalMovement() 함수에서 각각 switch문이 존재하며, 동일한 조건식을 사용하고 있습니다.&lt;br&gt;이 경우 조건식이 변경되거나 다른 동물이 추가될 때 마다 모든 switch문을 변경해주어야 하는 번거로움이 있습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;이러한 문제를 해결하기 위해 각각의 동물을 클래스로 정의하고, 해당 클래스에서 메서드를 정의하여 동물의 소리와 움직임을 처리하도록 수정할 수 있습니다.&lt;br&gt;이렇게 되면 switch문을 제거하고, 동물 클래스의 새로운 클래스를 추가하면 됩니다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
class Animal {
public:
    virtual void makeSound() = 0;
    virtual void move() = 0;
};

class Cat : public Animal {
public:
    void makeSound() override {
        // process cat sound
    }
    void move() override {
        // process cat movement
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        // process dog sound
    }
    void move() override {
        // process dog movement
    }
};

class Cow : public Animal {
public:
    void makeSound() override {
        // process cow sound
    }
    void move() override {
        // process cow movement
    }
};

void processAnimal(Animal* animal) {
    animal-&gt;makeSound();
    animal-&gt;move();
}
&lt;/code&gt;
&lt;/pre&gt;

&lt;br/&gt;

&lt;p&gt;이렇게 하면, 새로운 동물이 추가될 때마다 새로운 동물 클래스를 만들어 주면 되기 때문에 코드의 유지보수성이 높아집니다. 또한, 코드 중복도 줄일 수 있으며, 가독성도 좋아집니다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;적용 가능한 리팩터링 기법&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer-tj.tistory.com/53&quot; target=&quot;_blank&quot;&gt;조건부 로직을 다형성으로 바꾸기(Replace Conditional with Polymorphism)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>리팩터링/냄새 (리팩터링할 시점)</category>
      <category>Code Smell</category>
      <category>Refactoring</category>
      <category>Repeated Switches</category>
      <category>리팩터링</category>
      <category>리팩토링</category>
      <category>반복되는 switch문</category>
      <category>코드 냄새</category>
      <author>developer-tj</author>
      <guid isPermaLink="true">https://developer-tj.tistory.com/54</guid>
      <comments>https://developer-tj.tistory.com/54#entry54comment</comments>
      <pubDate>Tue, 4 Apr 2023 12:00:58 +0900</pubDate>
    </item>
    <item>
      <title>리팩터링 기법. 조건부 로직을 다형성으로 바꾸기(Replace Conditional with Polymorphism)</title>
      <link>https://developer-tj.tistory.com/53</link>
      <description>&lt;p&gt;조건부 로직을 다형성으로 바꾸기(Replace Conditional with Polymorphism)란 객체의 타입에 따라 분기되는 조건부 로직을 상속 구조를 이용하여 다형성을 적용하여 코드를 간결하고 유연하게 만드는 리팩터링 방법입니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;조건부 로직은 보통 if-else문, switch-case문 등으로 구현되며, 객체의 타입에 따라 다른 로직을 수행하도록 설계되어 있습니다.&lt;br&gt;이러한 코드는 코드의 유지보수성이 나쁘며, 새로운 객체 타입이 추가될 때마다 코드의 수정이 필요합니다.&lt;br&gt;따라서 이러한 조건부 로직을 다형성을 이용하여 분리하고, 객체의 타입에 따라 해당하는 메서드를 호출하는 방식으로 코드를 변경하는 것이 좋습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;이 방법을 사용하면, 객체의 타입에 따라 다른 동작을 수행해야 할 때 새로운 객체 타입을 추가하기가 쉬워집니다.&lt;br&gt;또한, 각 객체 타입마다 특정 동작을 수행하는 메서드가 존재하므로, 코드의 가독성이 높아지고 유지보수성도 향상됩니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;조건부 로직을 다형성으로 바꾸는 방법은 다음과 같습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;조건문에 해당하는 부분을 클래스의 메소드로 추출합니다.&lt;/li&gt;
&lt;li&gt;추출한 메소드를 추상 메소드로 정의하고, 상속받을 클래스에서 구현합니다.&lt;/li&gt;
&lt;li&gt;추상 클래스를 정의하고, 추상 메소드를 포함합니다.&lt;/li&gt;
&lt;li&gt;추상 클래스를 상속받아 각 상황에 맞는 클래스를 구현합니다.&lt;br/&gt;

&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;간단한 예시로, 도형 클래스를 다루는 코드를 예로 들어보겠습니다.&lt;br&gt;이전 코드에서는 각 도형의 타입에 따라 분기를 수행하였습니다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
class Shape {
public:
    enum Type {
        Circle,
        Rectangle,
        Triangle
    };

    Type getType() const { return type_; }

    double getArea() const {
        switch (type_) {
            case Circle:
                return PI * radius_ * radius_;
            case Rectangle:
                return width_ * height_;
            case Triangle:
                return 0.5 * base_ * height_;
        }
    }

private:
    Type type_;
    double radius_;
    double width_;
    double height_;
    double base_;
};
&lt;/code&gt;
&lt;/pre&gt;

&lt;br/&gt;

&lt;p&gt;이를 조건부 로직에서 다형성을 이용하여 변경하면, 각 도형 클래스를 만들고 각 클래스마다 getArea() 메서드를 구현하게 됩니다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
class Shape {
public:
    virtual double getArea() const = 0;
};

class Circle : public Shape {
public:
    Circle(double radius) : radius_(radius) {}
    double getArea() const override { return PI * radius_ * radius_; }
private:
    double radius_;
};

class Rectangle : public Shape {
public:
    Rectangle(double width, double height) : width_(width), height_(height) {}
    double getArea() const override { return width_ * height_; }
private:
    double width_;
    double height_;
};

class Triangle : public Shape {
public:
    Triangle(double base, double height) : base_(base), height_(height) {}
    double getArea() const override { return 0.5 * base_ * height; }
private:
    double base;
    double height_;
};

&lt;/code&gt;
&lt;/pre&gt;
&lt;br/&gt;


&lt;p&gt;위 코드는 다형성을 이용하여 조건부 로직을 처리하도록 바꾼 예시 코드입니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;기존 코드에서는 다양한 도형에 대한 정보를 하나의 클래스 내에 저장하고 있었습니다.&lt;br&gt;하지만 이를 다형성을 이용하여 각 도형마다 별도의 클래스로 분리하고, 공통적으로 필요한 부분은 부모 클래스인 Shape 클래스에 정의하여 사용하는 것입니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;위 코드에서 Circle, Rectangle, Triangle 클래스는 각 도형에 대한 클래스입니다.&lt;br&gt;이들은 모두 Shape 클래스를 상속받아 getArea() 함수를 오버라이딩하고 있습니다.&lt;br&gt;이렇게 하면 다른 클래스에서는 Shape 포인터를 이용하여 각 도형의 넓이를 구할 수 있습니다.&lt;br&gt;이는 조건문 없이 다형성을 이용하여 간결하고 유연한 코드를 작성할 수 있도록 도와줍니다.&lt;/p&gt;</description>
      <category>리팩터링/리팩터링 기법</category>
      <category>Refactoring</category>
      <category>Replace Conditional with Polymorphism</category>
      <category>리팩터링</category>
      <category>리팩터링 기법</category>
      <category>리팩토링</category>
      <category>리팩토링 기법</category>
      <category>조건부 로직을 다형성으로 바꾸기</category>
      <author>developer-tj</author>
      <guid isPermaLink="true">https://developer-tj.tistory.com/53</guid>
      <comments>https://developer-tj.tistory.com/53#entry53comment</comments>
      <pubDate>Mon, 3 Apr 2023 12:00:23 +0900</pubDate>
    </item>
    <item>
      <title>리팩터링 기법. 타입 코드를 서브클래스로 바꾸기(Replace Type Code with Subclasses)</title>
      <link>https://developer-tj.tistory.com/52</link>
      <description>&lt;p&gt;타입 코드(Type Code)란, 하나의 클래스 안에서 여러 종류의 객체를 표현하기 위해 사용하는 코드를 말합니다.&lt;br&gt;이는 예를 들어, 도형 클래스 안에서 도형의 종류를 표시하기 위한 숫자나 문자열과 같은 것을 말할 수 있습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;타입 코드를 서브클래스로 바꾸기(Replace Type Code with Subclasses)는 이러한 타입 코드를 사용하는 것을 서브클래스로 분리하는 방법입니다.&lt;br&gt;타입 코드에 따라 객체의 특성이 달라지는 것을 서브클래스로 만들어 표현함으로써, 객체지향적인 설계를 더욱 강화할 수 있습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;서브클래스로 분리하는 방법은, 기존 클래스의 타입 코드에 해당하는 각 서브클래스를 만든 다음, 기존 클래스에서 해당 타입 코드를 제거하고 대신 적절한 서브클래스의 인스턴스를 생성하여 반환하도록 수정하는 것입니다.&lt;br&gt;이렇게 하면 기존 클래스의 복잡도를 낮추고, 타입 코드에 따라 달라지는 동작을 서브클래스 내부에서 캡슐화함으로써 코드 유지보수성을 높일 수 있습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;예를 들어, 도형 클래스에서 타입 코드로 &amp;quot;사각형&amp;quot;, &amp;quot;원&amp;quot;, &amp;quot;삼각형&amp;quot; 등을 사용하고 있다면, 이를 각각의 서브클래스로 만들어 분리할 수 있습니다.&lt;br&gt;이렇게 하면 각 도형의 특성이 달라지는 경우에도 새로운 서브클래스를 추가하거나 수정하는 것만으로도 쉽게 처리할 수 있습니다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;다음은 도형 클래스에서 타입 코드로  &amp;quot;사각형&amp;quot;, &amp;quot;원&amp;quot;, &amp;quot;삼각형&amp;quot;을 사용하는 예제 코드가 있습니다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
enum class ShapeType {
  kRectangle,
  kCircle,
  kTriangle
};

class Shape {
public:
  Shape(ShapeType type, double width, double height, double radius, double base, double altitude)
    : type_(type), width_(width), height_(height), radius_(radius), base_(base), altitude_(altitude) {}

  double area() const {
    switch (type_) {
      case ShapeType::kRectangle:
        return width_ * height_;
      case ShapeType::kCircle:
        return PI * radius_ * radius_;
      case ShapeType::kTriangle:
        return 0.5 * base_ * altitude_;
      default:
        return 0.0;
    }
  }

  double perimeter() const {
    switch (type_) {
      case ShapeType::kRectangle:
        return 2 * (width_ + height_);
      case ShapeType::kCircle:
        return 2 * PI * radius_;
      case ShapeType::kTriangle:
        return base_ + 2 * sqrt(base_ * base_ + 0.25 * altitude_ * altitude_);
      default:
        return 0.0;
    }
  }

private:
  ShapeType type_;
  double width_;
  double height_;
  double radius_;
  double base_;
  double altitude_;
};
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;타입 코드를 서브클래스로 바꾸기를 적용합니다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
class Shape {
public:
  virtual double area() const = 0;
  virtual double perimeter() const = 0;
};

class Rectangle : public Shape {
public:
  Rectangle(double width, double height) : width_(width), height_(height) {}

  double area() const override { return width_ * height_; }
  double perimeter() const override { return 2 * (width_ + height_); }

private:
  double width_;
  double height_;
};

class Circle : public Shape {
public:
  Circle(double radius) : radius_(radius) {}

  double area() const override { return PI * radius_ * radius_; }
  double perimeter() const override { return 2 * PI * radius_; }

private:
  double radius_;
};

class Triangle : public Shape {
public:
  Triangle(double base, double altitude) : base_(base), altitude_(altitude) {}

  double area() const override { return 0.5 * base_ * altitude_; }
  double perimeter() const override { return base_ + 2 * sqrt(base_ * base_ + 0.25 * altitude_ * altitude_); }

private:
  double base_;
  double altitude_;
};
&lt;/code&gt;
&lt;/pre&gt;

&lt;br/&gt;

&lt;p&gt;위의 코드에서 Shape 클래스를 추상 클래스로 만들고 area()와 perimeter() 함수를 순수 가상 함수로 선언합니다.&lt;br&gt;그리고 Rectangle, Circle, Triangle 클래스를 Shape 클래스를 상속받아 만듭니다.&lt;br&gt;이렇게 하면 Shape 클래스를 사용하는 곳에서는 객체의 실제 타입을 알 필요 없이 다형성을 이용해 area()와 perimeter() 함수를 호출할 수 있습니다.&lt;br&gt;이렇게 하면 새로운 도형을 추가하더라도 Shape 클래스를 수정하지 않고 새로운 서브 클래스를 만들어서 추가할 수 있습니다.&lt;/p&gt;</description>
      <category>리팩터링/리팩터링 기법</category>
      <category>Refactoring</category>
      <category>Replace Type Code with Subclasses</category>
      <category>리팩터링</category>
      <category>리팩터링 기법</category>
      <category>리팩토링</category>
      <category>리팩토링 기법</category>
      <category>타입 코드를 서브클래스로 바꾸기</category>
      <author>developer-tj</author>
      <guid isPermaLink="true">https://developer-tj.tistory.com/52</guid>
      <comments>https://developer-tj.tistory.com/52#entry52comment</comments>
      <pubDate>Sun, 2 Apr 2023 12:00:05 +0900</pubDate>
    </item>
    <item>
      <title>리팩터링 기법. 기본형을 객체로 바꾸기(Replace Primitive with Object)</title>
      <link>https://developer-tj.tistory.com/51</link>
      <description>&lt;p&gt;기본형을 객체로 바꾸기(Replace Primitive with Object)는 기본형 변수를 사용하는 대신 새로운 클래스를 정의하고 그 클래스의 인스턴스를 사용하는 방식으로 코드를 개선하는 리팩터링 기법입니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;기본형 변수는 더 큰 데이터 구조와 연결되어 있지 않기 때문에 코드의 가독성과 유지보수성을 저해할 수 있습니다.&lt;br&gt;반면, 객체는 속성과 행동을 갖는 더 복잡한 데이터 구조를 나타낼 수 있습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;예를 들어, 기본형 변수로 통화를 나타내는 경우, 환율이나 기타 통화와 관련된 정보를 캡슐화하고, 통화 간의 변환을 수행할 수 있는 새로운 클래스를 정의할 수 있습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;또 다른 예로, 기본형 변수로 날짜를 나타내는 경우, 시간대, 일괄처리 및 기타 관련 정보를 캡슐화하고, 날짜 간의 비교, 연산 및 계산을 수행할 수 있는 새로운 클래스를 정의할 수 있습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;이 기법은 코드의 가독성, 유지보수성, 확장성을 향상시킬 수 있습니다.&lt;br&gt;하지만, 객체로 바꾸는 것은 기본형 변수를 사용하는 것보다 조금 더 많은 코드를 작성해야 하기 때문에 일부 개발자들은 이 기법을 사용하지 않는 경우도 있습니다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;기본형을 객체로 바꾸는 예시로 학생의 시험 점수를 저장하는 시스템이 있다고 가정해봅시다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
class Student {
public:
    Student(std::string name, int math_score, int science_score, int english_score)
        : name_(name), math_score_(math_score), science_score_(science_score), english_score_(english_score) {}

    std::string GetName() const { return name_; }
    int GetMathScore() const { return math_score_; }
    int GetScienceScore() const { return science_score_; }
    int GetEnglishScore() const { return english_score_; }

private:
    std::string name_;
    int math_score_;
    int science_score_;
    int english_score_;
};
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;Student 클래스는 시험 점수를 int로 저장하고 있습니다.&lt;br&gt;시험 점수를 객체로 바꾸어 보겠습니다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;먼저, 학생의 시험 점수를 저장할 Score 클래스를 정의합니다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
class Score {
public:
    Score(int math, int science, int english) : math_(math), science_(science), english_(english) {
        if (math_ &lt; 0 || math_ &gt; 100) {
            throw std::invalid_argument(&quot;math score should be between 0 and 100.&quot;);
        }
        if (science_ &lt; 0 || science_ &gt; 100) {
            throw std::invalid_argument(&quot;science score should be between 0 and 100.&quot;);
        }
        if (english_ &lt; 0 || english_ &gt; 100) {
            throw std::invalid_argument(&quot;english score should be between 0 and 100.&quot;);
        }
    }

    void setMath(int math) {
        if (math &lt; 0 || math &gt; 100) {
            throw std::invalid_argument(&quot;math score should be between 0 and 100.&quot;);
        }
        math_ = math;
    }

    void setScience(int science) {
        if (science &lt; 0 || science &gt; 100) {
            throw std::invalid_argument(&quot;science score should be between 0 and 100.&quot;);
        }
        science_ = science;
    }

    void setEnglish(int english) {
        if (english &lt; 0 || english &gt; 100) {
            throw std::invalid_argument(&quot;english score should be between 0 and 100.&quot;);
        }
        english_ = english;
    }

    int math() const { return math_; }
    int science() const { return science_; }
    int english() const { return english_; }

    double average() const { return static_cast&lt;double&gt;(math_ + science_ + english_) / 3; }

private:
    int math_;
    int science_;
    int english_;
};

&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;각 학생의 정보를 저장할 Student 클래스를 정의합니다.&lt;br&gt;Student 클래스는 이름과 Score 객체를 멤버 변수로 가지고 있습니다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
class Student {
public:
    Student(const std::string&amp; name, const Score&amp; score) : name_(name), score_(score) {}

    const std::string&amp; name() const { return name_; }
    const Score&amp; score() const { return score_; }

private:
    std::string name_;
    Score score_;
};
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;이제, main 함수에서 학생 정보를 생성하고 출력해보겠습니다.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
int main() {
    Score score1(90, 85, 95);
    Student student1(&quot;Alice&quot;, score1);

    Score score2(80, 75, 85);
    Student student2(&quot;Bob&quot;, score2);

    std::cout &lt;&lt; student1.name() &lt;&lt; &quot;'s average score: &quot; &lt;&lt; student1.score().average() &lt;&lt; std::endl;
    std::cout &lt;&lt; student2.name() &lt;&lt; &quot;'s average score: &quot; &lt;&lt; student2.score().average() &lt;&lt; std::endl;

    return 0;
}
&lt;/code&gt;
&lt;/pre&gt;


&lt;p&gt;기존에는 각 학생의 시험 점수를 int형으로 저장했지만, Score 클래스를 사용하여 각 과목의 점수를 멤버 변수로 저장하고 평균 점수를 계산할 수 있도록 했습니다.&lt;br&gt;이렇게 하면 데이터를 더욱 직관적으로 표현할 수 있으며, Score 클래스에서 추가적인 연산이 필요할 경우 Score 클래스 내부에 멤버 함수를 정의해주기만 하면 됩니다.&lt;/p&gt;</description>
      <category>리팩터링/리팩터링 기법</category>
      <category>Refactoring</category>
      <category>Replace Primitive with Object</category>
      <category>기본형을 객체로 바꾸기</category>
      <category>리팩터링</category>
      <category>리팩터링 기법</category>
      <category>리팩토링</category>
      <category>리팩토링 기법</category>
      <author>developer-tj</author>
      <guid isPermaLink="true">https://developer-tj.tistory.com/51</guid>
      <comments>https://developer-tj.tistory.com/51#entry51comment</comments>
      <pubDate>Sat, 1 Apr 2023 12:00:22 +0900</pubDate>
    </item>
  </channel>
</rss>