<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Bump into</title>
    <link>https://lala9663.tistory.com/</link>
    <description>초보의 험난한 공부</description>
    <language>ko</language>
    <pubDate>Sun, 28 Jun 2026 09:55:30 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>lala9663</managingEditor>
    <image>
      <title>Bump into</title>
      <url>https://tistory1.daumcdn.net/tistory/5452606/attach/45b62bdaa2cd48f4b7096daf9df1c108</url>
      <link>https://lala9663.tistory.com</link>
    </image>
    <item>
      <title>LLM 과 임베딩</title>
      <link>https://lala9663.tistory.com/169</link>
      <description>&lt;p&gt;회사에서 LLM과 관련하여 임베딩에 대한 주제가 나와 대화하는데 정확하게 알지 못해서 어려웠던 경험이 있다.&lt;br&gt;그래서 임베딩에 대해 조금 알아보려고 한다.&lt;/p&gt;
&lt;p&gt;임베딩(Embedding)은 자연어 처리(NLP) 및 머신러닝 분야에서 중요한 개념으로, 텍스트 데이터를 수치 벡터로 변환하는 기술이다.&lt;br&gt;우선 간단하게 임베딩의 개념, 종류부터 찾아보았다.&lt;/p&gt;
&lt;h2&gt;1. 임베딩이란?&lt;/h2&gt;
&lt;p&gt;임베딩은 텍슽트, 이미지, 음성 등 다양한 컴퓨터가 데이터를 고차원의 공간에서 저차원의 벡터로 변환하는 과정이라고 한다.&lt;br&gt;이를 통해 컴퓨터가 데이터를 보다 효율적으로 처리하고, 유사성을 계산하거나 예측 모델에 입력할 수 있게 된다.&lt;br&gt;임베딩의 주요 목적은 의미적으로 유사한 데이터를 벡터 공간에서도 가깝게 배치하는 것이다.&lt;br&gt;예를 들어, &amp;quot;고양이&amp;quot;와 &amp;quot;개&amp;quot;라는 단어는 의미적으로 유사하므로 임베딩 공간에서도 이 두 단어가 가깝게 배치된다.&lt;/p&gt;
&lt;h2&gt;2. 임베딩의 종류&lt;/h2&gt;
&lt;h3&gt;2.1 Word2Vec&lt;/h3&gt;
&lt;p&gt;Word2Vec은 구글에서 개발한 단어 임베딩 기법으로, 단어를 저차원 벡터로 표현하는 방법이다.&lt;br&gt;Word2Vec은 크게 두가지 접근 방식으로 나뉜다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CBOW(Continuous Bag of Words):  주변 단어들을 기반으로 중심 단어를 예측하는 방식&lt;/li&gt;
&lt;li&gt;Skip-gram: 중심 단어를 기반으로 주변 단어들을 예측하는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.2 GloVe(Global Vectors for Word Representation)&lt;/h3&gt;
&lt;p&gt;GloVe는 Word2Vec과 유사하지만, 전역적인 통계 정보를 사용하여 단어 벡터를 학습한다.&lt;br&gt;Glove는 특정 단어가 문서 전체에서 얼마나 자주 등장하는지와 그 단어가 다른 단어들과 얼마나 자주 함께 등장하는지를 고려한다.&lt;/p&gt;
&lt;h3&gt;2.3 FastText&lt;/h3&gt;
&lt;p&gt;FastText는 페이스북 AI 연구팀에서 개발한 임베딩 기법으로, 단어를 n-그램으로 분해하여 각 n-그램의 임베딩을 합산하여 단어 임베딩&lt;br&gt;을 생성한다. 이를 통해 철자 기반의 유사성을 고려할 수 있어 새로운 단어에 대한 임베딩을 생성할 수 있는 장점이 있다.&lt;/p&gt;
&lt;h3&gt;2.4 BERT(Bidirectional Encoder Representations from Transformers)&lt;/h3&gt;
&lt;p&gt;BERT는 트랜스포머 모델을 기반으로 한 양방향 임베딩 기법이다. BERT는 단어의 좌우 문맥을 동시에 고려하여 임베딩을 생성한다. 이는 문장의 전체적인 의미를 이해하는데 매우 효과적이다. BERT는 사전 학습된 모델을 통해 다양한 자연어 처리 작업에 쉽게 적용할 수 있다.&lt;/p&gt;
&lt;h3&gt;3. 임베딩 대표적인 사용&lt;/h3&gt;
&lt;h3&gt;3.1 자연어 처리&lt;/h3&gt;
&lt;p&gt;임베딩은 자연어 처리(NLP)에서 단어의 의미를 벡터로 표현하는 데 사용한다. 예를 들어, 텍스트 분류, 감성 분석, 기계 번역 등 다양한 NLP 작업에서 임베딩이 중요한 역할을 한다.&lt;/p&gt;
&lt;h3&gt;3.2 추천 시스템&lt;/h3&gt;
&lt;p&gt;사용자의 행동 데이터를 임베딩으로 변환하여 유사한 사용자 또는 아이템을 추천하는 데 사용된다. 예를 들면, 사용자의 검색 기록을 바탕으로 관심 있는 상품을 추천하거나, 음악 스트리밍 서비스에서 유사한 음악을 추천 하는 경우가 있다.&lt;/p&gt;
&lt;h3&gt;3.3 컴퓨터 비전&lt;/h3&gt;
&lt;p&gt;이미지 임베딩을 통해 이미지의 시작걱 특성을 벡터로 표현하여 이미지 검색, 객체 인식, 이미지 캡션 생성 등 다양한 컴퓨터 비전 작업에 활용된다.&lt;/p&gt;
&lt;h2&gt;4. 임베딩과 LLM&lt;/h2&gt;
&lt;p&gt;LLM은 자연어 이해와 생성 작업에서 뛰어난 성능을 발휘하며, 임베딩 기법을 통하여 언어의 의미적 구조를 효과적으로 학습할 수 있다.&lt;br&gt;LLM과 할루시네이션 등등 은 나중에 다른 글에서 자세하게 정리해보겠다.&lt;/p&gt;
&lt;h3&gt;4.1 임베딩과 LLM의 관계&lt;/h3&gt;
&lt;p&gt;LLM은 방대한 양의 텍스트 데이터를 학습하여 언어의 패넡과 구조를 이해하는 모델이다.&lt;br&gt;임베딩은 이러한 학습 과정에서 중요한 역할을 한다. 임베딩은 텍스트의 각 단어를 고차원의 실수 벡터로 변환하여, 단어 간의 유사성을 벡터 공간에서 표현할 수 있게 한다. 이를 통해 LLM은 문장의 의미를 보다 정확하게 파악하고, 유사한 의미를 가진 단어를 유사한 벡터로 매핑할 수 있다.&lt;/p&gt;
&lt;p&gt;임베딩은 LLM의 입력 및 내부 표현 방식에서 중요한 부분을 차지한다. 예를 들어, LLM은 입력된 문장을 입베딩 벡터로 변환하여 모델의 입력으로 사용하고, 모델의 내부에서 다양한 계층을 거치며 임베딩  벡터를 조정하고 변환하여 최종적인 예측을 수행한다.&lt;/p&gt;
&lt;h3&gt;4.2 LLM에서 임베딩의 역할&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;초기 임베딩&lt;br&gt;LLM은 학습 과정에서 문장을 토큰화(tokenization)하고, 각 토큰을 임베딩 벡터로 변환한다. 이 초기 임베딩은 모델이 학습 데이터를 처리하고, 패턴을 학습하며, 추론을 수행할 수 있는 기초가 됩니다. 일반적으로 이 임베딩은 랜덤하게 초기화된 후, 학습 과정을 통해 최적화된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;문맥 임베딩(Contextual Embedding)&lt;br&gt;초기의 정적 임베딩(static embedding)과 달리, LLM은 문맥에 따라 단어의 의미가 달라지는 것을 반영하는 문맥 임베딩(contextual embedding)을 사용한다. 예를 들어, &amp;quot;bank&amp;quot;라는 단어는 문맥에 따라 &amp;quot;강둑&amp;quot;을 의미할 수도 있고, &amp;quot;은행&amp;quot;을 의미할 수도 있다. BERT와 같은 모델은 양방향 트랜스포머 구조를 사용하여, 단어의 양쪽 문맥을 고려해 각 단어의 임베딩을 생성한다. 이를 통해 문맥에 따라 단어의 의미가 다르게 표현될 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;임베딩을 통한 전이 학습(Transfer Learning)&lt;br&gt;LLM은 일반적으로 대규모 데이터셋으로 사전 학습(pre-training)을 거친 후, 특정 작업에 맞게 미세 조정(fine-tuning)된다. 이 과정에서 임베딩 층은 중요한 역할을 한다. 사전 학습된 임베딩은 모델이 새로운 작업에서도 높은 성능을 발휘할 수 있게 해준다. 예를 들어, LLM이 문서 분류 작업에 미세 조정될 때, 사전 학습된 임베딩은 이미 많은 언어적 지식을 포함하고 있어, 적은 양의 추가 데이터로도 효과적인 학습이 가능하다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;RPA와의 결합&lt;/h2&gt;
&lt;p&gt;현재 내가 주 업무를 담당하고 있는 RPA 운영, 개발에서의 조합 및 방향성에 대해 생각해보았다.&lt;br&gt;현재 RPA는 간단한 업무, 메일 처리 같은 부분만 RPA로 만들어 사용중에 있다.&lt;/p&gt;
&lt;p&gt;LLM과 임베딩을 결합하면 단순한 규칙 기반 자동화를 넘어서 훨씬 더 지능적이고 복잡한 자동화 작업을 수행할 수 있을 거라 생각된다.&lt;br&gt;이 결합은 RPA가 처리할 수 있는 작업의 범위를 매우 크게 확장 시키고, 보다 정교하게 사용 가능할 것이라 예상된다.&lt;/p&gt;</description>
      <category>공부방</category>
      <author>lala9663</author>
      <guid isPermaLink="true">https://lala9663.tistory.com/169</guid>
      <comments>https://lala9663.tistory.com/169#entry169comment</comments>
      <pubDate>Mon, 26 Aug 2024 22:47:47 +0900</pubDate>
    </item>
    <item>
      <title>RPA가 뭐지?</title>
      <link>https://lala9663.tistory.com/168</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;한참 면접 준비를 하다 RPA라는 기술을 보게 되었다.&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;h2 data-ke-size=&quot;size26&quot;&gt;RPA&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Robotic Process Automation의 약자로 로봇 프로세스 자동화란 뜻으로 현대 기업 및 조직에서 업무 프로세스의 자동화를 위해 사용되는 혁신적인 기술이다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDKY2c%2FbtqECiWtQu6%2FOJSiJy6uAmJRK4Rv8FZqQ0%2Fimg.jpg&quot; alt=&quot;RPA&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기술은 소프트웨어 로봇 또는 자동화된 에이전트를 사용하여 일상적이고 반복적인 작업을 자동화하고, 인간의 업무 부담을 줄이며 업무 효율성을 극대화하는 것을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;따라서 RPA를 사용하여 다양한 처리를 할 수 있다. RPA 시나리오를 적용하여 이메일에 대한 자동 응답 생성부터 ERP에서의 데이터 작업을 자동화할 수도 있다.&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;h3 data-ke-size=&quot;size23&quot;&gt;RPA의 주요 특징&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;자동화: 반복적이고 규칙 기반의 업무 프로세스를 자동화하여 인력 낭비를 줄인다.&lt;/li&gt;
&lt;li&gt;유연성: 다양한 업무 환경과 시스템에 대해 대응할 수 있으며, 복잡한 프로세스도 자동화할 수 있다.&lt;/li&gt;
&lt;li&gt;실시간 처리: 실시간으로 데이터를 처리하고 업무를 수행할 수 있어 업무 효율성을 크게 향상 키신다.&lt;/li&gt;
&lt;li&gt;오류 감소: 인간의 실수를 최소화하고 일관된 품질을 유지할 수 있어 비용과 시간을 절감한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&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;/li&gt;
&lt;li&gt;인사 및 인력 관리: 인사 데이터 업데이트, 채용 과정, 급여 처리 등 인사 관리 작업을 자동화하여 인력 부담을 줄인다.&lt;/li&gt;
&lt;li&gt;고객 서비스: 고객 문의 처리, 주문 처리, 환불 처리 등 고객 서비스 업무를 효율적으로 처리한다.&lt;/li&gt;
&lt;li&gt;제조 및 공급망 관리: 생산 계획, 재고 관리, 납품 프로세스 등 제조 및 공급망 관리 작업을 자동화하여 생산성을 향상한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;그러면 전망은??&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.gttkorea.com/news/photo/202308/6298_6913_353.jpg&quot; alt=&quot;RPA 시장 전망&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것은 테크나비오(Technavio)가 발표한 &amp;lsquo;로봇 프로세스 자동화(RPA) 시장 전망과 분석, 2023~2027년&amp;rsquo; 보고서에 따른 것이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;대표적인 RPA&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;UiPath: RPA 업계에서 가장 널리 사용되는 솔루션 중 하나이다. 사용자 친화적인 디자인과 강력한 자동화 기능을 제공하여 다양한 산업과 업무 분야에서 널리 활용된다.&lt;/li&gt;
&lt;li&gt;Automation Anywhere: Automation Anywhere는 업계에서 가장 다양한 기능과 유연성을 제공하는 RPA 플랫폼 중 하나이다. 클라우드 기반 및 온프레미스 솔루션을 을 제공하여 기업의 다양한 요구사항을 충족시킨다.&lt;/li&gt;
&lt;li&gt;Blue Prism: 기업용 소프트웨어 자동화 및 프로세스 자동화를 위한 RPA 툴로 알려져 있다. 가장 보수적이고 안정적인 솔루션 중 하나로 평가되며, 규모 있는 기업에서 많이 사용된다.&lt;/li&gt;
&lt;li&gt;Microsoft Power Automate: Microsoft Power Automate는 Microsoft의 RPA 및 자동화 플랫폼으로, Microsoft의 기존 제품 및 서비스와의 통합이 강점이다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;RPA의 도전 과제&lt;/h3&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;인력의 역량 및 전문성 요구: RPA 시스템을 개발하고 운영하기 위해서는 IT 전문가나 프로세스 엔지니어 등의 전문적인 역량과 지식이 필요하다. 이를 확보하는 것이 일부 기업에 있어서 도전적일 수 있다.&lt;/li&gt;
&lt;li&gt;인프라 및 시스템 호환성: 기존의 시스템과의 호환성 문제나 인프라 구축 및 유지보수 비용이 도전 과제가 될 수 있다.&lt;/li&gt;
&lt;/ol&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>
      <author>lala9663</author>
      <guid isPermaLink="true">https://lala9663.tistory.com/168</guid>
      <comments>https://lala9663.tistory.com/168#entry168comment</comments>
      <pubDate>Thu, 22 Feb 2024 19:39:01 +0900</pubDate>
    </item>
    <item>
      <title>DDOS(디도스) 이건 어떤 공격이지?</title>
      <link>https://lala9663.tistory.com/167</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;내가 즐겨 보는 인터넷 방송이 최근 게임과 인터넷 방송에서 디도스 공격이 엄청나게 발생하고 있다,,ㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;말로만 들었던 디도스인데 이게 왜 유명한 게임에 갑자기 공격되는 거지?라는 생각이 들었다.&lt;/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;h2 data-ke-size=&quot;size26&quot;&gt;DDOS(Distributed Denial of Service)란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;악의적인 공격자가&lt;/b&gt; 대량의 트래픽이나 요청을 목표 시스템으로 보내 해당 시스템을 마비시키는 공격형태이다.&lt;br /&gt;DDOS 공격은 인터넷 서비스의 가용성을 침해하거나, 웹사이트나 네트워크 서비스를 중단시키는데 사용된다.&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;img src=&quot;https://file.mk.co.kr/meet/neds/2015/10/image_readtop_2015_952508_14440328862156668.jpg&quot; alt=&quot;대기줄&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 레스토랑에는 한 명의 웨이터가 있다. 손님들이 주문을 하고 음식을 받기 위해 웨이터에게 요청을 한다. 웨이터는 일일이 요청을 받고 음식을 가져오며 서비스를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, 디도스 공격은 수백 명의 인원이 동시에 그 레스토랑에 들어와서 주문을 너무 많이 한다고 상상해 보자. 웨이터는 수백 명의 주문을 처리하기에는 너무 바빠져서 다른 손님들의 요청을 받지 못하고, 주문을 처리하는 데 오랜 시간이 걸리게 된다. 이에 따라 레스토랑은 서비스를 제공할 수 없게 되고, 다른 손님들도 음식을 주문할 수 없게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디도스 공격은 레스토랑에 너무 많은 주문을 보내어 웨이터가 서비스를 제공할 수 없게 만드는 것과 유사하다. 공격자는 대량의 요청을 보내어 웹사이트나 서버의 자원을 고갈시키고, 정상적인 서비스를 제공하지 못하도록 만든다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&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;/li&gt;
&lt;/ol&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;ol style=&quot;list-style-type: decimal;&quot; start=&quot;2&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;서비스 거부(DoS) 발생&lt;/li&gt;
&lt;/ol&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;이로 인해 서비스 거부(Denial of Service, DoS)가 발생하고, 사용자들은 해당 서비스에 접속할 수 없게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; start=&quot;3&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;분산 공격(Distributed)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DDOS 공격은 분산된 다수의 컴퓨터나 장치를 사용하여 공격을 실행한다.&lt;/li&gt;
&lt;li&gt;이를 통해 공격 트래픽의 출처를 추적하기 어렵게 만들며, 방어가 어렵게 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DDOS 공격 유형&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;HTTP Flooding&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특징: HTTP 요청을 대량으로 보내는 공격 방식&lt;/li&gt;
&lt;li&gt;작동 방식: 공격자는 대량의 HTTP 요청을 보내어 웹 서버의 자원을 고갈시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; start=&quot;2&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;SYN Flood&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특징: TCP 연결을 설정하는데 필요한 SYN 패킷을 대량으로 보내는 공격방식&lt;/li&gt;
&lt;li&gt;작동 방식: 공격자는 대량의 SYN 요청을 보내고, 서버는 SYN/ACK 응답을 보내는데, 이를 대량으로 처리하면서 자원을 고갈시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; start=&quot;3&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;UDP Flood&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특징: UDP 패킷을 대량으로 보내는 공격 방식&lt;/li&gt;
&lt;li&gt;작동 방식: 공격자는 대량의 UDP 패킷을 목표 서버로 보내어 대역폭을 고갈시키고, 서버의 자원을 소모한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DDOS 공격의 대처 방법&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;기술적 대응: 인트라넷 방화벽, IPS(침입 방지 시스템)등을 사용하여 공격을 탐지하고 차단한다.&lt;/li&gt;
&lt;li&gt;트래픽 관리: 트래픽 모니터링 및 관리를 통해 이상 트래픽을 탐지하고 차단한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;그럼 예방책은?&lt;/h3&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;트래픽 분산: CDN(Content Delivery Network) 등을 활용하여 트래픽을 분산시켜 공격을 완화한다.&lt;/li&gt;
&lt;li&gt;캐싱 서버 사용: 캐싱 서버를 사용하여 웹 페이지의 로드를 최적화하고, 공격 대비한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;일반인들은...?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 일반인이 DDOS 공격에 직접 대처하기는 매우 어렵다고 한다.&lt;br /&gt;대부분의 DDOS 공격은 기술적으로 복잡하고 대량의 트래픽을 처리해야 하기 때문에 일반 사용자가 직접 대처하기는 거의 불가능하다고 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;범인 찾기&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bu87h6/btsELp0ZU16/FENQRUpzh8fQkDBXulIluk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bu87h6/btsELp0ZU16/FENQRUpzh8fQkDBXulIluk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bu87h6/btsELp0ZU16/FENQRUpzh8fQkDBXulIluk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbu87h6%2FbtsELp0ZU16%2FFENQRUpzh8fQkDBXulIluk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;370&quot; height=&quot;208&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&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;DDOS 공격을 실행하는 공격자를 식별하고 찾는 것 또한 매우 어렵다고 한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;IP주소 위장: 대부분의 DDOS 공격은 IP 주소를 위장하여 실행한다.(IP를 안 돌리고 하면 진짜 바보) 따라서 실제 공격자의 식별이 어려워진다.&lt;/li&gt;
&lt;li&gt;분산 공격: 디도스 공격은 여러 대의 컴퓨터나 장치를 사용하여 실행되기 때문에, 공격 트래픽의 출처를 추적하기 어렵다. 공격자는 봇넷이나 좀비 컴퓨터를 사용하여 공격을 분산시키고, 이를 통해 공격 트래픽의 출처를 숨긴다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조금 더 자세히 찾아보고 싶은 분들은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.akamai.com/ko/glossary/what-is-ddos&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.akamai.com/ko/glossary/what-is-ddos&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1707822252867&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;DDoS 공격이란 무엇일까요? | Akamai&quot; data-og-description=&quot;DDoS(Distributed Denial of Service) 공격이란 무엇이며 DDoS 공격이 인터넷 전반에서 다양한 웹사이트 운영에 어떤 피해를 주는지 확인하세요.&quot; data-og-host=&quot;www.akamai.com&quot; data-og-source-url=&quot;https://www.akamai.com/ko/glossary/what-is-ddos&quot; data-og-url=&quot;https://www.akamai.com/ko/glossary/what-is-ddos&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/QYDZG/hyVi82pEMB/SaH9ramREG7oNSAKkntkY0/img.png?width=1024&amp;amp;height=768&amp;amp;face=0_0_1024_768&quot;&gt;&lt;a href=&quot;https://www.akamai.com/ko/glossary/what-is-ddos&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.akamai.com/ko/glossary/what-is-ddos&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/QYDZG/hyVi82pEMB/SaH9ramREG7oNSAKkntkY0/img.png?width=1024&amp;amp;height=768&amp;amp;face=0_0_1024_768');&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;DDoS 공격이란 무엇일까요? | Akamai&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;DDoS(Distributed Denial of Service) 공격이란 무엇이며 DDoS 공격이 인터넷 전반에서 다양한 웹사이트 운영에 어떤 피해를 주는지 확인하세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.akamai.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;</description>
      <category>그 외</category>
      <author>lala9663</author>
      <guid isPermaLink="true">https://lala9663.tistory.com/167</guid>
      <comments>https://lala9663.tistory.com/167#entry167comment</comments>
      <pubDate>Tue, 13 Feb 2024 20:05:00 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] java.lang.IllegalArgumentException: Name for argument of type [java.lang.Long] not specified, and parameter name information not available via reflection.</title>
      <link>https://lala9663.tistory.com/166</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;jakarta.servlet.ServletException:&amp;nbsp;Request&amp;nbsp;processing&amp;nbsp;failed:&amp;nbsp;java.lang.IllegalArgumentException:&amp;nbsp;Name&amp;nbsp;for&amp;nbsp;argument&amp;nbsp;of&amp;nbsp;type&amp;nbsp;[java.lang.Long]&amp;nbsp;not&amp;nbsp;specified,&amp;nbsp;and&amp;nbsp;parameter&amp;nbsp;name&amp;nbsp;information&amp;nbsp;not&amp;nbsp;available&amp;nbsp;via&amp;nbsp;reflection.&amp;nbsp;Ensure&amp;nbsp;that&amp;nbsp;the&amp;nbsp;compiler&amp;nbsp;uses&amp;nbsp;the&amp;nbsp;'-parameters'&amp;nbsp;flag. &lt;br /&gt;&lt;br /&gt;테스트 코드를 돌리고 있는데 갑자기 이런 오류가 나왔다.. 갑자기 처음 보는 오류가 나와서 당황,,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해석을 해보니 파라미터를 못찾는 문제 같은데 왜 갑자기 이런 오류가 나왔는지 궁금하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;김영한 님께서 이와 유사한 질문에 대한 글에 답을 이미 해 주신 상태였다. 역시 갓&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결방법이 총 3가지가 있다고 한다.&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;span style=&quot;color: #006dd7;&quot;&gt;1. 애노테이션 생략 X&lt;/span&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;스프링 부트 3.2부터 자바 컴파일러에 -parameters 옵션을 넣어주어야 애노테이션의 이름을 생략할 수 있다고 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1707218605479&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@RequestMapping(&quot;/request&quot;)
public String request(@RequestParam(&quot;username&quot;) String username) {
   ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 요청 파라미터의 이름과 메서드의 매개변수 이름이 일치하지 않을 때 명시적으로 파라미터의 이름을 지정해줘야 하고 매개변수 이름과 요청 파라미터의 이름이 동일하면 생략할 수 있는데&amp;nbsp; 어찌 된 거지,,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;2. 컴파일 시점에 -parameters 옵션 적용&lt;/b&gt;&lt;/span&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;span style=&quot;color: #24292e;&quot;&gt;IntelliJ IDEA에서 File -&amp;gt; Settings를 연다. (Mac은 IntelliJ IDEA -&amp;gt; Settings)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #24292e;&quot;&gt;Build, Execution, Deployment &amp;rarr; Compiler &amp;rarr; Java Compiler로 이동한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #24292e;&quot;&gt;Additional command line parameters라는 항목에 다음을 추가한다.&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #24292e;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #24292e;&quot;&gt;-parameters&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #24292e;&quot;&gt; &lt;span style=&quot;color: #24292e;&quot;&gt;out 폴더를 삭제하고 다시 실행한다. 꼭 out 폴더를 삭제해야 다시 컴파일이 일어난다.&lt;/span&gt; &lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 나는 Java Compiler에 &lt;b&gt;&lt;span style=&quot;color: #24292e;&quot;&gt;&amp;nbsp;Additional command line parameters 이 항목이 보이지 않아서 이 방법은 패스,,&lt;/span&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;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;3.&amp;nbsp;빌드를 Grdle 방식으로&lt;/span&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;span style=&quot;color: #24292e;&quot;&gt;빌드를 할 때 gradle방식과 IntelliJ IDEA 방식이 있는데 나는 Intelli IDEA 방식을 사용하고 있다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #24292e;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #24292e;&quot;&gt;Gradle로 선택하면 컴파일 시점에서 해당 옵션을 자동으로 적용해 준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경하는 방법은 &lt;span style=&quot;color: #8a3db6;&quot;&gt;Settings -&amp;gt; Build, Execution, Deployment -&amp;gt; Build Tools -&amp;gt; Gradle&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드의 변경을 굳이 하고 싶지 않아서 3번 방식으로 문제를 해결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
참고자료:
&lt;a href=&quot;https://www.inflearn.com/questions/1088283/pathvariable-%EB%B3%80%EC%88%98%EB%AA%85-%EA%B0%99%EC%9D%84%EB%95%8C-%EC%83%9D%EB%9E%B5%EC%8B%9C-%EC%98%A4%EB%A5%98-%EB%B9%8C%EB%93%9C-%EC%84%A4%EC%A0%95%EC%9D%84-gradle%EB%A1%9C-%ED%95%98%EB%A9%B4-%ED%95%B4%EA%B2%B0%EB%90%98%EB%8A%94-%EA%B2%83-%EA%B0%99%EC%8A%B5%EB%8B%88%EB%8B%A4 &quot;&gt;인프런 질문&lt;/a&gt;
</description>
      <category>Spring</category>
      <author>lala9663</author>
      <guid isPermaLink="true">https://lala9663.tistory.com/166</guid>
      <comments>https://lala9663.tistory.com/166#entry166comment</comments>
      <pubDate>Tue, 6 Feb 2024 20:41:35 +0900</pubDate>
    </item>
    <item>
      <title>이벤트: 캡처링과 버블링의 원리와 활용</title>
      <link>https://lala9663.tistory.com/165</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 공부를 하면서 백엔드 지식뿐만 아니라 프론트의 지식도 알고 있어야 프로젝트를 하는데 도움도 되고 취업에도 유리하겠다란 생각이 들어 공부를 시작하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트를 배우면서 면접에서 가장 많이 질문받는 것 중 하나가 캡처링과 버블링의 차이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 설명하자면 캡처링과 버블링은 이벤트가 DOM에서 전파되는 방식을 설명하는 용어이다.&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;버블링(Bubbling)&lt;/b&gt;: 이벤트가 발생한 요소에서 시작하여 최상위 요소까지 전파되는 과정이다. 이벤트가 발생한 요소에서 시작해서 부모요소, 그 부모의 부모요소까지 전달되어 올라가는 방식이다.&lt;br /&gt;(제일 깊은 곳에 있는 요소에서 시작해 부모 요소를 거슬러 올라가며 발생하는 모양이 마치 물속 거품(bubble)과 닮았기 때문에 명명 지어졌다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;캡처링(Cpaturing)&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-filename=&quot;Pasted image 20231219200115.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;397&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byn5W3/btsCfZEfSC5/nKBJAIsPfatW8K3uVvVlK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byn5W3/btsCfZEfSC5/nKBJAIsPfatW8K3uVvVlK0/img.png&quot; data-alt=&quot;캡처링과 버블링&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byn5W3/btsCfZEfSC5/nKBJAIsPfatW8K3uVvVlK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbyn5W3%2FbtsCfZEfSC5%2FnKBJAIsPfatW8K3uVvVlK0%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;586&quot; height=&quot;397&quot; data-filename=&quot;Pasted image 20231219200115.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;397&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;h2 data-ke-size=&quot;size26&quot;&gt;이벤트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞에서 간단하게 설명하고 왔지만 여기서 계속 이벤트라는 단어가 있다. 여기서 이벤트는 뭘까?&lt;br /&gt;&lt;b&gt;**이벤트**&lt;/b&gt;란 사용자나 브라우저에서 발생하는 특정한 동작을 가리킨다. 예를 들어, 클릭, 마우스를 움직임, 키보드 입력 등이 모두 이벤트에 해당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이제 HTML 이벤트의 흐름을 살펴보자.&lt;br /&gt;HTML 이벤트의 흐름은 일반적으로 캡처링과 버블링 두 가지 단계로 나뉜다.&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;타겟 단계: 이벤트가 실제로 발생한 요소에 도달한 단계이다. 이벤트가 발생한 요소에서 해당 이벤트가 처리된다. 위의 사진을 예시로 들면 button에 해당한다.&lt;/li&gt;
&lt;li&gt;버블링 단계: 이벤트가 발생한 요소에서 시작하여 최상위 요소까지 거슬러 올라가는 단계이다. 이벤트 타겟요소에서 시작해서 최상위 요소까지 이벤트가 전파되며, 이 단계에서도 이벤트 핸들러가 동작할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;버블링&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저의 이벤트는 기본적으로 **버블링 방식**으로 이벤트가 전파된다.&lt;br /&gt;자바스크립트 `addEventListener()` 함수로 요소의 이벤트를 등록하면 기본적으로 버블링 전파 방식으로 이벤트가 흐르게 되어, 만일 자식 요소에 이벤트가 발생하면 부모 요소도 버블링 통해 이벤트가 전파되어 리스너가 호출되게 된다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;&amp;lt;body&amp;gt;
    &amp;lt;div class=&quot;one&quot;&amp;gt;
        &amp;lt;div class=&quot;two&quot;&amp;gt;
            &amp;lt;div class=&quot;three&quot;&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
    div.addEventListener('click', logEvent);
});

function logEvent(event) {
    console.log(event.currentTarget.className);
}&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;위 코드는 세 개의 div 태그에 모두 클릭 이벤트를 등록하고 클릭 했을 때 logEvent 함수를 실행시키는 코드이다. 여기서 위 그림대로 최하위 div 태그 `&amp;lt;div class=&quot;three&quot;&amp;gt;&amp;lt;/div&amp;gt;`&amp;nbsp;&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-filename=&quot;Pasted image 20231219200812.png&quot; data-origin-width=&quot;498&quot; data-origin-height=&quot;154&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnF4R5/btsCixmH82N/Vfqsi0PlFcPXAnk269Qvf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnF4R5/btsCixmH82N/Vfqsi0PlFcPXAnk269Qvf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnF4R5/btsCixmH82N/Vfqsi0PlFcPXAnk269Qvf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnF4R5%2FbtsCixmH82N%2FVfqsi0PlFcPXAnk269Qvf0%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;400&quot; height=&quot;124&quot; data-filename=&quot;Pasted image 20231219200812.png&quot; data-origin-width=&quot;498&quot; data-origin-height=&quot;154&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;div 태그 한 개만 클릭했지만 3개의 이벤트가 발생된다.&lt;br /&gt;이렇게 브라우저가 이벤트를 감지하는 이유가 버블링 방식이기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저는 특정 화면 요소에서 이벤트가 발생했을 때 그 이벤트를 최상위에 있는 화면 요소까지 이벤트를 전파시킨다. 따라서 그림과 같이 실행이 되는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 주의해야 할 점은 각 태그마다 이벤트가 등록되어 있기 때문에 상위 요소로 이벤트가 전달되는 것을 확인할 수 있다. 만약 이벤트가 특정 div 태그에만 달려 있다면 위와 같은 동작 결과는 확인할 수 없다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;캡처링&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버블링과는 반대 방향으로 진행되는 이벤트 전파 방식이다. 위의 그림처럼 특정 이벤트가 발생했을 때 최상위 요소에서부터 해당 태그를 찾아 내려간다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;&amp;lt;body&amp;gt;
    &amp;lt;div class=&quot;one&quot;&amp;gt;
        &amp;lt;div class=&quot;two&quot;&amp;gt;
            &amp;lt;div class=&quot;three&quot;&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
    div.addEventListener('click', logEvent, {
        capture: true // default 값은 false입니다.
    });
});

function logEvent(event) {
    console.log(event.currentTarget.className);
}&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;기본적으로 `addEventListner()` 에서는 버블링 방식이기 떄문에 옵션 객체에서 `capture:true`를 설정해줘야 한다. 그러면 해당 이벤트를 감지하기 위해 이벤트 버블링과 반대 방향으로 탐색한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Pasted image 20231219203203.png&quot; data-origin-width=&quot;274&quot; data-origin-height=&quot;164&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dVi40n/btsCf4Fy5Cf/jNFbOK16ARrL52Uswa8sU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dVi40n/btsCf4Fy5Cf/jNFbOK16ARrL52Uswa8sU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dVi40n/btsCf4Fy5Cf/jNFbOK16ARrL52Uswa8sU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdVi40n%2FbtsCf4Fy5Cf%2FjNFbOK16ARrL52Uswa8sU0%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;290&quot; height=&quot;174&quot; data-filename=&quot;Pasted image 20231219203203.png&quot; data-origin-width=&quot;274&quot; data-origin-height=&quot;164&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&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;/h2&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;하지만 브라우저는 기본적으로 캡처링 - 버블링으로 동작되기 때문에 이벤트 동작 자체를 바꿀 순 없다. HTML 구조에서 자식 요소가 부모 요소의 영역 안에 위치한다면, 자식 요소를 클릭했더라도 브라우저는 그것을 부모 요소도 함께 클릭한 것으로 해석된다. 이것은 브라우저의 이벤트 처리 방식으로, HTML 요소의 구조와 일관성이 유지되는 동작이다.&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;h3 data-ke-size=&quot;size23&quot;&gt;event.stopPropagation()&lt;/h3&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;function logEvent(event) {
    event.stopPropagation();
}&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;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;// 이벤트 버블링 예제
divs.forEach(function(div) {
    div.addEventListener('click', logEvent);
});

function logEvent(event) {
    event.stopPropagation();
    console.log(event.currentTarget.className); // three
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// 이벤트 캡쳐 예제
divs.forEach(function(div) {
    div.addEventListener('click', logEvent, {
        capture: true // default 값은 false입니다.
    });
});

function logEvent(event) {
    event.stopPropagation();
    console.log(event.currentTarget.className); // one
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;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://inpa.tistory.com/entry/JS-%F0%9F%93%9A-%EB%B2%84%EB%B8%94%EB%A7%81-%EC%BA%A1%EC%B3%90%EB%A7%81#%EB%B2%84%EB%B8%94%EB%A7%81__%EC%BA%A1%EC%B2%98%EB%A7%81_%EC%9B%90%EB%A6%AC&quot;&gt;인파 블로그 - 캡처링과 버블링&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/#%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%93%B1%EB%A1%9D&quot;&gt;캡틴 판교 - 이벤트 버블링 이벤트 캡처&lt;/a&gt;&lt;/p&gt;</description>
      <category>JavaScript</category>
      <author>lala9663</author>
      <guid isPermaLink="true">https://lala9663.tistory.com/165</guid>
      <comments>https://lala9663.tistory.com/165#entry165comment</comments>
      <pubDate>Tue, 19 Dec 2023 21:18:29 +0900</pubDate>
    </item>
    <item>
      <title>디자인 패턴 - 빌더패턴(Builder)</title>
      <link>https://lala9663.tistory.com/164</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;디자인 패턴이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;디자인 패턴&lt;/b&gt;은 기존 환경 내에서 반복적으로 일어나는 문제들을 어떻게 풀어나갈 것인가에 대한 일종의 해결책이다. 디자인 패턴하면 떠오르는 'Gof의 디자인 패턴'에서는 객체지향적 디자인 패턴의 카테고리를 &quot;생성패턴(Creational Pattern)&quot;, &quot;구조 패턴(Structural Pattern)&quot;, &quot;행동 패턴(Behavioral Patter)&quot; 이렇게 3가지로 구분하고 있다.&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;그중 생성 패턴에 해당하는 Builder 패턴에 대해 알아보자&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;빌더 패턴(Builder)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;빌더&lt;/b&gt;는 복잡한 객체들을 단계별로 생성할 수 있도록 하는 생성 디자인패턴이다. 이 패턴을 사용하면 같은 제작 코드를 사용하여 객체의 다양한 유형들과 표현을 제작할 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;구조&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1742&quot; data-origin-height=&quot;599&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mXniB/btsAULfdJ2T/Fc2hjxOpWB3FrCiS9xMyn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mXniB/btsAULfdJ2T/Fc2hjxOpWB3FrCiS9xMyn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mXniB/btsAULfdJ2T/Fc2hjxOpWB3FrCiS9xMyn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmXniB%2FbtsAULfdJ2T%2FFc2hjxOpWB3FrCiS9xMyn0%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;828&quot; height=&quot;285&quot; data-origin-width=&quot;1742&quot; data-origin-height=&quot;599&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Buolder(추상클래스)를 정의하고 이를 상속받은 ConcreteBuilder(서브클래스)를 구현한다.&lt;/li&gt;
&lt;li&gt;Product의 일부가 build 될 때마다 Director는 Builder에 통보한다.&lt;/li&gt;
&lt;li&gt;Builder는 Director의 요청을 처리해 Product에 부품을 추가한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1509&quot; data-origin-height=&quot;508&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/POGC3/btsAVtMjbSD/loz3tFB16sz5p9zQKDcM6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/POGC3/btsAVtMjbSD/loz3tFB16sz5p9zQKDcM6K/img.png&quot; data-alt=&quot;햄버거의 토핑&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/POGC3/btsAVtMjbSD/loz3tFB16sz5p9zQKDcM6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPOGC3%2FbtsAVtMjbSD%2Floz3tFB16sz5p9zQKDcM6K%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;824&quot; height=&quot;277&quot; data-origin-width=&quot;1509&quot; data-origin-height=&quot;508&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;br /&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;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h5&gt;문제점&lt;/h5&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌더 패턴을 사용하지 않을 때다.&lt;br /&gt;게임에서 캐릭터를 생성할 때 매우 많은 옵션이 있고, 매번 생성할 때마다 이 옵션들을 전부 인자로 넘겨야 한다고 가정해 보자.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;// 게임 캐릭터 클래스
public class GameCharacter {
    private String name;
    private String characterClass;
    private int level;
    private String weapon;
    // 많은 다른 속성들...

    // 생성자 - 매우 많은 인자를 받음
    public GameCharacter(String name, String characterClass, int level, String weapon /* 많은 다른 속성들... */) {
        this.name = name;
        this.characterClass = characterClass;
        this.level = level;
        this.weapon = weapon;
        // 다른 속성들 설정...
    }
}&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;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;// 게임 캐릭터 클래스 - 빌더 패턴 적용
public class GameCharacter {
    private String name;
    private String characterClass;
    private int level;
    private String weapon;
    // 다른 속성들...

    private GameCharacter(String name, String characterClass, int level, String weapon /* 많은 다른 속성들... */) {
        this.name = name;
        this.characterClass = characterClass;
        this.level = level;
        this.weapon = weapon;
        // 다른 속성들 설정...
    }

    public static class CharacterBuilder {
        private String name;
        private String characterClass;
        private int level;
        private String weapon;
        // 다른 속성들...

        public CharacterBuilder(String name, String characterClass) {
            this.name = name;
            this.characterClass = characterClass;
        }

        public CharacterBuilder setLevel(int level) {
            this.level = level;
            return this;
        }

        public CharacterBuilder setWeapon(String weapon) {
            this.weapon = weapon;
            return this;
        }

        // 다른 속성 설정 메서드들...

        public GameCharacter build() {
            return new GameCharacter(name, characterClass, level, weapon /* 많은 다른 속성들... */);
        }
    }
}&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;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public class Game {
    public static void main(String[] args) {
        GameCharacter warrior = new GameCharacter.CharacterBuilder(&quot;Aragorn&quot;, &quot;Warrior&quot;)
                                    .setLevel(30)
                                    .setWeapon(&quot;Sword&quot;)
                                    .build();

        GameCharacter mage = new GameCharacter.CharacterBuilder(&quot;Gandalf&quot;, &quot;Mage&quot;)
                                .setLevel(50)
                                .setWeapon(&quot;Staff&quot;)
                                .build();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;장단점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장점&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;가독성 향상: 객체 생성을 위한 복잡한 로직이나 많은 파라미터를 가진 생성자를 사용하지 않고, 체이닝 방식으로 객체를 구성할 수 있어 가독성이 높아진다.&lt;/li&gt;
&lt;li&gt;유연성: 필요한 속성만 설정하여 객체를 생성할 수 있다. 특정 속성이나 옵션을 설정하지 않아도 기본값을 사용하거나 생략할 수 있다.&lt;/li&gt;
&lt;li&gt;객체 생성 과정의 단순화: 복잡한 객체의 생성 과정을 캡슐화하여 사용자가 직접적으로 그 과정을 알 필요 없이 객체를 생성할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;코드 추가: 빌더 클래스를 작성하는 과정에서 추가적인 코드 작성이 필요하다. 특히, 많은 속성이 있는 객체의 경우에는 빌더 클래스의 작성이 복잡해질 수 있다.&lt;/li&gt;
&lt;li&gt;메모리 사용량 증가: 빌더 패턴은 객체를 생성하기 위한 별도의 빌더 객체를 생성하기 때문에 일부 메모리를 더 사용할 수 있다. 하지만 이는 대부분의 경우 무시할 수 있는 수준이다.&lt;/li&gt;
&lt;/ol&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://4z7l.github.io/2021/01/19/design_pattern_builder.html&quot;&gt;https://4z7l.github.io/2021/01/19/design_pattern_builder.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://refactoring.guru/ko/design-patterns/builder&quot;&gt;refactoring.guru&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;9https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-%EB%B0%98%EB%B3%B5%EC%9E%90Iterator-%ED%8C%A8%ED%84%B4-%EC%99%84%EB%B2%BD-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0?category=967431&quot;&gt;인파블로그 - 디자인 패턴&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>CS</category>
      <author>lala9663</author>
      <guid isPermaLink="true">https://lala9663.tistory.com/164</guid>
      <comments>https://lala9663.tistory.com/164#entry164comment</comments>
      <pubDate>Sun, 26 Nov 2023 23:49:51 +0900</pubDate>
    </item>
    <item>
      <title>디자인패턴 - 프로토타입 패턴(Prototype)</title>
      <link>https://lala9663.tistory.com/163</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;디자인 패턴이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;디자인 패턴&lt;/b&gt;은 기존 환경 내에서 반복적으로 일어나는 문제들을 어떻게 풀어나갈 것인가에 대한 일종의 해결책이다. 디자인 패턴하면 떠오르는 'Gof의 디자인 패턴'에서는 객체지향적 디자인 패턴의 카테고리를 &quot;생성패턴(Creational Pattern)&quot;, &quot;구조 패턴(Structural Pattern)&quot;, &quot;행동 패턴(Behavioral Patter)&quot; 이렇게 3가지로 구분하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그중 생성 패턴에 속하는 프로토타입 패턴에 대해 알아보자.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;프로토타입 패턴(Portotype Pattern)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로토타입 패턴은 객체를 생성하는데 비용이 많이 들고, 비슷한 객체가 이미 있는 경우에 사용되는 생성 패턴 중 하나이다.&lt;br /&gt;즉, 프로토타입 패턴은 원본 객체를 새로운 객체에 복사하여 필요에 따라 수정하는 메커니즘을 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;343&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OlWV2/btsAwsanIWp/XvTFidCpoNBys1cUzWy0z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OlWV2/btsAwsanIWp/XvTFidCpoNBys1cUzWy0z0/img.png&quot; data-alt=&quot;미이 만들어진 프로토타입은 서브클래싱의 대안이 될 수 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OlWV2/btsAwsanIWp/XvTFidCpoNBys1cUzWy0z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOlWV2%2FbtsAwsanIWp%2FXvTFidCpoNBys1cUzWy0z0%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;377&quot; height=&quot;330&quot; data-origin-width=&quot;343&quot; data-origin-height=&quot;300&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;code&gt;clone&lt;/code&gt; 메소드를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;clone&lt;/code&gt; 메서드의 구현은 모든 클래스에서 매우 유사하다. 이 메서드는 현재 클래스의 객체를 만든 후 이전 객체의 모든 필드 값을 새 객체로 전달한다.&lt;br /&gt;대부분의 프로그래밍 언어는 객체들이 같은 클래스에 속한 다른 객체의 비공개 필드들에 접근(access) 할 수 있도록 하므로 비공개 필드들을 복사하는 것도 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복제를 지원하는 객체를 &lt;b&gt;프로토타입&lt;/b&gt;이라고 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;구조&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZIjaP/btsAxdcM8i9/COPUyXMCkmgdMXxvz4Y3I0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZIjaP/btsAxdcM8i9/COPUyXMCkmgdMXxvz4Y3I0/img.png&quot; data-alt=&quot;프로토 타입 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZIjaP/btsAxdcM8i9/COPUyXMCkmgdMXxvz4Y3I0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZIjaP%2FbtsAxdcM8i9%2FCOPUyXMCkmgdMXxvz4Y3I0%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;673&quot; height=&quot;476&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;760&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;b&gt;프로토타입 패턴&lt;/b&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로토타입 패턴은 복사해야 하는 객체들의 구상 클래스들에 코드가 의존하면 안될 때 사용한다.&lt;br /&gt;이와 같은 경우는 코드가 어떤 인터페이스를 통해 타사 코드에서 전달된 객체들과 함께 작동할 때 많이 발생한다. 이러한 객체들의 구상 클래스들은 알려지지 않았기 때문에 이러한 클래스들에 의존할 수 없다.&lt;/li&gt;
&lt;li&gt;프로토타입 패턴은 클라이언트 코드에 복제를 지원하는 모든 객체와 작업할 수 있도록 일반 인터페이스를 제공한다. 이 인터페이스는 클라이언트 코드가 복제하는 객체들의 구상 클래스들에서 클라이언트 코드를 독립시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각자의 객체를 초기화하는 방식만 다른 자식 클래스들의 수를 줄이고 싶을 때 사용한다.&lt;br /&gt;사용하기 전에 많은 설정이 필요한 복잡한 클래스가 있다고 가정해보자.&lt;br /&gt;이 클래스를 설정하는 데는 몇 가지 일반적인 방법들이 있으며 설정되어야 하는 클래스의 새로운 인스턴스들의 생성을 담당하는 코드는 앱에 흩어져 있다.&lt;br /&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;h3 data-ke-size=&quot;size23&quot;&gt;장단점&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;장점&lt;/h4&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;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;단점&lt;/h4&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;code&gt;clone&lt;/code&gt; 메소드를 오버라이딩 해야 한다. 모든 필드와 관련된 복사 과정을 올바르게 구현해야 하므로 구현이 까다로울 수 있다.&lt;/li&gt;
&lt;li&gt;보안 문제: &lt;code&gt;clone&lt;/code&gt; 메소드는 객체의 내용을 복제하기 때문에, 중요한 정보가 포함된 객체의 복제 시 보안상의 문제가 발생할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;예시&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;시나리오: 게임 개발에서 프로토타입 패턴 적용&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RPG게임을 개발 중이다. 이 게임에는 다양한 종류의 몬스터가 등장한다. 이들을 생성하는 과정이 복잡하고 자원을 많이 소모한다. 어떤 몬스터들은 유사하면서도 약간씩 차이가 있을 뿐이다.&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;pre class=&quot;arduino&quot;&gt;&lt;code&gt;import java.util.HashMap;
import java.util.Map;

// 추상 클래스: 몬스터의 기본 형태를 정의합니다.
abstract class Monster {
    protected String name;
    protected int health;
    protected int attack;

    public abstract Monster cloneMonster();

    public String getName() {
        return name;
    }

    public void attack() {
        System.out.println(name + &quot;이(가) 공격을 합니다! 공격력: &quot; + attack);
    }

    public void takeDamage(int damage) {
        health -= damage;
        if (health &amp;lt;= 0) {
            System.out.println(name + &quot;이(가) 쓰러졌습니다!&quot;);
        } else {
            System.out.println(name + &quot;의 체력이 &quot; + health + &quot; 남았습니다.&quot;);
        }
    }
}

// 구체적인 몬스터 클래스: 용병 몬스터
class Mercenary extends Monster {
    public Mercenary() {
        this.name = &quot;용병&quot;;
        this.health = 100;
        this.attack = 20;
    }

    @Override
    public Monster cloneMonster() {
        return new Mercenary();
    }
}

// 구체적인 몬스터 클래스: 오우거 몬스터
class Ogre extends Monster {
    public Ogre() {
        this.name = &quot;오우거&quot;;
        this.health = 150;
        this.attack = 30;
    }

    @Override
    public Monster cloneMonster() {
        return new Ogre();
    }
}

// 몬스터 팩토리: 몬스터를 관리하고 생성하는 클래스
class MonsterFactory {
    private static final Map&amp;lt;String, Monster&amp;gt; prototypes = new HashMap&amp;lt;&amp;gt;();

    static {
        prototypes.put(&quot;용병&quot;, new Mercenary());
        prototypes.put(&quot;오우거&quot;, new Ogre());
    }

    public static Monster createMonster(String type) {
        Monster monster = prototypes.get(type);
        if (monster != null) {
            return monster.cloneMonster();
        }
        return null;
    }
}

// 테스트 코드
public class PrototypePatternExample {
    public static void main(String[] args) {
        Monster mercenary = MonsterFactory.createMonster(&quot;용병&quot;);
        if (mercenary != null) {
            System.out.println(&quot;용병을 소환했습니다.&quot;);
            mercenary.attack();
            mercenary.takeDamage(10);
        }

        Monster ogre = MonsterFactory.createMonster(&quot;오우거&quot;);
        if (ogre != null) {
            System.out.println(&quot;오우거를 소환했습니다.&quot;);
            ogre.attack();
            ogre.takeDamage(50);
        }
    }
}&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;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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://refactoring.guru/ko/design-patterns/prototype/java/example&quot;&gt;프로토타입&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@newtownboy/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85%ED%8C%A8%ED%84%B4Prototype-Pattern&quot;&gt;디자인 패턴 프로토타입&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>CS</category>
      <author>lala9663</author>
      <guid isPermaLink="true">https://lala9663.tistory.com/163</guid>
      <comments>https://lala9663.tistory.com/163#entry163comment</comments>
      <pubDate>Sun, 19 Nov 2023 14:08:00 +0900</pubDate>
    </item>
    <item>
      <title>디자인 패턴 - 전략 패턴(Strategy)</title>
      <link>https://lala9663.tistory.com/162</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;디자인 패턴이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;디자인 패턴&lt;/b&gt;은 기존 환경 내에서 반복적으로 일어나는 문제들을 어떻게 풀어나갈 것인가에 대한 일종의 해결책이다. 디자인 패턴하면 떠오르는 'Gof의 디자인 패턴'에서는 객체지향적 디자인 패턴의 카테고리를 &quot;생성패턴(Creational Pattern)&quot;, &quot;구조 패턴(Structural Pattern)&quot;, &quot;행동 패턴(Behavioral Patter)&quot; 이렇게 3가지로 구분하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그중 행동 패턴에 속하는 전략 패턴에 대해 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;전략 패턴(Strategy)&lt;/h3&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;h4 data-ke-size=&quot;size20&quot;&gt;예시&lt;/h4&gt;
&lt;h5&gt;문제점&lt;/h5&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당신은 RPG 게임을 만들기로 했다. RPG 게임의 특성상 캐릭터의 직업이 있고 캐릭터마다의 특징이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 게임에서 가장 많이 요청되는 기능 중 하나가 전직과 공격이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임의 첫 번째 버전에서는 직업이 전사만 있었다. 하지만 유저들은 다른 직업도 나오길 원했다. 그래서 다음 업데이트 때 마법사라는 직업을 추가했다.&lt;br /&gt;사람들은 만족했지만 유저들은 의견이 적극적으로 반영된 게임을 극찬하며 다른 직업들도 나오길 바랬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 이제 문제가 시작된다. 새 직업을 추가할 때마다 메인 클래스의 크기가 두 배로 늘어났고, 어느 시점부터는 관리하기가 힘들거라 예상되었다.&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;h5&gt;해결책&lt;/h5&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 문제를 해결하기 위해 전략 패턴을 도입했다. 각 직업을 별도의 전략 클래스로 분리하여, 메인 클래스는 각 직업에 해당하는 전략을 참조하도록 설계했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 새로운 직업이 추가될 때마다 메인 클래스의 코드 수정을 최소화할 수 있고, 각 직업의 특징이나 기능을 변경할 때에도 해당 전략 클래스만 수정하면 되게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이로써 유저들의 요구에 계속 빠르게 대응할 수 있게 되었고, 게임 시스템의 확장성과 유지보수성이 크게 향상되었다.&lt;br /&gt;또한, 다른 팀원들과의 협업이 원활해지면서 코드 충돌 문제도 줄일 수 있었다. 새로운 직업이 추가될 때마다 전략을 생성하고 설정하는 작업만 진행하면 되므로 게임의 기능이 빠르게 확장할 수 있게 되었다.&lt;/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;/h3&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;// 전략 인터페이스
interface AttackStrategy {
    void attack();
}

// 검으로 공격하는 전략
class SwordAttack implements AttackStrategy {
    public void attack() {
        System.out.println(&quot;검으로 공격!&quot;);
    }
}

// 마법으로 공격하는 전략
class MagicAttack implements AttackStrategy {
    public void attack() {
        System.out.println(&quot;마법으로 공격!&quot;);
    }
}

// 직업 인터페이스
interface Job {
    void performJob();
}

// 기사 클래스
class Warrior implements Job {
    private AttackStrategy attackStrategy;

    public Warrior(AttackStrategy attackStrategy) {
        this.attackStrategy = attackStrategy;
    }

    public void setAttackStrategy(AttackStrategy attackStrategy) {
        this.attackStrategy = attackStrategy;
    }

    public void performJob() {
        // 기사의 특별한 능력 실행
        if (attackStrategy != null) {
            attackStrategy.attack();
        }
    }
}

// 마법사 클래스
class Wizard implements Job {
    private AttackStrategy attackStrategy;

    public Wizard(AttackStrategy attackStrategy) {
        this.attackStrategy = attackStrategy;
    }

    public void setAttackStrategy(AttackStrategy attackStrategy) {
        this.attackStrategy = attackStrategy;
    }

    public void performJob() {
        // 마법사의 특별한 능력 실행
        if (attackStrategy != null) {
            attackStrategy.attack();
        }
    }
}

// 게임 실행
public class Game {
    public static void main(String[] args) {
        // 기사 생성 및 공격 방법 설정
        Knight knight = new Knight(new SwordAttack());
        // 기사가 검으로 공격
        knight.performJob();

        // 마법사 생성 및 공격 방법 설정
        Wizard wizard = new Wizard(new MagicAttack());
        // 마법사가 마법으로 공격
        wizard.performJob();

        // 기사의 전략 변경 (새로운 전략으로 전환)
        knight.setAttackStrategy(new MagicAttack());
        // 기사가 이제는 마법으로 공격
        knight.performJob();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;장단점&lt;/h3&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;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;/li&gt;
&lt;li&gt;&lt;b&gt;확장성:&lt;/b&gt; 새로운 전략 클래스를 추가하거나 기존 전략을 수정함으로써 시스템에 쉽게 새로운 기능을 도입할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;단점&lt;/h4&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;/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;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;템플릿 메서드 패턴:&lt;/b&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;/li&gt;
&lt;li&gt;&lt;b&gt;전략 패턴:&lt;/b&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;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고:&lt;br /&gt;&lt;a href=&quot;https://refactoring.guru/ko/design-patterns/strategy&quot;&gt;https://refactoring.guru/ko/design-patterns/strategy&lt;/a&gt;&lt;/p&gt;</description>
      <category>CS</category>
      <author>lala9663</author>
      <guid isPermaLink="true">https://lala9663.tistory.com/162</guid>
      <comments>https://lala9663.tistory.com/162#entry162comment</comments>
      <pubDate>Sun, 12 Nov 2023 22:41:27 +0900</pubDate>
    </item>
    <item>
      <title>GoF 디자인 패턴: 소프트웨어 디자인의 핵심</title>
      <link>https://lala9663.tistory.com/161</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;GoF(Gang of Four)는 소프트웨어 디자인 패턴에 대한 가장 잘 알려진 참고 자료 중 하나인&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Design Patterns: Elements of Reusable Object-Oriented Software 책의 저자들을 지칭하는 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;465&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bryRmg/btszH76hnY1/3kjKOKcnpsIzwQ7AKYp8W1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bryRmg/btszH76hnY1/3kjKOKcnpsIzwQ7AKYp8W1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bryRmg/btszH76hnY1/3kjKOKcnpsIzwQ7AKYp8W1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbryRmg%2FbtszH76hnY1%2F3kjKOKcnpsIzwQ7AKYp8W1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;294&quot; height=&quot;600&quot; data-origin-width=&quot;465&quot; data-origin-height=&quot;600&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GoF는 Erich Gamma, Richard Helm, Ralph Johnson, John Vissides&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;GoF가 제안한 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;span&gt;&amp;nbsp; 책은 1994년 처음 출판되었으며, 객체 지향 소프트웨어 개발에서 디자인 패턴의 중요성을 강조하고 이를 23가지 주요 디자인 패턴으로 문서화했다.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 디자인 패턴은 크게 3가지 범주로 나눌 수 있다.&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;b&gt;1. 생성 패턴 - 5&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;&amp;nbsp; 생성 패턴은 객체의 생성과 초기화에 관련된 패턴이다. 이러한 패턴은 객체를 어떻게 생성하고 구성할지에 대한 문제를 해결한다.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;객체 생성에 대한 패턴/ 캡슐화와 유연성&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100.814%; height: 242px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style6&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.2997%; height: 20px;&quot;&gt;&lt;b&gt;추상 팩토리 (Abstract Factory)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 85.8291%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;상위 클래스의 객체 생성코드를 하위클래스가 상속받는다(상위변경=하위자동변경)&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.2997%; height: 20px;&quot;&gt;&lt;b&gt;빌더 (Builder)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 85.8291%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;분리된 인스턴스를 조합하여 객체 생성. 같은 객체를 생성해도 다른 결과를도출할 수 있음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.2997%; height: 20px;&quot;&gt;&lt;b&gt;팩토리 메소드 (Factory Method)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 85.8291%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;객체 생성 코드를 하위클래스에서 구체화. 상위 클래스는 인터페이스만 제공(각각 다른작업수행)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.2997%; height: 20px;&quot;&gt;&lt;b&gt;프로토타입(Prototype)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 85.8291%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;원본을 복제하는 형태로 객체 생성, 비용 저렴&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.2997%; height: 20px;&quot;&gt;&lt;b&gt;싱글턴(Singleton)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 85.8291%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;클래스 내 생성되는 인스턴스가 하나만 필요할 때 사용(동시참조X)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 구조패턴 - 7&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;&amp;nbsp;구조 패턴은 클래스 및 객체의 구조화와 조합에 관련된 패턴이다. 이러한 패턴은 객체 간의 관계를 조직화하고 확장성을 향상시키는데 사용된다.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;구조가 복잡한 시스템 개발에 도움을 줄 수 있는 패턴&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100.93%; height: 128px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style6&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 31.9443%; height: 20px;&quot;&gt;&lt;b&gt;어댑터(Adapter)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.4492%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;일치하지 않는 인터페이스 변환 (전류 어댑터와 같은 역할)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 31.9443%; height: 20px;&quot;&gt;&lt;b&gt;브릿지(Bridge)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.4492%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;추상층(기능)과 구현층(구체화)을 분리하여 서로 독립적 확장 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 31.9443%; height: 20px;&quot;&gt;&lt;b&gt;합성(Composite)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.4492%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;트리구조로 구성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.9443%; height: 17px;&quot;&gt;&lt;b&gt;데코레이터(Decorator)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.4492%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;&amp;nbsp;클래스에 기능을 추가하기 위해 다른 객체를 덧붙이는 형태&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.9443%; height: 17px;&quot;&gt;&lt;b&gt;파사드(Facade)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.4492%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;&amp;nbsp;다수의 서브클래스들의 통합 인터페이스를 제공할 수 있는 Wrapper 객체 구성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.9443%; height: 17px;&quot;&gt;&lt;b&gt;플라이웨이트(Flyweight)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.4492%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;다수의 유사 객체 생성이 필요할 때 메모리 절약을 위해 최대한 공유해서 사용하는 형태&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.9443%; height: 17px;&quot;&gt;&lt;b&gt;프록시(Proxy)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.4492%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;접근이 어려운 객체에 접근할 수 있도록 인터페이스 역할 수행&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 행위패턴 - 11&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;&amp;nbsp;행위 패턴은 객체 간의 상호 작용 및 역할 분배에 관련된 패턴이다. 이러한 패턴은 객체 간의 협력과 상호작용을 개선하고 중복 코드를 줄이는 데 사용된다.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;상호작용이나 책임 분배에 대한 부분을 정의하고 결합도는 최소화 하는 것이 목표인 패턴&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 101.049%; height: 563px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style6&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 31.4254%; height: 20px;&quot;&gt;&lt;b&gt;책임 연쇄(Chain of Responsibility)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.4053%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;요청을 처리할 수 있는 객체가 둘 이상 존재하여 한 객체가 처리하지 못하면 다음 객체로 넘어가는 형태의 패턴. 각 객체들이 고리(Chain)으로 묶여있어 요청이 해결될 때까지 고리를 따라 책임이 넘어간다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 31.4254%; height: 20px;&quot;&gt;&lt;b&gt;커맨드(Command)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.4053%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;명령어를 캡슐화하여 재사용하거나 취소할 수 있도록 필요한 정보를 로그에 남기는 형태&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.4254%; height: 17px;&quot;&gt;&lt;b&gt;인터프리터(Interpreter)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.4053%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;언어에 문법 표현을 정의하는 패턴&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.4254%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;반복자(Iterator)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.4053%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;접근이 잦은 객체는 동일한 인터페이스를 사용하도록 하는 패턴&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.4254%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;중재자(Mediator)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.4053%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;상호작용을 캡슐화하여 결합도를 낮추기위해 사용&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.4254%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;메멘토(Memento)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.4053%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;특정 시점에서의 객체 내부 상태를 객체화함으로써 이후 요청에 따라 객체를 해당 시점의 상태로 돌릴 수 있는 기능을 제공하는 패턴이다. Ctrl+Z 기능이 이 패턴의 대표적 기능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.4254%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;옵저버(Observer)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.4053%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;이벤트 발행과 구독, 상태 변화 전달. 한 객체의 상태가 변화하면 객체에 상속되어있는 다른 객체들에게 변화된 상태를 전달하는 패턴. 카톡의 읽음표시 같은 느낌&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.4254%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;상태(State)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.4053%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;이벤트를 객체 상태에 따라 다르게 처리해야할 때 사용. 카톡 알림설정 같은 느낌&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.4254%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;전략(Strategy)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.4053%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;동일 계열 알고리즘 상호 교환, 독립적 사용&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.4254%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;템플릿 메소드(Template Method)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.4053%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;상위에서 인터페이스를 정의하고 하위에서 구체화시킴 (유지보수 쉬워짐&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.4254%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;방문자(Visitor)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.4053%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #f2f2f2; color: #000000; text-align: start;&quot;&gt;처리 기능을 별도의 클래스로 구성. 분리된 처리 기능은 각 클래스를 방문(Visit)하여 수행한다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;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;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책을 읽으면서 패턴들을 하나씩 정리하면서 블로그에 작성해 채워나가야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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://y-oni.tistory.com/53&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://y-oni.tistory.com/53&lt;/a&gt;&lt;/p&gt;</description>
      <category>CS</category>
      <author>lala9663</author>
      <guid isPermaLink="true">https://lala9663.tistory.com/161</guid>
      <comments>https://lala9663.tistory.com/161#entry161comment</comments>
      <pubDate>Sun, 5 Nov 2023 23:26:28 +0900</pubDate>
    </item>
    <item>
      <title>CSR 과 SSR 그리고 SPA</title>
      <link>https://lala9663.tistory.com/160</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;원티드 인턴쉽에서 멘토님의 강의를 듣던 중 CSR 과 SSR 이란 주제가 나왔었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;SSR은 알고 있는데 CSR 과 SPA는 뭐지? 처음 듣네,,, 생각하고 바로 찾아보았다. ㅋㅋ&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;h3 data-ke-size=&quot;size23&quot;&gt;CSR&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Client Side Rendering&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;랜더링 위치: CSR은 &lt;b&gt;클라이언트 측&lt;/b&gt;에서 랜더링이 이루어진다. 즉, 브라우저에서 페이지의 내용을 생성하고 업데이트한다.&lt;/li&gt;
&lt;li&gt;방식: 웹 애플리케이션의 초기 로딩은 서버에서 HTML파일을 받아오지만, 이후 내용 및 뷰의 업데이트는 클라이언트 측 JavaScropt를 사용하여 비동기적으로 처리된다. 이는 주로 JavaScript 프레임워크(ex: React, Angular, Vue.js)를 활용한다.&lt;/li&gt;
&lt;li&gt;검색 엔진 최적화(SEO): CSR 기반 앱은 검색 엔진 최적화를 위한 추가 작업이 필요할 수 있다. 검색 엔진은 페이지의 초기 HTML 로드만 처리하며, 페이지 업데이트는 JavaScript를 통해 이루어지므로 초기 크롤링 후에는 동적 데이터에 대한 크롤링이 어려울 수 있다.&lt;/li&gt;
&lt;li&gt;페이지 로딩 속도: 초기 로딩이 빠르며, 클라이언트 측에서 필요한 데이터를 비동기적으로 가져와 랜더링하므로 빠른 반응형 인터페이스를 제공한다.&lt;/li&gt;
&lt;li&gt;유저: 페이지 초기 로딩 이후 향상된다. 페이지 내용이 변경될 때 브라우저에서 페이지를 다시 그리기 때문에 부드럽게 느껴진다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SSR&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Server Side Rendering&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;랜더링 위치: SSR은 &lt;b&gt;서버 측&lt;/b&gt;에서 랜더링이 이루어진다. 즉, HTML 페이지를 생성하고 브라우저에 전달한다.&lt;/li&gt;
&lt;li&gt;방식: 웹 애플리케이션의 초기 로딩 및 페이지 내용 랜더링이 서버에서 수행된다. 서버는 페이지의 내용을 미리 생성하고 데이터를 삽입한 후, 클라이언트에 제공한다.&lt;/li&gt;
&lt;li&gt;검색 엔진 최적화(SEO): SSR 기반 앱은 검색 엔진 최적화가 간단하다. 검색 엔진은 페이지의 초기 HTML을 수신하므로 페이지 내용을 이해하고 색인화하기 쉽다.&lt;/li&gt;
&lt;li&gt;페이지 로딩 속도: 초기 로딩 속도는 CSR보다 상대적으로 느리다. 그러나 클라이언트 측에서 추가 데이터 요청이 필요하지 않아 전체 페이지 로딩이 빠르다.&lt;/li&gt;
&lt;li&gt;유저: 초기 페이지 로딩이 느릴 수 있지만 전체 페이지가 서버에서 준비되므로 그 이후에는 좋아진다. 페이지가 완전한 상태로 로드되기 때문에 페이지 전환이 매끄럽게 이루어진다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SPA&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Single Page Application&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;랜더링 위치: SPA는 클라이언트 측에서 모든 랜더링이 이루어진다. 웹 애플리케이션의 초기 로딩 시에 하나의 HTML 페이지를 불러오며, 이후 페이지 내용 및 상태 업데이트는 JavaScript를 통해 동적으로 처리된다.&lt;/li&gt;
&lt;li&gt;방식: SPA는 페이지 간 전환 시에 서버로부터 새로운 HTML을 가져오지 않는다. 대신, 클라이언트 측에서 필요한 데이터를 비동기적으로 가져와 페이지 내용을 업데이트한다.&lt;/li&gt;
&lt;li&gt;검색 엔진 최적화 (SEO): 초기 SPA 구현에서는 검색 엔진 최적화가 어려웠지만, 현재는 몇 가지 기술적 방법으로 SPA를 SEO 친화적으로 만드는 방법이 개발되었다.&lt;/li&gt;
&lt;li&gt;페이지 로딩 속도: 초기 로딩 속도는 빠르다. 이후 페이지 전환 시에 필요한 데이터만 가져와 랜더링때문.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 장단점이 존재해서 뭐가 좋다고 하기엔 어렵지만,&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요새의 트렌드는 SPA라고 한다.&amp;nbsp;&lt;/p&gt;</description>
      <category>CS</category>
      <author>lala9663</author>
      <guid isPermaLink="true">https://lala9663.tistory.com/160</guid>
      <comments>https://lala9663.tistory.com/160#entry160comment</comments>
      <pubDate>Sat, 28 Oct 2023 01:20:40 +0900</pubDate>
    </item>
  </channel>
</rss>