<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>성장하는 프로그래머</title>
    <link>https://hellocoding.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Mon, 15 Jun 2026 15:30:11 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>kail</managingEditor>
    <item>
      <title>FAST IO 원리</title>
      <link>https://hellocoding.tistory.com/8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;우선 fastIO란 무엇인가?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IO 버퍼크기는 2048바이트 정도로 버퍼에서 한번에 나눠서 받기 때문에 이 값 이상의 버퍼 값이 들어온다면 비효율적으로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;들어올 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 우리는 이런 상황에 fastIO를 사용할 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fastIO는 값을 받을 때 한번에 받아서 해당 값을 처리해준다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드는 아래와 같다(picuhila님의 코드를 참고하였다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;unroll-roops는 최적화에 쓰이는 방법인데, 현재에서 다루는 과정은 아니기 때문에 생략한다&lt;/p&gt;
&lt;pre id=&quot;code_1651042343631&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#pragma GCC optimize(&quot;unroll-loops&quot;)
#include&amp;lt;iostream&amp;gt;
#include&amp;lt;string&amp;gt;
#include&amp;lt;vector&amp;gt;

using namespace std;
class FastIn
{
	public:
	const static int BUFFER_MAX = 1048575;
	static char buf[BUFFER_MAX + 1];
	static int pos;
	FastIn()
	{
		clear();
	}
	static void clear()
	{
		pos = BUFFER_MAX;
	}
	static void read_buffer()
	{
		fread(buf, sizeof(char), BUFFER_MAX, stdin);
	}
	static char getchar()
	{
		if (pos == BUFFER_MAX)
		{
			read_buffer();
			pos = 0;
		}
		return buf[pos++];
	}
	static int nextint()
	{
		int res = 0;
		char c;
		do
		{
			c = getchar();
		} while (c &amp;lt; '0' || c&amp;gt;'9');
		res = c - '0';
		while (1)
		{
			c = getchar();
			if (c &amp;lt; '0' || c&amp;gt;'9')break;
			res = (res * 10) + c - '0';
		}
			return res;
		}
	};

char FastIn::buf[FastIn::BUFFER_MAX + 1];
int FastIn::pos;
int v[3000009];
int ch[3000009];
int l, ml, mk, c,x;
int main()
{
	l = FastIn::nextint(); //총 거리
	ml = FastIn::nextint(); //기관총 유효 사거리
	mk = FastIn::nextint(); //기관총 데미지
	c = FastIn::nextint(); // 거리1에 한해 무한대 데미지를 주는 수류탄 개수
	for (int i = 0; i &amp;lt; l; i++)
	{
		v[i] = FastIn::nextint(); //0m부터 총거리까지 좀비체력
	}
	int dam = mk;
	for (int i = 0; i &amp;lt; l; i++)
	{
		if (ch[i]) dam -= mk;
		if (v[i] -dam &amp;gt; 0)
		{
			c--;
			if (c &amp;lt; 0)
			{
				cout &amp;lt;&amp;lt; &quot;NO&quot;;
				return 0;
			}
		}
		else
		{
			if (i + ml &amp;lt; l)
			{	
				ch[i + ml] = 1;
			}
			dam += mk;
		}
	}
	cout &amp;lt;&amp;lt; &quot;YES&quot;;
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 fread의 코드는 아래와 같다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fread로&amp;nbsp;우리는&amp;nbsp;static으로&amp;nbsp;이미&amp;nbsp;값을&amp;nbsp;받고&amp;nbsp;해당&amp;nbsp;값을&amp;nbsp;char&amp;nbsp;배열에&amp;nbsp;넣고&amp;nbsp;시작한다&lt;br /&gt;그&amp;nbsp;다음&amp;nbsp;null이라는&amp;nbsp;중간&amp;nbsp;공백으로&amp;nbsp;구분을&amp;nbsp;한다&lt;br /&gt;fastio를 쓰는 예시는 아래와 같다&lt;br /&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/19644&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/19644&lt;/a&gt;&lt;br /&gt;이제&amp;nbsp;여기서&amp;nbsp;나는&amp;nbsp;io값은&amp;nbsp;최대&amp;nbsp;얼마인가?&lt;br /&gt;처음에는&amp;nbsp;7글자이다(3*10^6은&amp;nbsp;6글자로&amp;nbsp;표현가능&amp;nbsp;+&amp;nbsp;공백&amp;nbsp;한글자)&lt;br /&gt;그&amp;nbsp;다음에는&amp;nbsp;7+(3*10^6)*4이다&amp;nbsp;(기관총&amp;nbsp;범위&amp;nbsp;3*(10^6)만큼&amp;nbsp;입력하고(총&amp;nbsp;6글자+공백&amp;nbsp;한글자),&amp;nbsp;해당&amp;nbsp;입력범위에서&amp;nbsp;각각의&amp;nbsp;거리에&amp;nbsp;대한&amp;nbsp;데미지가&amp;nbsp;최대&amp;nbsp;100까지&amp;nbsp;설정하므로&amp;nbsp;(각각&amp;nbsp;3글자+공백한글자)&lt;br /&gt;그&amp;nbsp;다음에는&amp;nbsp;7글자&amp;nbsp;(3*10^6)&amp;nbsp;만큼&amp;nbsp;입력된다&lt;br /&gt;그러면&amp;nbsp;왜&amp;nbsp;100만에&amp;nbsp;가까운&amp;nbsp;수부터&amp;nbsp;1mb까지가&amp;nbsp;효과적이었는가?&lt;br /&gt;간단하다 입력이 최악인 경우 10^6이 아니라 10^6에 가까운 값만큼 L에 입력되었기 때문이다 그래서 1mb에 못미치는 값이 입력되었기 때문에 입력받을 떄 크기가 1mb보다 약간 작아도 잘 작동했다&lt;br /&gt;이제&amp;nbsp;생기는&amp;nbsp;의문은&amp;nbsp;왜&amp;nbsp;1MB보다&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;&lt;a href=&quot;https://ljhblog.tistory.com/59&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ljhblog.tistory.com/59&lt;/a&gt;&lt;br /&gt;메모리&amp;nbsp;연산은&amp;nbsp;리얼모드에서&amp;nbsp;최대&amp;nbsp;1MB로&amp;nbsp;8086프로세서와&amp;nbsp;교환&amp;nbsp;가능하다&lt;br /&gt;여기서&amp;nbsp;8086&amp;nbsp;프로세서가&amp;nbsp;무엇이냐하면&lt;br /&gt;간단히 말하면 어셈 배울 때 Thumb Instruction이라고 해서 우리가 잘아는 명령어인 EQ(동일), GE(크거나 같다),LE(작거나 같다) 등 이거 관련 명령어를 가지고 있는 친구가(스프링 타임리프쪽에서 아마 본 적이 있을 것 같다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;https://namu.wiki/w/%EC%9D%B8%ED%85%94%208086?from=8086&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8086프로세서(16비트 컴퓨터)이후에도&amp;nbsp; 계속 새로운 프로세서(32비트 컴퓨터,64비트 컴퓨터)가 나왔는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 최대의 메모리를 다룰 수 있는 1MB 처리를 다루는 리얼모드는 동일한 것 같다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서&amp;nbsp;1MB연산이&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;아래 쪽에 관심있으면 플래그 레지스터(flag register)라고 해서 어셈에서 다루는 거라고 하니까 찾아보면 좋을 것같다&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;</description>
      <category>ㄷ</category>
      <author>kail</author>
      <guid isPermaLink="true">https://hellocoding.tistory.com/8</guid>
      <comments>https://hellocoding.tistory.com/8#entry8comment</comments>
      <pubDate>Wed, 27 Apr 2022 16:03:30 +0900</pubDate>
    </item>
    <item>
      <title>타임리프 정리</title>
      <link>https://hellocoding.tistory.com/7</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#the-template-engine&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#the-template-engine&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1648622413101&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Tutorial: Using Thymeleaf&quot; data-og-description=&quot;1 Introducing Thymeleaf 1.1 What is Thymeleaf? Thymeleaf is a modern server-side Java template engine for both web and standalone environments, capable of processing HTML, XML, JavaScript, CSS and even plain text. The main goal of Thymeleaf is to provide a&quot; data-og-host=&quot;www.thymeleaf.org&quot; data-og-source-url=&quot;https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#the-template-engine&quot; data-og-url=&quot;https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#the-template-engine&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cifxI8/hyNQ4mWYgm/O9j1C4qsVeKmlUA3pOLbz0/img.png?width=944&amp;amp;height=411&amp;amp;face=0_0_944_411,https://scrap.kakaocdn.net/dn/cLvGLh/hyNSe9jybI/ikkonsYHFQPPsv9aXvKV40/img.png?width=576&amp;amp;height=530&amp;amp;face=0_0_576_530&quot;&gt;&lt;a href=&quot;https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#the-template-engine&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#the-template-engine&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cifxI8/hyNQ4mWYgm/O9j1C4qsVeKmlUA3pOLbz0/img.png?width=944&amp;amp;height=411&amp;amp;face=0_0_944_411,https://scrap.kakaocdn.net/dn/cLvGLh/hyNSe9jybI/ikkonsYHFQPPsv9aXvKV40/img.png?width=576&amp;amp;height=530&amp;amp;face=0_0_576_530');&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;Tutorial: Using Thymeleaf&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1 Introducing Thymeleaf 1.1 What is Thymeleaf? Thymeleaf is a modern server-side Java template engine for both web and standalone environments, capable of processing HTML, XML, JavaScript, CSS and even plain text. The main goal of Thymeleaf is to provide a&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.thymeleaf.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 타임리프에 관한 설명을 읽으며 모르는 단어는 번역기 돌려 보고 문장도 모르겠으면 통째로 번역해서 다시 번역해보고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 모르겠거나 정리용으로 블로그 글 들을 뒤져보곤 하는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무도 ITemplateResolver가 TemplateResolver로 구현되어있는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 ServletContextTemplateResolver의 객체로만 보이는지에 대한 자세한 설명이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 대해 의문이 들어 자바/스프링 단톡방에도 질문하였으나, 평일 오후라 그런지 다들 답변이 없으셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스택오버플로우에도 딱히 관련된 사항이 없는 것 같아 한번 간단히 정리하였다.(결론적으로 내 예상이 맞았다..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번의 The tymleaf Resolver에 관한 내용을 읽어보면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Template Resolvers are objects that implement an interface from the Thymeleaf API called&lt;span&gt;&amp;nbsp;&lt;/span&gt;org.thymeleaf.templateresolver.ITemplateResolver:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라는 설명이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;번역하자면, Template Resolvers는 Thymleaf API에서 요청한 인터페이스의 ITemplateResolver를 구현한 객체라는 말이다.&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;ServletContextTemplateResolver templateResolver = 
        new ServletContextTemplateResolver(servletContext);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 templateResolver는 ServletContextTemplateResolver class를 참조하는 것 같다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(당연하지만 추상 class나 interface면, new로 인스턴스화 작업이 일어나지 않는다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추상 class에서 default 함수만 쓸 경우 그냥 class를 쓰는 것이 낫기 때문에 쓸 필요가 없다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 여기서, templateResolver는 ITemplateResolver를 구현한 객체인데, 왜 templateResolver는 ServletContextTemplateResolver를 참조한다고 할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 당연히 ServletContextTemplateResolver의 부모 class나 인터페이스가 ITemplateResolver라고 생각할 수 있다.&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;그러면, TemplateResolver라는 네이밍으로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현하면되는 걸, 왜 네이밍할때 ServletContextTemplateResolver로 구현했는가에 대한 의문이 생긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시말해 ITemplateResolver랑 ServletContextTemplateResolver가 네이밍으로 봤을 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서로가 1차적으로 연결된 관계가 아니란 점은 도출해 볼 수 있다는 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2시간동안 찾아보니 상속 관계는 위와 같고(링크: &lt;a href=&quot;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/ServletContextTemplateResolver.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/ServletContextTemplateResolver.html&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html?is-external=true&quot;&gt;Object&lt;/a&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://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/AbstractTemplateResolver.html&quot;&gt;org.thymeleaf.templateresolver.AbstractTemplateResolver&lt;/a&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://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/AbstractConfigurableTemplateResolver.html&quot;&gt;org.thymeleaf.templateresolver.AbstractConfigurableTemplateResolver&lt;/a&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;org.thymeleaf.templateresolver.ServletContextTemplateResolver&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현의 관계는 위와 같다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/ITemplateResolver.html&quot;&gt;ITemplateResolver&lt;/a&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;org.thymeleaf.templateresolver.AbstractTemplateResolver&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 AbstractTemplateResolver가 ItemplateResolver를 구현하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/AbstractConfigurableTemplateResolver.html&quot;&gt;AbstractConfigurableTemplateResolver&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/DefaultTemplateResolver.html&quot;&gt;DefaultTemplateResolver&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/StringTemplateResolver.html&quot;&gt;StringTemplateResolver&lt;/a&gt; 라는 자식 class가 존재한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/AbstractConfigurableTemplateResolver.html&quot;&gt;org.thymeleaf.templateresolver.AbstractConfigurableTemplateResolver&lt;/a&gt;는 &lt;a href=&quot;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/ClassLoaderTemplateResolver.html&quot;&gt;ClassLoaderTemplateResolver&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #353833;&quot;&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/FileTemplateResolver.html&quot;&gt;FileTemplateResolver&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #353833;&quot;&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/ServletContextTemplateResolver.html&quot;&gt;ServletContextTemplateResolver&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #353833;&quot;&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/UrlTemplateResolver.html&quot;&gt;UrlTemplateResolver&lt;/a&gt; 라는 자식 class가 존재한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AbstractTemplateResolver라는 추상 class는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;protected boolean &lt;span style=&quot;background-color: #ffffff; color: #353833;&quot;&gt;computeResolvable &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #353833;&quot;&gt;함수로 resolver가 적용가능한지 체크하고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #eeeeef; color: #353833;&quot;&gt;protected abstract&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templatemode/TemplateMode.html&quot;&gt;TemplateMode&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;enum으로 &lt;span style=&quot;background-color: #fefefe; color: #545454;&quot;&gt; templateResolver.templateMode&lt;/span&gt;&lt;span style=&quot;background-color: #fefefe; color: #545454;&quot;&gt; = TemplateMode.HTML여기서 쓰는 것처럼&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTML,CSS 형식으로 setting 하는 것이 가능하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #eeeeef; color: #353833;&quot;&gt;protected abstract&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/cache/ICacheEntryValidity.html&quot;&gt;ICacheEntryValidity&lt;/a&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;boolean &lt;span style=&quot;background-color: #ffffff; color: #353833;&quot;&gt;&lt;a href=&quot;https://www.thymeleaf.org/apidocs/thymeleaf/3.0.0.BETA03/org/thymeleaf/templateresolver/AbstractTemplateResolver.html#getCheckExistence--&quot;&gt;getCheckExistence&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #353833;&quot;&gt;()&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;템플릿이 리턴하기 전에 존재하는 지 검사할 수 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;String getName()&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;div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AbstractConfigurableTemplateResolver 라는 class에서는&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 prefix랑 suffix를 set으로 설정하는 것을 알 수 있다.&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;templateResolver.setPrefix(&quot;/WEB-INF/templates/&quot;);
templateResolver.setSuffix(&quot;.html&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸로 타임리프를 사용할 떄 접두사 접미어로 (상위폴더,하위이름) 실제 파일의 이름을 쉽게 찾아서 사용한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 이제, controller에서 view resolver로 보내줄 때&lt;/p&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;return &quot;thymleafpractice1&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 보내주는데 이러면, (또는 thymeleafpractice1.html로 보내주기도 하는데, 이렇게 해도 아마 .html이 접미어랑 중복되면 자동으로 접미어만 빼거나 하는식으로 해주지않을까 싶다)&lt;/p&gt;
&lt;div&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;servletContext.getResourceAsStream(&quot;/WEB-INF/templates/thymleafpractice1.html&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&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://countryxide.tistory.com/8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://countryxide.tistory.com/8&lt;/a&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;pre class=&quot;abnf&quot;&gt;&lt;code&gt;templateResolver.setCacheTTLMs(3600000L);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 작성하면 대략 1시간 정도 내가 코드를 바꿔도 임시저장소에서 있던 걸 그대로 보내주는 시간을 정해주는 작업인것같다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;60*60*1000ms(1s)&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(templateResolver);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로 , 템플릿 엔진에서는 이렇게 만든 템플릿리졸버를 값으로 받는데 이 과정은 CGVT 엔진에서 동작한다&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;public class GTVGApplication {
  
    
    ...
    private final TemplateEngine templateEngine;
    ...
    
    
    public GTVGApplication(final ServletContext servletContext) {

        super();

        ServletContextTemplateResolver templateResolver = 
                new ServletContextTemplateResolver(servletContext);
        
        // HTML is the default mode, but we set it anyway for better understanding of code
        templateResolver.setTemplateMode(TemplateMode.HTML);
        // This will convert &quot;home&quot; to &quot;/WEB-INF/templates/home.html&quot;
        templateResolver.setPrefix(&quot;/WEB-INF/templates/&quot;);
        templateResolver.setSuffix(&quot;.html&quot;);
        // Template cache TTL=1h. If not set, entries would be cached until expelled
        templateResolver.setCacheTTLMs(Long.valueOf(3600000L));
        
        // Cache is set to true by default. Set to false if you want templates to
        // be automatically updated when modified.
        templateResolver.setCacheable(true);
        
        this.templateEngine = new TemplateEngine();
        this.templateEngine.setTemplateResolver(templateResolver);
        
        ...

    }

}&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;&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;</description>
      <author>kail</author>
      <guid isPermaLink="true">https://hellocoding.tistory.com/7</guid>
      <comments>https://hellocoding.tistory.com/7#entry7comment</comments>
      <pubDate>Wed, 30 Mar 2022 17:38:12 +0900</pubDate>
    </item>
    <item>
      <title>디자인 패턴 정리(2)</title>
      <link>https://hellocoding.tistory.com/6</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;팩토리 메소드 패턴 vs 프록시 패턴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팩토리 메소드 패턴은 &quot;객체의 생성&quot;을 서브 class에 위임하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프록시 패턴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프록시 패턴은 class끼리 직접 참조하지 않고 간접적으로 서브 class를 통해 참조해서 값을 출력하거나 getter로 받거나 하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프록시 패턴 vs 중재자 패턴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프록시 패턴은 서브 class를 통해서 값을 바꿀 수 없지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중재자 패턴은 서브 class를 통해서 값을 바꿀 수도 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 쉽게 설명해주겠다.&lt;/p&gt;
&lt;pre id=&quot;code_1647915898663&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface DeliveryFood{
    public void setPrice(int price);
    public int getPrice();
}
class Pizza implements DeliveryFood {
    private int price=0;
    public Pizza(int price) {
        this.price=price;
    }
    public int getPrice() {
        return this.price;
    }
    public void setPrice(int price) {
        this.price=price;
    }
}

class Chicken implements DeliveryFood{
    private Chicken chicken() {

    }
    private int price=0;
    private Chicken(int price) {
        this.price=price;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
}
// pizza로도 확장 가능성이 존재하고
// 치킨이랑 pizza가 존재한다면..
// 또한 피자는 따로 배달이 안된다면..

class FlyWeight{
    public Chicken chicken;
    public Chicken getChicken() {
        return chicken;
    }
    public Chicken getChicken(int price) {
        chicken.setPrice(price);
        return chicken;
    }
}

class Proxy{
    private Chicken chicken;
    public int chickenPrice() {
        return chicken.getPrice();
    }
}

class ChickenService{
    private Proxy proxy;
    private final int chickenPrice;
    private int deliveryPrice;
    public ChickenService() {
        this.chickenPrice=proxy.chickenPrice();
    }
    public void chickenPrice(){

        if(chickenPrice&amp;gt;=30000) {
            deliveryPrice=0;
        }
        else {
            deliveryPrice=3000;
        }
    }
}

public class java46 {
    public static void main(String[] args) {
        FlyWeight flyWeight=new FlyWeight();
        Chicken chicken=flyWeight.getChicken();
        Pizza pizza=new Pizza(10000);
        // 관심사 분리를 한번 더 생각해서, Chicken chicken=new Chicken();
        // 이렇게 하고 싱글톤으로 하나의 객체로 관리하는 방식이 스프링에서 쓰는 방법이다
        // 이건 new로 새로 생성하지 않고
        // 하나의 객체를 참조하기 때문에 
        // 플라이웨이트를 이용한 프록시라고 할 수 있다.
    }
}&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;p data-ke-size=&quot;size16&quot;&gt;숨기는 용도로 사용한다고 생각했지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 proxy는 대리자. 대리자의 패턴을 의미한다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 굳이 서브 class로 분리한 이유는 관심사의 분리.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 쉽게 말하면 하나의 class가 감당할 것이 너무 많아져서 분리하거나,&lt;/p&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;저기서, chickenService만 따로 둔 이유는 피자는 배달이 안된다고 생각했을 때를&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가정했기 때문에 Service를 따로 만들지 않았다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서, 프록시 패턴은 실제로 값을 set으로 바꿀 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오직, 기존에 있는 값을 참고할 뿐이다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기 뒤부터는 사실 중요한 내용은 아니다.(바로 프록시 패턴을 참고해도 좋을 것 같다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 왜 싱글톤을 이용한 프록시/ 플라이웨이트를 이용한 프록시로 나누냐면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호출 규약을 어떻게 하느냐에 따라 플라이웨이트로 짜려다가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;싱글톤에 있는 코드를 비슷하게 생각없이 그대로 호출해서 new 로 접근한적이 있어서&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;위의 코드에서 Proxy라는 class가&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;(근데 다음날 수정할 때 생성자를 혹시 몰라서 막아주는 걸 안해놓고 new()로 참조하니까&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아 내가 실수했네 이렇게 생각했는데, (생성자는 확실히 막는데, 플라이웨이트는 거기서 자유롭게&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;짜는 형식이기 때문에 싱글톤처럼 private 생성자를 쓰면 얼마든지 막을 수 있다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차이점은 얘를 이용하면 static으로 사전에 정의를 하지않아도 잘 작동하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 기능을 분리하지만 class가 하나 더 증가한다는 특성이 있겠다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;class가 하나 더 늘면, 코드 자체는 너무 길어져 버린다는 단점을 생각해볼 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장점은 static 키워드는 multi-thread 환경에서 문제가 생기고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;multi-thread 접근을 방지하기 위한 방법으로는 synchronized의 사용이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yeonyeon.tistory.com/113&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://yeonyeon.tistory.com/113&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647917035387&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;[Java] static과 synchronized&quot; data-og-description=&quot;흔히 static 키워드는 multi-thread 환경에서 문제가 생기고, multi-thread 접근을 방지하기 위한 방법으로는 synchronized의 사용이 있다. static만 쓰거나, synchronized만 쓰거나, 둘 다 쓰거나... 이런 경우가..&quot; data-og-host=&quot;yeonyeon.tistory.com&quot; data-og-source-url=&quot;https://yeonyeon.tistory.com/113&quot; data-og-url=&quot;https://yeonyeon.tistory.com/113&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/NCSs0/hyNM2nrtv0/N6c2Cu2T1ThJjvNM4Pg4Dk/img.jpg?width=642&amp;amp;height=400&amp;amp;face=0_0_642_400,https://scrap.kakaocdn.net/dn/bbkOPu/hyNLLni6cB/TnyDNQGy6sscl7Vo3rkBt1/img.jpg?width=642&amp;amp;height=400&amp;amp;face=0_0_642_400,https://scrap.kakaocdn.net/dn/cgMqGQ/hyNLUduqWK/2OZ850AnRVPKKys2Hu9n41/img.jpg?width=642&amp;amp;height=400&amp;amp;face=0_0_642_400&quot;&gt;&lt;a href=&quot;https://yeonyeon.tistory.com/113&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yeonyeon.tistory.com/113&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/NCSs0/hyNM2nrtv0/N6c2Cu2T1ThJjvNM4Pg4Dk/img.jpg?width=642&amp;amp;height=400&amp;amp;face=0_0_642_400,https://scrap.kakaocdn.net/dn/bbkOPu/hyNLLni6cB/TnyDNQGy6sscl7Vo3rkBt1/img.jpg?width=642&amp;amp;height=400&amp;amp;face=0_0_642_400,https://scrap.kakaocdn.net/dn/cgMqGQ/hyNLUduqWK/2OZ850AnRVPKKys2Hu9n41/img.jpg?width=642&amp;amp;height=400&amp;amp;face=0_0_642_400');&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;[Java] static과 synchronized&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;흔히 static 키워드는 multi-thread 환경에서 문제가 생기고, multi-thread 접근을 방지하기 위한 방법으로는 synchronized의 사용이 있다. static만 쓰거나, synchronized만 쓰거나, 둘 다 쓰거나... 이런 경우가..&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yeonyeon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(쉽게 얘기하면 static으로 사전에 정의하는데 그걸 한꺼번에 돌리니 한꺼번에 늘어날 가능성이 존재하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;synchronized로 돌아가는 환경을 고정시켜버리면 성능저하가 일어난다 위의 해결 방법으로는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 싱글톤으로 lazyHolder 방식이 있는 것 같은데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 static이어도 multi-thread에 안전하고 synchronized를 사용하지 않는다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 하나의 class에 너무 많은 기능을 부여하는 것을 관심사의 분리작업으로 분리가 된다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Chicken,Pizza,dakbal,galbi 등 이렇게 여러 곳에서 값을 간접적으로 참조한다면 다른 class에서 그냥&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 class에 메소드를 부여해서 참조할 목적이라면 이 부분은 그냥 구분하는 게 낫다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(사실 이 부분에 대해서는 그냥 각각의 class가 부담하는 게 적으면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관심사 분리가 중요한가 싶었는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 설계 단위에서 부담할 게 많아지면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 때부터 함수로 분리하는 코드를 제작한다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 코드 자체가 너무 많아서 이렇게 분리했구나 라고 이해는 되겠지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 class가 감당하는 게 너무 많으니&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이후부터의 코드만을 따로 구분하기 때문에, 이런 코드는 왜 같이 해놓고, 이 코드는 왜 따로 처리했을 까 하며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고의로 코드를 짤 때 해당 목적을 강조하는 듯한 느낌과 하나의 class안에 여러가지 기능이 있는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 class가 너무 많은 것을 내포하고 있어서 그 이후부터, 목적을 따로 구분하기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이질적인 느낌도 드는 것 같다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 같은 메모리주소를 참조한다면 한 메소드에 넣지말고, 이런 코드는 관심사의 분리 용도로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음부터 구분하는 것이 맞는 것 같다.는 결론이 나왔다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 대한 내용은 스프링 김영한 강사님의 기초강의에서 관심사 분리를 듣고, 의문이 들어서 생각해본 결론이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(참고로 스프링 컨테이너에서는 싱글톤에서&amp;nbsp; 관리를 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 작성하는 동안에는 그냥 플라이웨이트를 써도 되지 않았을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;싶었는데 기본을 싱글톤에서 관리하되, 다른 객체를 생성해야하면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로토타입 스코프로 Provider를 이용하면 알아서 처리를 다 해주기 떄문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Config를 수동 생성 할 때도, 굳이 플라이웨이트 패턴을 쓸 필요가 없다)&lt;/p&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_1647927437514&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;
class Client {
    private Mediator mediator;
    public void findID() {
        mediator.findID();    
    }
    public void setID(String id) {
        mediator.setID(id);
    }
    public void setPassword(String password) {
        mediator.setPassword(password);
    }
}

class Mediator{
    private String userID;
    private String userPassword;
    public void findID() {
        System.out.println(userID);
    }
    public void setID(String id) {
        this.userID=id;
    }
    public void setPassword(String password) {
        this.userPassword=password;
    }
    
}

class Server {
    private Mediator mediator;
    public void findID() {
        mediator.findID();
    }
    public void setID(String id) {
        mediator.setID(id);
    }
    public void setPassword(String password) {
        mediator.setPassword(password);
    }

}

public class java46 {
    public static void main(String[] args) {
        
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Server 쪽이랑 Client 각 단에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서로가 서로의 값을 바꾸려고 시도해서 접근해도 실제로는 mediator가 관리한다&lt;/p&gt;
&lt;pre id=&quot;code_1647928101671&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class NonMember {
    private Mediator mediator;
    public void setEmail(String email) {
        mediator.setEmail(email);
    }
    public void setID(String id) {
        mediator.setID(id);
    }
    public void setPassword(String password) {
        mediator.setPassword(password);
    }
}

class Member{
    Mediator mediator;
    
    public void findID(String id) {
        mediator.findID(id);
    }
    public void findPassword(String Password) {
        mediator.findPassword();
    }
}
class Mediator{
    private String email;
    private String userID;
    private String userPassword;
    public void setEmail(String email) {
        this.email=email;
    }
    public void findID() {
        System.out.println(userID);
    }
    public void findID(String email) {
        if(email==null) {
            System.out.println(&quot;어떠한 이메일도 등록되지않았습니다&quot;);
        }
        if(email!=this.email) {
            System.out.println(&quot;등록된 이메일이 바꼈거나 다른 이메일입니다&quot;);
        }
        System.out.println(userID);
    }
    public void findPassword() {
        System.out.println(userPassword);
    }
    public void setID(String id) {
        this.userID=id;
    }
    public void setPassword(String password) {
        this.userPassword=password;
    }
    
}

class Server {
    private Mediator mediator;
    public void findID() {
        mediator.findID();
    }
    public void setID(String id) {
        mediator.setID(id);
    }
    public void setPassword(String password) {
        mediator.setPassword(password);
    }

}



public class java46 {
    public static void main(String[] args) {
        
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래는 db같은 곳에 넣던가 (작게 테스트를 할꺼면) 임시로 동적 배열에 추가하면서 이메일,id,password로 정해야하지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그것까진 생각안하고 오직 하나의 계정에 대해서만 만들고 조회하도록 했다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 저기서 Mediator를 쓰지 않았다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NONMEMBER&amp;lt;-&amp;gt; MEMBER MEMBER&amp;lt;-&amp;gt;SERVER SERVER&amp;lt;-&amp;gt;NONMEMBER 이런식으로 서로가 서로의 데이터에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;접근하게 짜야되서 코드가 더 복잡해보일 것이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 이렇게 전부 다 Mediator에 접근해서 실제 코드로는 Mediator가 접근하도록 할 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 관련 자료를 오지게 뒤졌는데, Mediator를 cpp에서는 locate같이 직접 class로 접근해서 하는 경우도 있는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;java 블로그들은 다 interface로 접근했지만, 어차피 위와 같은 mediator는 다른 mediator를 만들어야 할 확장성이 있는 것도 아니고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능과 역할(interface와 class)에 대해서 굳이 비교할 필요없이 굳이 중간에 값 전달및 세팅만 하는 친구이고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전달 및 중간에 값 수정만 하는 거라서 큰 기능을 하는 것도 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 최근에 김영한 강사님의 스프링을 공부하는데 강사님께서도 interface로 연결안하고, 바로 class를 사용하시는 게 좀 컸다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 위 코드에서는 Mediator interface를 따로 두지않고, class로 바로 연동시켰다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 자료가 어디있냐면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 핵심 원리 기본편의 AppConfig 리팩토링 쪽을 보길 권한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보면 알겠지만 Public class로 구현하셨다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(실제 스프링 환경에서 수동 빈등록도 사용하신다고 하셨고, 위 기초 강의를 보면 알겠지만, 그 윗부분은 쭉 인터페이스와 class로 기능과 구현을 분리하는 걸 강조하시는데, 위 부분에서 interface로 두지 않는 것만 봐도 어느정도 의미가 있지 않나 싶다)&lt;/p&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;</description>
      <author>kail</author>
      <guid isPermaLink="true">https://hellocoding.tistory.com/6</guid>
      <comments>https://hellocoding.tistory.com/6#entry6comment</comments>
      <pubDate>Tue, 22 Mar 2022 15:00:35 +0900</pubDate>
    </item>
    <item>
      <title>디자인 패턴에 대한 정리(1)</title>
      <link>https://hellocoding.tistory.com/5</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;디자인&amp;nbsp;패턴&amp;nbsp;한번씩&amp;nbsp;보면&amp;nbsp;가질&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;의문들(1)&lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;추상팩토리패턴:&amp;nbsp;abstract구조로&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;높다&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;부여한다&lt;br /&gt;추가:&amp;nbsp;디자인패턴과는&amp;nbsp;상관없는데&amp;nbsp;abstract로&amp;nbsp;코딩했기때문에,&amp;nbsp;다중상속&amp;nbsp;불가능(즉&amp;nbsp;하나의&amp;nbsp;추상class에&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;class라면&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;상속받기보다는&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;게&amp;nbsp;크다면&lt;br /&gt;그&amp;nbsp;또한&amp;nbsp;케이크를&amp;nbsp;보는&amp;nbsp;class단위로&amp;nbsp;잡고&amp;nbsp;상속대신&amp;nbsp;케이크에서&amp;nbsp;케이크를&amp;nbsp;보는&amp;nbsp;클래스의&amp;nbsp;객체를&amp;nbsp;케이크라는&amp;nbsp;class를&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;abstract&amp;nbsp;class로&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;이건&amp;nbsp;혼자&amp;nbsp;작업할&amp;nbsp;떄&amp;nbsp;그런것이고,&amp;nbsp;기획자가&amp;nbsp;확장안해도&amp;nbsp;되요&amp;nbsp;라고&amp;nbsp;말했는데,&amp;nbsp;아...&amp;nbsp;확장안해도&amp;nbsp;된다고&amp;nbsp;했는데&amp;nbsp;확장해주세요&amp;nbsp;이러고&amp;nbsp;있으면&amp;nbsp;인터페이스가&amp;nbsp;훨씬&amp;nbsp;좋음)&lt;br /&gt;(물론&amp;nbsp;abstract로&amp;nbsp;혹시&amp;nbsp;몰라서&amp;nbsp;확장할&amp;nbsp;수도&amp;nbsp;있으니&amp;nbsp;class로&amp;nbsp;짜야지&amp;nbsp;이렇게&amp;nbsp;하면&amp;nbsp;되는데,&amp;nbsp;이렇게&amp;nbsp;abstract로&amp;nbsp;짜면&amp;nbsp;설계할&amp;nbsp;떄&amp;nbsp;머리에&amp;nbsp;힘을&amp;nbsp;좀&amp;nbsp;넣고&amp;nbsp;해야될듯)&lt;br /&gt;굳이&amp;nbsp;abstract로&amp;nbsp;쓰는&amp;nbsp;이유는&amp;nbsp;protected를&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;interface로도&amp;nbsp;물론&amp;nbsp;짤&amp;nbsp;수&amp;nbsp;있음&amp;nbsp;블로그에&amp;nbsp;올려놨는데,&amp;nbsp;마음대로&amp;nbsp;생각해서&amp;nbsp;고르면&amp;nbsp;될듯)&lt;br /&gt;2.&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;setter를&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;기능임&lt;br /&gt;장점:&amp;nbsp;이클립스는&amp;nbsp;db로&amp;nbsp;값&amp;nbsp;받을&amp;nbsp;때처럼&amp;nbsp;자바로&amp;nbsp;db값&amp;nbsp;안&amp;nbsp;바꾸고&amp;nbsp;그냥&amp;nbsp;객체&amp;nbsp;넘기기같은&amp;nbsp;거만&amp;nbsp;할꺼면&amp;nbsp;안에&amp;nbsp;5개&amp;nbsp;값&amp;nbsp;이상이&amp;nbsp;들어오면&amp;nbsp;여러개&amp;nbsp;값&amp;nbsp;받을&amp;nbsp;때&amp;nbsp;처럼&amp;nbsp;setter&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;강제할&amp;nbsp;수&amp;nbsp;있음&amp;nbsp;근데&amp;nbsp;이렇게&amp;nbsp;짜면&amp;nbsp;&lt;br /&gt;null&amp;nbsp;값이&amp;nbsp;들어올&amp;nbsp;수&amp;nbsp;있는건&amp;nbsp;함수를&amp;nbsp;빼먹으면&amp;nbsp;ㅈ되는듯?&amp;nbsp;그래서&amp;nbsp;필자는&amp;nbsp;&lt;br /&gt;if문&amp;nbsp;같이&amp;nbsp;만약&amp;nbsp;들어올&amp;nbsp;값이&amp;nbsp;null이면&amp;nbsp;예외를&amp;nbsp;throws로&amp;nbsp;넘길&amp;nbsp;것을&amp;nbsp;주장함(이렇게&amp;nbsp;짜면&amp;nbsp;setter처럼&amp;nbsp;null로&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;단점2:&amp;nbsp;인텔리제이는&amp;nbsp;생성자&amp;nbsp;안의&amp;nbsp;매개변수&amp;nbsp;값이&amp;nbsp;자동으로&amp;nbsp;보여주기&amp;nbsp;떄문에,&amp;nbsp;딱히&amp;nbsp;위와&amp;nbsp;같이&amp;nbsp;짤&amp;nbsp;필요가&amp;nbsp;없음&amp;nbsp;컴파일러가&amp;nbsp;ㅈ사기라는&amp;nbsp;말이기도&amp;nbsp;함...&lt;br /&gt;3.&amp;nbsp;팩토리메소드패턴:&amp;nbsp;생성할&amp;nbsp;떄&amp;nbsp;서브&amp;nbsp;class로&amp;nbsp;위임하는&amp;nbsp;패턴&lt;br /&gt;생성할&amp;nbsp;때&amp;nbsp;객체를&amp;nbsp;직접&amp;nbsp;생성해줘도&amp;nbsp;되는데,&amp;nbsp;얘는&amp;nbsp;Factory같은&amp;nbsp;다른&amp;nbsp;class가&amp;nbsp;생성을&amp;nbsp;해줌&amp;nbsp;AppConfig&amp;nbsp;만들&amp;nbsp;때&amp;nbsp;위&amp;nbsp;패턴을&amp;nbsp;사용함&lt;br /&gt;장점:&amp;nbsp;DI&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;setter/getter&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;A&amp;nbsp;&amp;lt;-&amp;gt;&amp;nbsp;B랑&amp;nbsp;B&amp;lt;-&amp;gt;C&amp;nbsp;C&amp;lt;-&amp;gt;A&amp;nbsp;라는&amp;nbsp;구조가&amp;nbsp;있으면&amp;nbsp;미디에이터&amp;nbsp;패턴으로&amp;nbsp;A&amp;lt;-&amp;gt;D&amp;nbsp;B&amp;lt;-&amp;gt;D&amp;nbsp;C&amp;lt;-&amp;gt;D로&amp;nbsp;편하게&amp;nbsp;짜겠지만&lt;br /&gt;시간이&amp;nbsp;없으니&amp;nbsp;public으로&amp;nbsp;각&amp;nbsp;데이터&amp;nbsp;바로&amp;nbsp;접근&amp;nbsp;수정해서&amp;nbsp;짜면&amp;nbsp;좀&amp;nbsp;더&amp;nbsp;빠르다는&amp;nbsp;거(안&amp;nbsp;썼을&amp;nbsp;때&amp;nbsp;좀&amp;nbsp;빠르니까&amp;nbsp;이거의&amp;nbsp;이익이&amp;nbsp;상황에&amp;nbsp;따라선&amp;nbsp;나을&amp;nbsp;수&amp;nbsp;있다는&amp;nbsp;점?)&lt;br /&gt;4.&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;clonable&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;갖다&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;사용하면&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;느려짐&lt;br /&gt;5.싱글턴:&amp;nbsp;얘는&amp;nbsp;생성하고&amp;nbsp;이후&amp;nbsp;이&amp;nbsp;메모리&amp;nbsp;사용할&amp;nbsp;떄&amp;nbsp;같은&amp;nbsp;메모리주소를&amp;nbsp;참조하도록&amp;nbsp;강제하는&amp;nbsp;느낌임&amp;nbsp;우회법도&amp;nbsp;있긴한데,&amp;nbsp;하는&amp;nbsp;사람이&amp;nbsp;설마&amp;nbsp;있을&amp;nbsp;까&amp;nbsp;싶어서&amp;nbsp;그냥&amp;nbsp;말&amp;nbsp;안함(그런거&amp;nbsp;우회할&amp;nbsp;수준이면&lt;br /&gt;이미&amp;nbsp;기존의&amp;nbsp;코드대로&amp;nbsp;짤듯)&lt;br /&gt;장점:&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;알고리즘할&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;db도&amp;nbsp;분리안하고&amp;nbsp;짜면&amp;nbsp;더&amp;nbsp;빠르다는&amp;nbsp;얘기도&amp;nbsp;있던데,&amp;nbsp;분리해서&amp;nbsp;하면&amp;nbsp;그&amp;nbsp;대신&amp;nbsp;db단이랑&amp;nbsp;분리가&amp;nbsp;더&amp;nbsp;잘되서&amp;nbsp;분리한다는&amp;nbsp;얘기를&amp;nbsp;들어&amp;nbsp;본&amp;nbsp;적이&amp;nbsp;있고,&lt;br /&gt;빠르면&amp;nbsp;c++을&amp;nbsp;위주로&amp;nbsp;하면&amp;nbsp;되는데,&amp;nbsp;java단은&amp;nbsp;좀&amp;nbsp;더&amp;nbsp;보기&amp;nbsp;편한&amp;nbsp;걸&amp;nbsp;위주로&amp;nbsp;아는&amp;nbsp;성향이&amp;nbsp;있다&lt;br /&gt;그래서&amp;nbsp;cpp쪽은&amp;nbsp;좀&amp;nbsp;더&amp;nbsp;저렇게&amp;nbsp;사용하는&amp;nbsp;걸&amp;nbsp;지향하겠지만,&amp;nbsp;java단은&amp;nbsp;저런&amp;nbsp;걸&amp;nbsp;짠다면&amp;nbsp;주변&amp;nbsp;사람들이&amp;nbsp;어렵더라도&amp;nbsp;얼마나&amp;nbsp;잘&amp;nbsp;사용하는지&amp;nbsp;&quot;보편성에&amp;nbsp;대한&quot;&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;줄이고,&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;java를&amp;nbsp;효율적으로&amp;nbsp;짜는&amp;nbsp;것이&amp;nbsp;아닌가&amp;nbsp;싶다)&lt;br /&gt;6.&amp;nbsp;어댑터:&amp;nbsp;두&amp;nbsp;개의&amp;nbsp;일정한&amp;nbsp;상황에서만&amp;nbsp;가능하게&amp;nbsp;정의&amp;nbsp;된&amp;nbsp;인터페이스들이&amp;nbsp;이미&amp;nbsp;있다면&amp;nbsp;이걸&amp;nbsp;유지보수할&amp;nbsp;떄&amp;nbsp;중간에&amp;nbsp;이을&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;인터페이스랑&amp;nbsp;구현체를&amp;nbsp;하나&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;연결되어있는&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;것&amp;nbsp;같다)&lt;br /&gt;7.&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;증가&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;치킨먹는class랑&amp;nbsp;피자먹는&amp;nbsp;class가&amp;nbsp;있는데,&amp;nbsp;여기서&amp;nbsp;그냥&amp;nbsp;각&amp;nbsp;class마다&amp;nbsp;먹는&amp;nbsp;게&amp;nbsp;공통적이라면&lt;br /&gt;먹는&amp;nbsp;함수만&amp;nbsp;오버라이딩&amp;nbsp;하고&amp;nbsp;void&amp;nbsp;eat(){sout(치킨먹기)sout&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;없다&lt;br /&gt;(그러니까&amp;nbsp;치킨먹는&amp;nbsp;class,피자먹는&amp;nbsp;class에&amp;nbsp;음식interface(안에&amp;nbsp;아무것도&amp;nbsp;없음),음식먹는class를&amp;nbsp;굳이&amp;nbsp;할&amp;nbsp;필요는&amp;nbsp;없다)&lt;br /&gt;8.컴퍼지트&amp;nbsp;패턴&amp;nbsp;&lt;br /&gt;트리&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;중간&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;add함수&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;File1.add(File2)이딴식으로&amp;nbsp;연결해야한다&lt;br /&gt;9.&amp;nbsp;데커레이터&amp;nbsp;패턴&lt;br /&gt;동적으로&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;맞을&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;저게&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;class가&amp;nbsp;ml당&amp;nbsp;가격이랑&amp;nbsp;이런거&amp;nbsp;상황에&amp;nbsp;맞게&amp;nbsp;선택해야&amp;nbsp;되고&amp;nbsp;커피콩도&amp;nbsp;class라g당&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;있는지&lt;br /&gt;이런거&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;class&amp;nbsp;우유&amp;nbsp;class&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;class&amp;nbsp;우유{if(우유&amp;nbsp;사기위한&amp;nbsp;조건==true)&amp;nbsp;{return&amp;nbsp;true;}&amp;nbsp;우유&amp;nbsp;함수(){return&amp;nbsp;우유&amp;nbsp;가격;}}&amp;nbsp;&lt;br /&gt;class설탕&amp;nbsp;{if(설탕&amp;nbsp;사기위한&amp;nbsp;조건==true)&amp;nbsp;설탕함수(){return&amp;nbsp;설탕&amp;nbsp;가격;}}&lt;br /&gt;머&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;커피class에&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;class형식으로&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;넘길&amp;nbsp;생각보다는&amp;nbsp;따로&amp;nbsp;사기위한&amp;nbsp;조건을&amp;nbsp;단위로&amp;nbsp;class를&amp;nbsp;둬서&amp;nbsp;거기에서&amp;nbsp;처리하도록&amp;nbsp;하는&amp;nbsp;것이&amp;nbsp;훨씬&amp;nbsp;잘&amp;nbsp;짜여진&amp;nbsp;설계이기&amp;nbsp;때문이다&lt;br /&gt;10.&amp;nbsp;퍼사드&amp;nbsp;패턴&lt;br /&gt;복잡하거나&amp;nbsp;반복적인&amp;nbsp;과정을&amp;nbsp;간단하게&amp;nbsp;사용하게&amp;nbsp;하는&amp;nbsp;패턴&lt;br /&gt;그냥&amp;nbsp;계산기&amp;nbsp;있으면&amp;nbsp;34+3을&amp;nbsp;할&amp;nbsp;떄&amp;nbsp;내부적으로&amp;nbsp;0과1어떻게&amp;nbsp;컴퓨터에서&amp;nbsp;처리하는지&amp;nbsp;코딩안하고&amp;nbsp;return&amp;nbsp;34+3;&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;class&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;oop&amp;nbsp;패턴방식인거&amp;nbsp;생각)&lt;br /&gt;11.&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;좋다&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;느낌이다&lt;br /&gt;12.&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;분리해줄&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;후순위로&amp;nbsp;해야되는&amp;nbsp;게&amp;nbsp;낫다.&lt;br /&gt;13.&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;class라&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;낫다&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;조건에서만&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;class로&amp;nbsp;쉽게&amp;nbsp;수정하려고&amp;nbsp;쓰는&amp;nbsp;용도.&amp;nbsp;책임&amp;nbsp;연쇄&amp;nbsp;패턴은&amp;nbsp;A안되면&amp;nbsp;B로&amp;nbsp;B안되면&amp;nbsp;C로&amp;nbsp;처리하는&amp;nbsp;용도&amp;nbsp;&lt;br /&gt;14.&amp;nbsp;인터프리터&amp;nbsp;패턴&lt;br /&gt;코딩&amp;nbsp;언어&amp;nbsp;만들면,&amp;nbsp;문법&amp;nbsp;같은&amp;nbsp;걸&amp;nbsp;class단위로&amp;nbsp;묶는&amp;nbsp;패턴&lt;br /&gt;장점:&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;java같은&amp;nbsp;언어에서&amp;nbsp;프로그램만&amp;nbsp;실행시키도록&amp;nbsp;하는&amp;nbsp;방법을&amp;nbsp;추천한다&lt;br /&gt;15.&amp;nbsp;이터레이터&amp;nbsp;패턴&lt;br /&gt;장점:&amp;nbsp;이터레이터&amp;nbsp;만들어서&amp;nbsp;class에&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;전에&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;add로&amp;nbsp;직접&amp;nbsp;늘려줘야되서&amp;nbsp;컴파짓도&amp;nbsp;되지만&amp;nbsp;이터레이터&amp;nbsp;패턴으로&amp;nbsp;짜는게&amp;nbsp;맞다&lt;br /&gt;16.&amp;nbsp;미디에이터&amp;nbsp;패턴&lt;br /&gt;장점:&amp;nbsp;위에서도&amp;nbsp;말했는데&amp;nbsp;A&amp;lt;-&amp;gt;B&amp;nbsp;B&amp;lt;-&amp;gt;C&amp;nbsp;C&amp;lt;-&amp;gt;A&amp;nbsp;이렇게&amp;nbsp;각각이&amp;nbsp;각각을&amp;nbsp;참조하는&amp;nbsp;구조라면&amp;nbsp;A&amp;lt;-&amp;gt;D&amp;nbsp;B&amp;lt;-&amp;gt;D&amp;nbsp;C&amp;lt;-&amp;gt;D&amp;nbsp;이런식으로&amp;nbsp;짜는게&amp;nbsp;훨씬&amp;nbsp;보기&amp;nbsp;편하다&lt;br /&gt;단점:&amp;nbsp;위&amp;nbsp;패턴으로&amp;nbsp;만드는데&amp;nbsp;걸리는&amp;nbsp;시간&lt;br /&gt;17.&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;패턴&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;A기억하고&amp;nbsp;B로&amp;nbsp;A를&amp;nbsp;추가해서&amp;nbsp;B쓰다가&amp;nbsp;A클래스로&amp;nbsp;다시&amp;nbsp;참조하거나&amp;nbsp;하면&amp;nbsp;되는데,&lt;br /&gt;clonable쓰면&amp;nbsp;되고,&amp;nbsp;A,B,C,D,E,F&amp;nbsp;각각&amp;nbsp;저장하려고&amp;nbsp;하면&amp;nbsp;clonable로&amp;nbsp;B,C,D,E,F를&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;같다(stack으로&amp;nbsp;넣어서&amp;nbsp;쉽게&amp;nbsp;&lt;br /&gt;가져다&amp;nbsp;쓸&amp;nbsp;수&amp;nbsp;있음)&lt;br /&gt;단점:&amp;nbsp;2개&amp;nbsp;비교하고&amp;nbsp;끝낼&amp;nbsp;때&amp;nbsp;스택으로&amp;nbsp;메모리&amp;nbsp;저장해도&amp;nbsp;되기는&amp;nbsp;할&amp;nbsp;것&amp;nbsp;같은데,&amp;nbsp;clonable이&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;복사하려면&amp;nbsp;다&amp;nbsp;만들어야되는&amp;nbsp;반면,&amp;nbsp;이&amp;nbsp;친구는&amp;nbsp;스택만&amp;nbsp;만들면&amp;nbsp;된다)&lt;br /&gt;18.옵서버&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;패턴&lt;br /&gt;좀&amp;nbsp;더&amp;nbsp;풀어서&amp;nbsp;설명하면&lt;br /&gt;A라는&amp;nbsp;class랑&amp;nbsp;B라는&amp;nbsp;class가&amp;nbsp;있다면&amp;nbsp;여기서&amp;nbsp;B에서&amp;nbsp;A라는&amp;nbsp;class를&amp;nbsp;사용하려면&amp;nbsp;생성자에서&amp;nbsp;A라는&amp;nbsp;class를&amp;nbsp;인자로&amp;nbsp;받으면&amp;nbsp;되는데,&lt;br /&gt;이런&amp;nbsp;경우&amp;nbsp;생기는&amp;nbsp;단점은&amp;nbsp;A라는&amp;nbsp;class에&amp;nbsp;있는&amp;nbsp;변수를&amp;nbsp;막&amp;nbsp;접근할&amp;nbsp;수도&amp;nbsp;있다.&amp;nbsp;그리고&amp;nbsp;만약&amp;nbsp;A대신&amp;nbsp;service의&amp;nbsp;같은&amp;nbsp;기능을&amp;nbsp;하는C라는&amp;nbsp;class로&amp;nbsp;사용을&amp;nbsp;바꾸고&amp;nbsp;싶다면&lt;br /&gt;A대신&amp;nbsp;C로&amp;nbsp;인자를&amp;nbsp;바꾸고,&amp;nbsp;값을&amp;nbsp;보낼&amp;nbsp;때도&amp;nbsp;A로&amp;nbsp;보내지&amp;nbsp;말고&amp;nbsp;C로&amp;nbsp;보내게&amp;nbsp;짜야해서&amp;nbsp;비효율적이다&lt;br /&gt;근데,&amp;nbsp;이걸&amp;nbsp;service의&amp;nbsp;기능을&amp;nbsp;인터페이스로&amp;nbsp;만들고&amp;nbsp;A랑&amp;nbsp;C를&amp;nbsp;인터페이스의&amp;nbsp;구현체로&amp;nbsp;만들면&lt;br /&gt;인터페이스로&amp;nbsp;보내면&amp;nbsp;인터페이스의&amp;nbsp;구혀A대신&amp;nbsp;C로&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;한다&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;것&lt;br /&gt;옵저버&amp;nbsp;패턴은&amp;nbsp;쉽게&amp;nbsp;가져다&amp;nbsp;쓸&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;&quot;인터페이스로&amp;nbsp;값을&amp;nbsp;보내주는&amp;nbsp;방법&quot;이다&lt;br /&gt;스테이트&amp;nbsp;패턴:&amp;nbsp;각&amp;nbsp;객체마다&amp;nbsp;동적으로&amp;nbsp;객체&amp;nbsp;상태가&amp;nbsp;A면&amp;nbsp;A&amp;nbsp;형태로&amp;nbsp;B면&amp;nbsp;B형태로&amp;nbsp;자주&amp;nbsp;바뀌면&amp;nbsp;효과적인&amp;nbsp;방법이다&lt;br /&gt;장점:&amp;nbsp;예를&amp;nbsp;들어&amp;nbsp;A라는&amp;nbsp;사람이&amp;nbsp;한&amp;nbsp;게임&amp;nbsp;내에서&amp;nbsp;검으로&amp;nbsp;공격도&amp;nbsp;되고,&amp;nbsp;활로도&amp;nbsp;공격이&amp;nbsp;되는데&amp;nbsp;무기를&amp;nbsp;계속&amp;nbsp;이거&amp;nbsp;썼다가&amp;nbsp;저거썼다가&amp;nbsp;하면&amp;nbsp;스트레티지(전략패턴)은&amp;nbsp;attack()메소드를&amp;nbsp;오버라이딩&amp;nbsp;해서&lt;br /&gt;A를&amp;nbsp;객체로&amp;nbsp;생성했다가&amp;nbsp;B를&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;이걸&amp;nbsp;계속&amp;nbsp;바꾸려고한다면&amp;nbsp;change.sword()&amp;nbsp;change.bow()만&amp;nbsp;호출해서&lt;br /&gt;객체만&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;각&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;유지되므로&amp;nbsp;스트레티지(전략&amp;nbsp;패턴)이&amp;nbsp;더&amp;nbsp;효과적이다&lt;br /&gt;템플릿&amp;nbsp;메소드&amp;nbsp;패턴:&amp;nbsp;&lt;br /&gt;나중에 함수를 오버라이딩 할 때, 기존의 부모 class에 있는 것과 자식class에 있는 메소드를&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;br /&gt;행위자랑&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;class로&amp;nbsp;구분하는&amp;nbsp;패턴이다&lt;br /&gt;장점:&amp;nbsp;예를&amp;nbsp;들어&amp;nbsp;캐릭터&amp;nbsp;커스터마이징&amp;nbsp;할&amp;nbsp;때&amp;nbsp;A라는&amp;nbsp;사람이랑&amp;nbsp;B라는&amp;nbsp;댄스&amp;nbsp;동작이&amp;nbsp;있다면&lt;br /&gt;3D&amp;nbsp;캐주얼&amp;nbsp;같은&amp;nbsp;게임을&amp;nbsp;A라는&amp;nbsp;사람&amp;nbsp;B라는&amp;nbsp;사람&amp;nbsp;C라는&amp;nbsp;사람이라는&amp;nbsp;사람틀이랑&amp;nbsp;3d&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;A라는&amp;nbsp;사람&amp;nbsp;B라는&amp;nbsp;사람&amp;nbsp;C라는&amp;nbsp;사람&amp;nbsp;틀만&amp;nbsp;만들고&amp;nbsp;목흔드는&amp;nbsp;댄스의&amp;nbsp;class를&amp;nbsp;만들어서,&amp;nbsp;거기서&amp;nbsp;각&amp;nbsp;행위자&amp;nbsp;class의&amp;nbsp;목을&amp;nbsp;흔드는&amp;nbsp;동작을&amp;nbsp;취하는&amp;nbsp;함수를&amp;nbsp;만들면&amp;nbsp;된다&lt;br /&gt;단점:&amp;nbsp;class는&amp;nbsp;너무&amp;nbsp;많아지면&amp;nbsp;역으로&amp;nbsp;불필요하다.&amp;nbsp;그래서,&amp;nbsp;위와&amp;nbsp;같이&amp;nbsp;행위자랑&amp;nbsp;행동을&amp;nbsp;구분해야하는&amp;nbsp;확장성이&amp;nbsp;필요하다면&amp;nbsp;그거에&amp;nbsp;맞게&amp;nbsp;분리하면&amp;nbsp;될&amp;nbsp;뿐이라고&amp;nbsp;생각한다&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <author>kail</author>
      <guid isPermaLink="true">https://hellocoding.tistory.com/5</guid>
      <comments>https://hellocoding.tistory.com/5#entry5comment</comments>
      <pubDate>Sat, 19 Mar 2022 16:27:03 +0900</pubDate>
    </item>
    <item>
      <title>팩토리 메소드를 interface로 구현해보기</title>
      <link>https://hellocoding.tistory.com/3</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=qr7I18Lhsl8&amp;amp;list=PLsoscMhnRc7pPsRHmgN4M8tqUdWZzkpxY&amp;amp;index=2&quot;&gt;https://www.youtube.com/watch?v=qr7I18Lhsl8&amp;amp;list=PLsoscMhnRc7pPsRHmgN4M8tqUdWZzkpxY&amp;amp;index=2&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=qr7I18Lhsl8&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/eUrcs/hyNxRz2YAo/dAFPrGPSEXC1kBOFAQPCo0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/qr7I18Lhsl8&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 영상과 4강 팩토리 메소드를 보고, 의문이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(따라서 소스예제는 3강에 있는 abstract단만 건들여봤다)&lt;/p&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;interface 자체는 protected같은 코드가 오기 어렵다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 경우 protected가 의도적으로 함수를 숨기기 위해서 사용되는 장점을 잃는 댓가가 따른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 자바에서는 위의 경우를 사용할 때 전체 코드에서 abstract를 지원해서, 기능을 확장하며, 사용하는걸 (컴파일러가) 권고한다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 abstract 대신 interface로 저것도 대체 가능하지 않을까? 라는 의문이 들었고 이를 실제로 코드로 작성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(네이밍은 이해바란다..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 내가 interface로 시도하려고 했다가, 위와 같이 작성한 이유가 있는데, 그것 까지 코드 보여주면 너무 길어지기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단히 말로 설명한다....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 큰 public class함수에 protected 인터페이스를 작성하고, 그 안을 public으로 작성(c++과는 다르기 때문에 인터페이스 안의 메소드는 제어 확장자가 정해져있기 때문에 이렇게 작성하게 된다...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1-1. 인터페이스안의 함수를 static으로 작성하고, 구현체에서 그 값을 수정할 수 있도록 하기(try-catch로 컴파일 에러 예외처리 따로)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt;이 경우&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 예외처리만 남은 상태였는데, SOLID 원칙 중 LSP(리스코프 치환 원칙)에 어긋나는 것 같아서 보류하고 바로 수정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1-2.본문에서 시도한 것처럼 인터페이스의 함수를 none-static으로 하고, try-catch로 interface타입에 null을 부여하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각 대입하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(처음에 해봤을 때 타입이 잘 안나왔는데, stack-overflow를 보니 묶을 때 기본 타입이 안전하지 않을 수 있는건 null을 써야됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt;이 경우에도, abstract보다 단점이 존재했다..&lt;/p&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;둘째로, 그 타입을 상속받을 경우 @Override를 쓰지 못함(즉, 오버라이드 애너테이션에 맞지 않음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1645895759961&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    //하위 클래스로 나눠진 메소드들을 구현한다 (Templete method는 이걸 묶어서 다 구현)
    // protected interface t{
    //     public String fssdef();
    // }
    //자바에서 interface 에 정의되는 메소드는 외부로 공개되는 메소드를 정의하는 것 입니다. 그러므로 private 나 protected 로 정의가 불가능합니다.

    abstract class AbstGameConnectHelper {
        protected abstract String doSecurity(String string);
        protected abstract boolean authentication(String id,String password);
        protected abstract int authentication(String userName);
        protected abstract String connection(String info);

        //템플릿 메소드
        public String requestConnection(String encodedInfo) throws Exception {
            //보안 작업 -&amp;gt; 암호화된 문자열을 디코딩
            String decodedInfo = doSecurity(encodedInfo);
            String id=&quot;aaa&quot;;
            String password=&quot;bbb&quot;;

            if(!authentication(id,password)){   //id,password불일치라면
                throw new Error(&quot;아이디 암호 불일치&quot;);
            }

            String userName=&quot;&quot;; 
            int i=authentication(userName);
            switch(i)
            {
                case -1:
                    throw new Exception(&quot;셧다운&quot;);
                case 0: //게임 매니저
                    break;
                case 1: //유료회원
                    break;
                case 2: //무료회원
                    break;
                case 3: //권한없음
                    break;
                default:    //기타 상황
                    break;
            }


            return connection(encodedInfo);

        }
    }

    class DefaultGameConnectHelper extends AbstGameConnectHelper {

        @Override
        protected String doSecurity(String string) {
            // TODO Auto-generated method stub
            System.out.println(&quot;디코드&quot;);
            return string;
        }

        @Override
        protected boolean authentication(String id, String password) {
            // TODO Auto-generated method stub
            System.out.println(&quot;아이디/암호 확인 과정&quot;);
            return true;
        }

        @Override
        protected int authentication(String userName) {
            // TODO Auto-generated method stub
            System.out.println(&quot;권한 확인&quot;);
            return 0;
        }

        @Override
        protected String connection(String info) {
            // TODO Auto-generated method stub
            System.out.println(&quot;마지막 접속단계!&quot;);
            return info;
        }

    }&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;pre id=&quot;code_1645895815222&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class java32 {
    @FunctionalInterface
    protected interface faeaw{
        public String doSecurity2(String string);
    }
    @FunctionalInterface
    protected interface faeaw2{
        public boolean authentication2(String id,String password);
    }
    @FunctionalInterface
    protected interface faeaw3{
        public int authentication2(String userName);
    }
    @FunctionalInterface
    protected interface faeaw4 {
        public String connection2(String info);
    }

    public String requestConnection2(String encodedInfo) {
    try{
            // 보안 작업 -&amp;gt; 암호화된 문자열을 디코딩
    faeaw trySecurity=null;
    faeaw2 tryAuthentication2ToLogin=null;
    faeaw3 tryAuthentication2ToName=null;
    faeaw4 dfawef=null;
  
    String decodedInfo = trySecurity.doSecurity2(encodedInfo);
    

    String id=&quot;aaa&quot;;
    String password=&quot;bbb&quot;;
    if(!tryAuthentication2ToLogin.authentication2(id,password)){   //id,password불일치라면
        throw new Error(&quot;아이디 암호 불일치&quot;);
        }
            String userName=&quot;&quot;; 
            int i=tryAuthentication2ToName.authentication2(userName);
            switch(i)
            {
                case -1:
                    throw new Exception(&quot;셧다운&quot;);
                case 0: //게임 매니저
                    break;
                case 1: // 유료회원
                    break;
                case 2: // 무료회원
                    break;
                case 3: // 권한없음
                    break;
                default:    // 기타 상황
                    break;
            }


            return dfawef.connection2(encodedInfo);

        }
        catch(Throwable e)
        {
            e.printStackTrace();
        }
        
        return null;
    }
}



class DefaultGameConnectHelper2 extends java32 {

        class wfnke implements faeaw { 
        @Override
            public String doSecurity2(String string) {
            // TODO Auto-generated method stub
            System.out.println(&quot;디코드&quot;);
            return string;
            }   
        }
            class wfnke2 implements faeaw2 {
            @Override
            public boolean authentication2(String id, String password) {
            // TODO Auto-generated method stub
                System.out.println(&quot;아이디/암호 확인 과정&quot;);
                return true;
            }
        }
        class wfnke3 implements faeaw3 {
            @Override
            public int authentication2(String userName) {
            // TODO Auto-generated method stub
            System.out.println(&quot;권한 확인&quot;);
            return 0;
            }
        }   

        class wfnke4 implements faeaw4 {
            @Override
            public String connection2(String info) {
            // TODO Auto-generated method stub
            System.out.println(&quot;마지막 접속단계!&quot;);
            return info;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;implements로 구현한 코드&lt;/p&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번에 서술된 단점&lt;/p&gt;
&lt;pre id=&quot;code_1645895898014&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class fawamewlkmf extends DefaultGameConnectHelper2{
    class Appl43te extends DefaultGameConnectHelper2.wfnke3 {
        // @Override 위의 타입에서 수정했으므로 이건 하면 안됨
    public String connection2(String info) {
        // TODO Auto-generated method stub
        System.out.println(&quot;??&quot;);
        System.out.println(&quot;마지막 접속단계!&quot;);
        return info;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 접근할 때 어렵게 접근해야한다는 단점이 존재한다..&lt;/p&gt;
&lt;pre id=&quot;code_1645895957892&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Fwln extends SFe {

	@Override
	protected String fanwk() {
		// TODO Auto-generated method stub
		return null;
	}
	
}
class fnewk extends Fwln {
	@Override
	protected String fanwk() {
		// TODO Auto-generated method stub
		return null;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 abstract는 한번 더 상속을 받을 때 이렇게 쉽게 접근 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후기는 위와 같이 @FunctionalInterface같은 에너테이션과 SOLID 원칙(isp,Ocp)에 위반되지 않는 코드를 작성하느라 힘들었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;static으로 할 것이냐, non-static으로 할 것이냐, 다른 방법이 있느냐, interface 접근을 어케할 것이냐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 경우는 어떻게 처리하면 되느냐, 등 조건이 너무 많았다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번을 시도 할 때, String대신 Optional&amp;lt;String&amp;gt;을 쓰다가 본문에서는 쓰지 않았는데, 기존 코드에서 id, password에 null 값이 들어올 수도 있다는 내용이 없기도 했고, 이 경우 초기 선언 값을 Null로 했기 떄문에, 중간 인터페이스 과정이 NULL 값이 접근이 되면 예외가 될 것이고, 그게 아니면 기존 코드와 동일한 효과를 내기 때문에 쓰지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 Optional,람다를 익힌지 얼마 안되서 짜보고 싶긴 했는데, 아직은 딱히 쓰면 좋겠다는 코드가 잘 보이지 않은 것 같다&lt;/p&gt;</description>
      <author>kail</author>
      <guid isPermaLink="true">https://hellocoding.tistory.com/3</guid>
      <comments>https://hellocoding.tistory.com/3#entry3comment</comments>
      <pubDate>Sun, 27 Feb 2022 02:19:46 +0900</pubDate>
    </item>
  </channel>
</rss>