<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0">
  <title type="html">The Winner Takes It All</title>
  <id>http://www.nohungry.net/tt1/</id>
  <link rel="alternate" type="text/html" hreflang="ko" href="http://www.nohungry.net/tt1/" />
  <subtitle type="html">뽐뿌가 없으면 블로그도 없다.</subtitle>
  <updated>2011-10-04T08:59:54+09:00</updated>
  <generator>Textcube 1.7.7 : Beta 2</generator>
  <entry>
    <title type="html">[C#] 폼(Form) 간의 값을 전달하는 방법!</title>
    <link rel="alternate" type="text/html" href="http://www.nohungry.net/tt1/162" />
    <link rel="replies" type="application/atom+xml" href="http://www.nohungry.net/tt1/atom/response/162" thr:count="7"/>
    <category term=".NET" />
    <category term="C# 강좌" />
    <category term="delegate" />
    <category term="이벤트" />
    <category term="폼 간의 값을 전달하는 방법" />
    <author>
      <name>(노헝그리)</name>
    </author>
    <id>http://www.nohungry.net/tt1/162</id>
    <updated>2010-03-18T15:41:59+09:00</updated>
    <published>2010-03-18T15:39:03+09:00</published>
    <summary type="html">부모 폼과 자식 폼이 있다; 자식 폼에서 A라는 버튼을 클릭했을 때; B라는 텍스트 박스의 내용을 부모 폼의 C라는 텍스트 박스에 표시하고 싶다; 그 방법은?&lt;br&gt;&lt;br&gt;물론; 가장 간단한 방법은 private으로 선언되어 있는 C라는 텍트스 박스를 public으로 선언하고; 자식 폼에서 직접 이 텍스트 박스에 접근하여; 값을 대입하는 방법이 있습니다;&lt;br&gt;&lt;br&gt;하지만; 개인적으로 이 방법은 C#이 지향하는 OOP(Object-oriented paradigm)를 위배하고; 깔끔하지 못한 방법으로 별로 권장하고 싶지 않네요;&lt;br&gt;&lt;br&gt;개인적으로 권장하는 것은 이벤트(event)를 이용하는 것 입니다; 이벤트는 단순히 폼 간의 어떤 데이터를 주고 받을 수 있을 뿐만 아니라; 서로 다른 클래스 간의 데이터 전송에도 유용하며, 데이터를 구조체 형식으로도 넘길 수 있는 등 다양한 장점이 있지요; 무엇보다, OOP를 준수하면서도; 깔끔한 코드를 유지할 수 있다는 것에 후한 점수를 주고 싶군요;&lt;br&gt;&lt;br&gt;이 이벤트를 구현하는 방법에 가장 핵심이 되는 내용은 바로 delegate 입니다.&lt;br&gt;C++/MFC, java 등 다른 언어에 능숙한 사람들 대부분이 C#에 금방 적응하게 됨에도 불구하고; 그나마 C#에서 가장 당황하는 개념이 delegate가 아닐까 싶네요; (나만 그런가?;)&lt;br&gt;&lt;br&gt;delegate는 한글로 굳이 번역하자면; 대리자라고 하는데; C#이 다른 언어와 차별성을 가지는 중요한 몇 몇 이슈 중 하나가 이 녀석의 존재라고 생각합니다;&lt;br&gt;&lt;br&gt;단어 뜻으로만 이해하자면; 어려우니까; 서두에 언급한 자식 폼에서 부모 폼으로 텍스트를 전달하는 예제를 통해; delegate의 역할을 이해해보죠;&lt;br&gt;&lt;br&gt;이미 언급했지만; 자식 폼에서 부모 폼으로 데이터를 전달할 때, 이벤트를 이용하기로 하였는데; 이벤트에서 가장 기본적인 사실은; 이벤트를 발생하는 곳이 있으면, 이벤트를 받는 쪽도 있어야 된다는 것입니다;&lt;br&gt;&lt;br&gt;따라서, 자식 폼에는 이벤트를 발생시키는 녀석을 정의하고, 부모 폼에서는 이벤트를 받는 녀석을 정의해야 된겠지요. 이미 C#을&amp;nbsp; 이용해 윈 폼 프로그래밍을 해본 사람이라면; 폼에 버튼을 붙이고; 클릭 이벤트를 추가해서; 버튼을 클릭하면; 메시지 박스로 &quot;Hello, World!&quot; 정도는 경험이 있을 것 입니다;&lt;br&gt;&lt;br&gt;이 때, 버튼도 우리가 예로 들려는 자식 폼과 같습니다; 버튼이 이벤트를 발생시키고, 부모 폼에서 버튼 이벤트를 받아, 거기서 메시지 박스를 띄운 것이기 때문이지요;&lt;br&gt;&lt;br&gt;자 이벤트를 정의하는 과정은 다음과 같습니다;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1329496948.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;516&quot; width=&quot;600&quot; /&gt;&lt;/div&gt; &lt;br&gt;클래스 ChildFormEventArgs는 이벤트 데이터가 들어 있는 클래스에 대한 기본 클래스인 EventArgs를 상속 받아 구현하였습니다. 우리는 자식 폼에서 부모 폼으로 텍스트를 전송할 목적이므로, 기본 클래스에 message란 속성을 추가하였구요;&lt;br&gt;&lt;br&gt;그리고 그 아래 이벤트 대리자(delegate)를 선언하는데, 대리자를 통해 넘기는 파라미터에 주목해봅시다;&lt;br&gt;ChildFormEventArgs는 앞에 언급한대로 이벤트 데이터 이고, object sender는 뭘까요?&lt;br&gt;&lt;br&gt;이벤트를 발생 시킨 주체입니다; 우리의 예에서는 바로 자식폼이 되겠지요;&lt;br&gt;&lt;br&gt;이벤트를 위한 대리자를 선언했으면; 자식 폼에 이 이벤트를 발생시키기 위한 코드를 구현해야 합니다;&lt;br&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1199729411.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;621&quot; width=&quot;493&quot; /&gt;&lt;/div&gt;&lt;br&gt;이벤트 선언부를 눈여겨 보세요;&lt;br&gt;&lt;br&gt;이에 앞서 선언한 delegate에 이벤트를 위한 엑세스 한정자인 event를 붙였습니다; 그리고 파생 클래스에서 이 이벤트를 일으키거나 override 할 수 있도록 protected와 virtual 키워드를 붙였지요;&lt;br&gt;&lt;br&gt;그리고 그 아래 정의된 메소드는 자식 폼에 추가한 버튼을 클릭하면 호출되는 녀석; 이미 알고 있듯이; 우리는 버튼을 클릭했을 때, 자식 폼에 있는 텍스트 박스(txtSentMessage)에 적힌 텍스트를 부모 폼에 전달하기 위함이므로; 앞서 정의한 event를 발생시킬 수 있는 NotifyEvent를 호출하도록 하였습니다;&lt;br&gt;&lt;br&gt;그럼, 이제 부모 폼에서 이벤트를 받을 수 있도록 구현해보죠;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1105612176.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;602&quot; width=&quot;600&quot; /&gt;&lt;/div&gt;&lt;br&gt;부모 폼의 생성자(constructor)에 자식폼의 메모리를 할당하고; 이벤트를 받기 위해 OnNotifyParent이벤트 핸들러를 추가합니다;&lt;br&gt;&lt;br&gt;자, 여기서 대리자(delegate)의 역할을 이해할 수 있습니다. 자식 폼에서는 결코 부모 폼의 child_OnNotifyParent 메소드를 직접적으로 호출하지 않습니다. 단지, 이벤트로 정의한 OnNotifyParent(delegate)를 구현하였고; 이를 이용해 이벤트를 발생시키는 NotifyEvent 메소드만 구현했을 뿐이지요; 하지만 OnNotifyParent는 대리자란 명칭에 걸맞게; NotifyEvent가 호출되면; 간접적으로 child_OnNotifyParent 해줬습니다;&lt;br&gt;&lt;br&gt;이 때 이벤트 데이터를 전달해주는 ChildFormEventArgs를 통해 자식폼의 텍스트 박스에 적힌 텍스트를 가져올 수 있네요;&lt;br&gt;&lt;br&gt;다시, 정리하자면 이렇습니다.&lt;br&gt;1. 이벤트는 이벤트를 발생시키는 곳이 있으면, 발생한 이벤트를 듣는 곳도 있다;&lt;br&gt;2. 이벤트는 이벤트를 발생시키는 곳과 발생한 이벤트를 듣는 곳을 잇기 위한 대리자(delegate)로 구현한다.&lt;br&gt;&lt;br&gt;delegate란 개념은 단지; 이벤트를 구현할 때만 쓰이지 않습니다; 제가 오래 전에 블로그에 쓴 C#에서 &lt;a href=&quot;http://www.nohungry.net/tt1/39&quot; target=&quot;_blank&quot;&gt;크로스 쓰레드 문제&lt;/a&gt;에서도 언급된 적이 있습니다. 사실 저도 저 때 delegate 개념이 구체화 되지는 않았습니다; 어렴풋이 이해만 했었고; 단지 저런 상황이 생기면; 다시 써먹기 위해 남겼을 뿐이지요..;&lt;br&gt;&lt;br&gt;혹시나 필요하신 분들이 있을까; 아티클에 설명한 예제의 소스 코드를 첨부합니다;&lt;br&gt;&lt;br&gt;&lt;a href=&quot;http://www.nohungry.net/Data/EventHandlerSampleApp.zip&quot; target=&quot;_blank&quot;&gt;다운로드&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;fieldset style=&quot;margin:20px 0px 20px 0px;padding:5px;&quot;&gt;&lt;legend&gt;&lt;span&gt;&lt;strong&gt;크리에이티브 커먼즈 라이센스&lt;/strong&gt;&lt;/span&gt;&lt;/legend&gt;&lt;!--Creative Commons License--&gt;&lt;div style=&quot;float: left; width: 88px; margin-top: 3px;&quot;&gt;&lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;&lt;img alt=&quot;Creative Commons License&quot; style=&quot;border-width: 0&quot; src=&quot;http://i.creativecommons.org/l/by-nc-nd/2.0/kr/88x31.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: 92px; margin-top: 3px; text-align: justify;&quot;&gt;이 저작물은 &lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스&lt;/a&gt;에 따라 이용하실 수 있습니다.
			&lt;!-- Creative Commons License--&gt;
			&lt;!-- &lt;rdf:RDF xmlns=&quot;http://web.resource.org/cc/&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;&gt;
			&lt;Work rdf:about=&quot;&quot;&gt;
			&lt;license rdf:resource=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; /&gt;
			&lt;/Work&gt;
			&lt;License rdf:about=&quot;http://creativecommons.org/licenses/by-nc-nd/&quot;&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Reproduction&quot;/&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Distribution&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Notice&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Attribution&quot;/&gt;&lt;prohibits rdf:resource=&quot;http://web.resource.org/cc/CommercialUse&quot;/&gt;&lt;/License&gt;&lt;/rdf:RDF&gt; --&gt;&lt;/div&gt;&lt;/fieldset&gt;</summary>
  </entry>
  <entry>
    <title type="html">[C#] 클라이언트/서버 프로그래밍의 기초 개념;</title>
    <link rel="alternate" type="text/html" href="http://www.nohungry.net/tt1/161" />
    <link rel="replies" type="application/atom+xml" href="http://www.nohungry.net/tt1/atom/response/161" thr:count="0"/>
    <category term=".NET" />
    <category term="TCP" />
    <category term="UDP" />
    <category term="소켓 프로그래밍" />
    <category term="클라이언트 서버 프로그래밍" />
    <category term="포트" />
    <author>
      <name>(노헝그리)</name>
    </author>
    <id>http://www.nohungry.net/tt1/161</id>
    <updated>2010-03-18T11:51:57+09:00</updated>
    <published>2010-03-09T18:06:52+09:00</published>
    <summary type="html">&amp;nbsp;클라이언트/서버 프로그래밍(이하 C/S)은 네트워크(Network) 프로그램 중에 가장 일반적이고, 가장 폭 넓게 사용됩니다; 넓은 의미로 보면 사람들이 많이 하는 온라인 게임, 메신저, P2P 등도 클라이언트/서버 구조에 속합니다;&lt;br&gt;&lt;br&gt;&amp;nbsp;클라이언트와 서버란?&lt;br&gt;좀 억지스럽긴 하지만; 굳이 표현하자면 전화를 거는 사람이 클라이언트, 전화를 받는 사람이 서버입니다; 물론, 일반적인 C/S 프로그램은 서버는 하나, 클라이언트는 다수인 경우입니다. (사실, 때에 따라선 서버도 다수, 클라이언트도 다수가 될 수 있지만...) 결국 클라이언트와 서버가 통신을 하기 위해서는 클라이언트가 서버에 접속 요청을 하고; 서버가 이를 수락함으로써 연결이 맺어집니다;&lt;br&gt;&lt;br&gt;&amp;nbsp;클라이언트와 서버가 연결이 맺어지기 까지의 과정을 소개하자면 다음과 같습니다.&lt;br&gt;A. 서버가 특정 포트를 오픈(Bind)합니다.&lt;br&gt;B. 서버가 클라이언트의 연결을 대기(Listen)합니다.&lt;br&gt;C. 클라이언트가 서버의 특정 포트로 연결(Connect)합니다.&lt;br&gt;D. 서버가 클라이언트의 연결을 수락(Accept)합니다.&lt;br&gt;&lt;br&gt;&amp;nbsp;괄호() 안의 용어는 대부분의 소켓(Socket) APIs에서 제공하는 함수 또는 메쏘드의 이름이며, 표준 용어라고 할 수 있습니다. 원칙적이라면 서버가 특정 포트에 바인딩 한다고 표현하는 것이 맞겠지요.&lt;br&gt;&lt;br&gt;&amp;nbsp;잠깐... 여기서 몇가지 짚고 넘어가야할 이야기가 있습니다;&lt;br&gt;제가 앞서 기술한 내용은 모두 연결지향성 프로토콜(TCP)을 기준으로 한 내용입니다; 이외에도 일반적으로 네트워크 프로그래밍에 등장하는 비연결지향성 프로토콜(UDP)도 많이 사용되며, 그 외에도 IPX, IP 등 너무 많은 프로토콜이 있지만; 여기선 다 생략하고, 일단 TCP를 기준으로 하겠습니다;&lt;br&gt;&lt;br&gt;&amp;nbsp;여기까지 썼는데도; 또 생소한 용어들이 또 등장했습니다; 하나 하나 설명하자면!&lt;br&gt;우선, 소켓(Socket) - 소켓은 앞서 나열한 A~D까지 나열한 실제 행동을 수행하는 녀석입니다. 결국 클라이언트든, 서버든, 실제로는 소켓이란 녀석이 Bind 되고, Listen을 하고, Connect도 하고, Accept도 합니다. Send와 Receive도 다 소켓이 합니다. 따라서, 굳이 나누자면 서버 프로그램에서 구현한 소켓은 서버 측 소켓, 클라이언트 프로그램에서 구현한 소켓은 클라이언트 측 소켓으로 말 할 수 있습니다.&lt;br&gt;&lt;br&gt;포트(Port) - 포트는 실제 네트워크 상에서 패킷이 오가는 통로입니다. 서버 측 소켓과 클라이언트 측 소켓을 이어주는 하나의 길이라고 생각하면 되겠네요. 몇몇 좋은(?) 회사들은 메신저를 사용하지 못하도록 방화벽으로 차단을 합니다. 이 때 방화벽은 실제로 메신저가 사용하는 포트를 차단함으로써 메신저를 무용지물로 만듭니다; 일반적으로 윈도우즈에서는 1 ~ 65535의 포트가 사용됩니다; 우리가 늘 업무 시간에도 몰래 몰래 하는 인터넷 서핑은 80번,&amp;nbsp; FTP는 21번, MySQL은 3306번을 사용합니다. 이 때 포트는 TCP, UDP 구분을 해서 씁니다; 여기서 중요한 사실은 이미 사용 중인 포트는 다른 소켓에서 사용할 수 없습니다; 따라서; 일반적으로 네트워크 프로그램을 개발할 때는 O/S 및 기존의 잘 알려진 프로그램에서 사용하는 포트가 집중되어 있는 1024번 이후의 포트를 사용합니다.&lt;br&gt;&lt;br&gt;프로토콜(Protocol) - 프로토콜은 사전적 의미 그대로 규약입니다. 예를 들면, 저와 미국 친구가 전화를 하는데; 저는 우리나라 말로 얘기하고, 미국 친구는 영어로 얘기한다면; 정상적인 대화가 될 수가 없습니다; (저는 영어를 모르고, 친구는 우리 말을 모르기 때문이지요.) 네트워크 상에서도 그런 불상사를 막기 위해; 몇 몇 상황에 맞도록 규약(약속)을 만들었는데, 그것이 TCP, UDP 같은 것들입니다. 만약; 서버에서 TCP로 소켓을 생성하여 통신을 하도록 한다면; 당연히 클라이언트도 TCP로 소켓을 생성하여 통신을 해야합니다; TCP나 UDP는 구현 하는 목적에 맞게 쓰면 됩니다; TCP나 UDP에 대해서도 소개하자면; 내용이 많기에 다음 기회로 넘기겠습니다.&lt;br&gt;&lt;br&gt;지금까지 아주 짧게나마; 클라이언트/서버 프로그래밍에서 처음 접하게 되는 기초 개념을 살펴보았습니다.&lt;br&gt;다시 짚고 넘어가자면; 클라이언트/서버 프로그램에서 가장 중요한 핵심은 소켓이고; 소켓을 통해 클라이언트와 서버가 통신 하기 까지는 A~D 과정을 통해서 이루어진다는 사실을 기억해야 합니다. 그리고, 포트와 프로토콜에 대해서도 간략히 살펴보았네요;&lt;br&gt;&lt;br&gt;다음 아티클에서는 소켓과 프로토콜을 실제 코드를 통해 좀 더 기술할 수 있도록 하겠습니다;&lt;br&gt;&lt;fieldset style=&quot;margin:20px 0px 20px 0px;padding:5px;&quot;&gt;&lt;legend&gt;&lt;span&gt;&lt;strong&gt;크리에이티브 커먼즈 라이센스&lt;/strong&gt;&lt;/span&gt;&lt;/legend&gt;&lt;!--Creative Commons License--&gt;&lt;div style=&quot;float: left; width: 88px; margin-top: 3px;&quot;&gt;&lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;&lt;img alt=&quot;Creative Commons License&quot; style=&quot;border-width: 0&quot; src=&quot;http://i.creativecommons.org/l/by-nc-nd/2.0/kr/88x31.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: 92px; margin-top: 3px; text-align: justify;&quot;&gt;이 저작물은 &lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스&lt;/a&gt;에 따라 이용하실 수 있습니다.
			&lt;!-- Creative Commons License--&gt;
			&lt;!-- &lt;rdf:RDF xmlns=&quot;http://web.resource.org/cc/&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;&gt;
			&lt;Work rdf:about=&quot;&quot;&gt;
			&lt;license rdf:resource=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; /&gt;
			&lt;/Work&gt;
			&lt;License rdf:about=&quot;http://creativecommons.org/licenses/by-nc-nd/&quot;&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Reproduction&quot;/&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Distribution&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Notice&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Attribution&quot;/&gt;&lt;prohibits rdf:resource=&quot;http://web.resource.org/cc/CommercialUse&quot;/&gt;&lt;/License&gt;&lt;/rdf:RDF&gt; --&gt;&lt;/div&gt;&lt;/fieldset&gt;</summary>
  </entry>
  <entry>
    <title type="html">[C#] 비동기 소켓을 이용한 프로그래밍(Asynchronous Socket)</title>
    <link rel="alternate" type="text/html" href="http://www.nohungry.net/tt1/160" />
    <link rel="replies" type="application/atom+xml" href="http://www.nohungry.net/tt1/atom/response/160" thr:count="8"/>
    <category term=".NET" />
    <category term="C#" />
    <category term="라이브러리" />
    <category term="비동기 소켓 프로그래밍" />
    <author>
      <name>(노헝그리)</name>
    </author>
    <id>http://www.nohungry.net/tt1/160</id>
    <updated>2010-03-05T16:39:16+09:00</updated>
    <published>2010-03-05T16:39:10+09:00</published>
    <summary type="html">Win32 API나 MFC와 마찬가지로 .NET Framework에서도 비동기 방식으로 소켓 통신을 하기 위한 방법을 제공한다. 그 방법은 MSDN 내에 &lt;a href=&quot;http://msdn.microsoft.com/ko-kr/library/5w7b7x5f%28VS.80%29.aspx&quot; target=&quot;_blank&quot;&gt;비동기 서버 소켓&lt;/a&gt; 사용과 &lt;a href=&quot;http://msdn.microsoft.com/ko-kr/library/bbx2eya8%28VS.80%29.aspx&quot; target=&quot;_blank&quot;&gt;비동기 클라이언트 소켓&lt;/a&gt; 사용에 관한 아티클에 상세하게 소개 되어 있다.&lt;br&gt;&lt;br&gt;이 글에서 소개하고자 하는 AsyncSocketClient와 AsyncSocketServer는 .NET Framework에서 제공하는 비동기 소켓을 좀 더 사용하기 쉽게 만든 일종의 Wrapper 라이브러리라고 할 수 있다. 물론, .NET Framework 자체에서 소켓을 좀 더 고수준화한 TcpClient와 TcpListener란 클래스도 제공하지만; 제약이 많다;&lt;br&gt;&lt;br&gt;물론, Socket에서 제공하는 모든 부분까지 구현한 것은 아니고; Connect, Close, Send, Receive, Accept 정도만 제공하는 것으로 소스를 공개함으로써 누구나 수정, 재배포가 가능하도록 하였다(다시 말해서; 자기가 필요한 부분은 추가로 구현해서 써도 상관없다.); 하지만, 가급적이면 저의 흔적을 말살하지 않기를..ㅠㅠ; &lt;br&gt;&lt;br&gt;아, 그리고 이 라이브러리는 100% TCP 기반으로 구현되어 있다; UDP는 제공하지 않는다;&lt;br&gt;&lt;br&gt;이 라이브러리가 .NET Framework에서 제공하는 소켓 클래스보다 편리한 부분은 소켓에서 발생하는 Connect, 
Close, Accept, Error, Send, Receive 등을 이벤트화 하였기에; 폼이나 다른 클래스에서 소켓을 핸들링 
하는 것이 쉬워졌다; 다시 말해서, 폼이나 클래스에서 이벤트 핸들러만 재정의하면 소켓 이벤트를 처리할 수 있다;&lt;br&gt;&lt;br&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1016960824.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;580&quot; width=&quot;408&quot; /&gt;&lt;/div&gt;&lt;br&gt;위 그림에서 알 수 있듯이, 본 라이브러리는 기본적으로 AsyncSocketClass란 하나의 부모 클래스와 클라이언트 소켓 파트를 구현한 AsyncSocketClient, 서버 소켓 파트를 구현한 AsyncSocketServer로 이루어져 있다;&lt;br&gt;&lt;br&gt;자식 클래스들을 좀 더 자세히 살펴보면 다음과 같다;&lt;br&gt;&lt;br&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1127696378.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;488&quot; width=&quot;413&quot; /&gt;&lt;/div&gt;AsyncSocketClient는 public method로 Connect, Close, Send, Receive가 지원된다; 하지만; Receive는 특수한 경우를 제외하고는 개발자가 직접 호출할 필요는 없다; (이 부분은 나중에 좀 더 자세하게 설명하도록 한다..) 왜냐하면; 기본적으로 연결이 성공하면 데이터 수신을 위해 자동적으로 수신 대기 상태가 되기 때문이다;&lt;br&gt;&lt;br&gt;만약, 데이터 수신을 성공하면, OnReceive 이벤트를 재정의 하여, 이 이벤트 핸들러에서 수신한 데이터를 지지고 볶고 하면 된다.OnConnect, OnClose, OnSend 모두 같다;&lt;br&gt;&lt;br&gt;아래는 AsyncSocketClient를 이용해 구현한 샘플 프로그램의 코드 일부(이벤트 재정의 부분)이다. &lt;br&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1112517765.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;406&quot; width=&quot;568&quot; /&gt;&lt;/div&gt;&lt;br&gt;여기서 중요한 것은 AsyncSocketClient 생성자의 인자로 숫자 0이 들어갔는데; 이는 다수의 AsyncSocketClient 인스턴스들을 생성을 가졍했을 때, 각각을 식별하기 위한 ID라고 할 수 있다.&lt;br&gt;&lt;br&gt;그리고 그 아래 OnConnect 이벤트 핸들러가 있는데; &lt;br&gt;인자로 object sender와 AsyncSocketConnectionEventArgs e가 들어간다.&lt;br&gt;&lt;br&gt;sender는 AsyncSocketClient로 캐스팅해서 쓰면, 이벤트가 발생한 소켓 클라이언트 자신이다;&lt;br&gt;(AsyncSocketClient worker = (AsyncSocketClient)sender;)&lt;br&gt;&lt;br&gt;AsyncSocketConnectionEventArgs는 이벤트가 발생한 소켓 클라이언트의 ID 등을 포함하고 있다;&lt;br&gt;&lt;br&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1284920337.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;80&quot; width=&quot;600&quot; /&gt;&lt;/div&gt;&lt;br&gt;OnReceive를 살펴보면 넘어오는 Event 인자가 소켓의 ID, 수신한 바이트 수(ReceivedBytes), 수신한 데이터(ReceivedData)가 포함되어 있음을 알 수 있다. 참고로 위의 코드는 수신한 데이터가 byte[] 타입이기 때문에, string으로 캐스팅하기 위한 Encoding.... 코드가 포함되어 있다.&lt;br&gt;&lt;br&gt;그 다음 AsyncSocketServer로 넘어가면;&lt;br&gt;&lt;br&gt;AsyncSocketServer는 public method로 Listen, Stop이 지원된다; 만약 Client의 접근이 Accept 되면, OnAccept 이벤트가 발생하므로, OnAccept 이벤트를 재정의 하여, Client를 처리하면 된다;&lt;br&gt;&lt;br&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1024834987.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;324&quot; width=&quot;478&quot; /&gt;&lt;/div&gt;&lt;br&gt;AsyncSocketServer에서 가장 중요한 부분은 클라이언트 소켓의 접속을 처리하는 OnAccept 부분이다.&lt;br&gt;&lt;br&gt;OnAccept에서 넘어오는 Event 인자는 접속이 허가된 소켓(e.Worker) 인스턴스가 포함되어 있다;&lt;br&gt;&lt;br&gt;따라서, OnAccept 이벤트 핸들러에서는 AsyncSocketClient를 그대로 이용하기 위해, 이벤트 핸들러 내의&lt;br&gt;첫 줄과 같은 코드가 필요하다; 또한; 클라이언트의 ID가 중복되지 않도록, 새로운 ID도 부여한다.&lt;br&gt;&lt;br&gt;그리고 그 다음이 앞서 언급한 AsyncSocketClient가 Receive를 호출해야할 특수한 상황이다; &lt;br&gt;구현 방법에 따라서; 이 부분은 Accept 코드 내에서 처리할 수도 있었지만; 어짜피 개발자가 이벤트 핸들러 연결도 필요하기 때문에; 그냥 이렇게 구현하였다.&lt;br&gt;&lt;br&gt;끝으로 새로 생성한 클라이언트 소켓들을 미리 정의한 이벤트 핸들러와 연결하는 코드들이 나오고;&lt;br&gt;끝으로 클라이언트 리스트에 Add한다. (다수의 클라이언트 접속 가능 예를 들기 위해서 이렇게 했음);&lt;br&gt;&lt;br&gt;좀 더 편리한 개발을 위해서는; MSDN 수준의 Class Specification을 쓰고 싶었지만; 시간 및 기타 여건이 허락되지 않는 관계로 이만 줄임!&lt;br&gt;&lt;br&gt;대신에 라이브러리 및 예제 소스를 공개하니; 이를 이용하면 되지 않을까... 무책임하게 생각해봅니다;&lt;br&gt;&lt;br&gt;다운로드: &lt;a href=&quot;http://www.nohungry.net/Data/AsyncSocket.zip&quot; target=&quot;_blank&quot;&gt;http://www.nohungry.net/Data/AsyncSocket.zip&lt;/a&gt;&lt;br&gt;&lt;fieldset style=&quot;margin:20px 0px 20px 0px;padding:5px;&quot;&gt;&lt;legend&gt;&lt;span&gt;&lt;strong&gt;크리에이티브 커먼즈 라이센스&lt;/strong&gt;&lt;/span&gt;&lt;/legend&gt;&lt;!--Creative Commons License--&gt;&lt;div style=&quot;float: left; width: 88px; margin-top: 3px;&quot;&gt;&lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;&lt;img alt=&quot;Creative Commons License&quot; style=&quot;border-width: 0&quot; src=&quot;http://i.creativecommons.org/l/by-nc-nd/2.0/kr/88x31.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: 92px; margin-top: 3px; text-align: justify;&quot;&gt;이 저작물은 &lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스&lt;/a&gt;에 따라 이용하실 수 있습니다.
			&lt;!-- Creative Commons License--&gt;
			&lt;!-- &lt;rdf:RDF xmlns=&quot;http://web.resource.org/cc/&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;&gt;
			&lt;Work rdf:about=&quot;&quot;&gt;
			&lt;license rdf:resource=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; /&gt;
			&lt;/Work&gt;
			&lt;License rdf:about=&quot;http://creativecommons.org/licenses/by-nc-nd/&quot;&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Reproduction&quot;/&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Distribution&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Notice&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Attribution&quot;/&gt;&lt;prohibits rdf:resource=&quot;http://web.resource.org/cc/CommercialUse&quot;/&gt;&lt;/License&gt;&lt;/rdf:RDF&gt; --&gt;&lt;/div&gt;&lt;/fieldset&gt;</summary>
  </entry>
  <entry>
    <title type="html">[C#] Auto FTP Uploader</title>
    <link rel="alternate" type="text/html" href="http://www.nohungry.net/tt1/159" />
    <link rel="replies" type="application/atom+xml" href="http://www.nohungry.net/tt1/atom/response/159" thr:count="0"/>
    <category term=".NET" />
    <category term=".Net Framework 2.0" />
    <category term="C#" />
    <category term="delegate" />
    <category term="FTP" />
    <category term="FtpWebRequest" />
    <category term="ManualResetEvent" />
    <category term="Microsoft Visual Studio 2005" />
    <category term="Monitor" />
    <category term="Thread" />
    <author>
      <name>(노헝그리)</name>
    </author>
    <id>http://www.nohungry.net/tt1/159</id>
    <updated>2010-03-03T15:29:51+09:00</updated>
    <published>2010-03-03T15:29:48+09:00</published>
    <summary type="html">&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1331749408.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;482&quot; width=&quot;600&quot; /&gt;&lt;/div&gt;&lt;br&gt;&amp;nbsp;회사에서 맡은 프로젝트 중... 실시간으로 생성되는 데이터를 원격의 FTP 서버에 전송해야할 일이 생겼다. &lt;br&gt;&lt;br&gt;&amp;nbsp;상용 FTP 클라이언트 프로그램에서 일종의 매크로 기능을 사용하면 이와 같은 기능을 대신할 수 있지만; 상용 프로그램을 쓰는 것도 부담 스럽고; 내가 원하는대로 커스터마이징 하는 것이 불가능해서 그냥 만들었다.&lt;br&gt;&lt;br&gt;Auto FTP Uploader의 로직은 매우 심플하다; 특정 Source Folder를 설정하고, 업로드 할 FTP 주소와 계정 정보를 입력해둔 다. Auto FTP Uploader는 Source Folder의 Rename 이벤트를 감지하여, 이벤트가 발생하면, 원격 FTP 주소에 업로드 한다.&lt;br&gt;&lt;br&gt;&amp;nbsp;Source Folder의 Create 이벤트를 감지할 경우, 파일 작성이 완료되는 시점을 알 수 없으므로, 데이터를 생성하는 부분에서 파일이 작성되는 시간 동안에는 확장자를 TMP로 만들고, 파일 작성이 완료되면 확장자를 DAT로 바꾸게 하였기에 Rename 이벤트를 감지하도록 했다. (Temp Folder와 Complete 폴더는 원격 FTP 서버의 요구 사항에 의해 만든 것으로 파일이 작성되면 원격 FTP 서버에 동일한 파일명의 Dummy File을 업로드 한다.)&lt;br&gt;&lt;br&gt;&amp;nbsp;프로그램 자체는 뭐 특별한 기능은 없지만; .NET Framework를 이용하면 간단한 FTP를 구현하는 것은 일도 아니라는 생각이 든다. 또, C#을 처음 접하는 이들에게는 C#을 이해하는데 도움이 되지 않을까 생각한다.&lt;br&gt;&lt;br&gt;&amp;nbsp;이 프로그램에 사용된 주요 프로그래밍 테크닉은 다음과 같다.&lt;br&gt;&lt;br&gt;&amp;nbsp;1. 파일 입/출력&lt;br&gt;&amp;nbsp;2. FtpWebRequest 클래스의 사용법&lt;br&gt;&amp;nbsp;3. 간단한 Thread의 사용 예&lt;br&gt;&amp;nbsp;4. ManualResetEvent, Monitor를 이용한 동기화 기법&lt;br&gt;&amp;nbsp;5. 델리게이트(delegate)를 이용한 클래스 또는 폼 간의 이벤트 발생 및 전달&lt;br&gt;&lt;br&gt;&amp;nbsp;코멘트가 상세히 포함되어 있지는 않지만; 복잡한 로직은 거의 없고, 가급적 모듈별로 분리하도록 노력하였기 때문에 크게 어려움은 없지 않을까 생각해본다...;&lt;br&gt;&lt;br&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1345065020.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;659&quot; width=&quot;584&quot; /&gt;&lt;/div&gt;&lt;br&gt;&lt;span style=&quot;font-weight: bold; color: rgb(0, 51, 102);&quot;&gt;소스 다운로드 : &lt;/span&gt;&lt;a style=&quot;font-weight: bold; color: rgb(0, 51, 102);&quot; href=&quot;http://www.nohungry.net/Data/FTPUploader.zip&quot; target=&quot;_blank&quot;&gt;http://www.nohungry.net/Data/FTPUploader.zip&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;span style=&quot;color: rgb(212, 26, 1); font-weight: bold;&quot;&gt;수정 및 재배포 자유, 영리적 목적의 사용도 자유! 단, 출처만 밝혀주세요;&lt;/span&gt;&lt;br&gt;&lt;fieldset style=&quot;margin:20px 0px 20px 0px;padding:5px;&quot;&gt;&lt;legend&gt;&lt;span&gt;&lt;strong&gt;크리에이티브 커먼즈 라이센스&lt;/strong&gt;&lt;/span&gt;&lt;/legend&gt;&lt;!--Creative Commons License--&gt;&lt;div style=&quot;float: left; width: 88px; margin-top: 3px;&quot;&gt;&lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;&lt;img alt=&quot;Creative Commons License&quot; style=&quot;border-width: 0&quot; src=&quot;http://i.creativecommons.org/l/by-nc-nd/2.0/kr/88x31.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: 92px; margin-top: 3px; text-align: justify;&quot;&gt;이 저작물은 &lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스&lt;/a&gt;에 따라 이용하실 수 있습니다.
			&lt;!-- Creative Commons License--&gt;
			&lt;!-- &lt;rdf:RDF xmlns=&quot;http://web.resource.org/cc/&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;&gt;
			&lt;Work rdf:about=&quot;&quot;&gt;
			&lt;license rdf:resource=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; /&gt;
			&lt;/Work&gt;
			&lt;License rdf:about=&quot;http://creativecommons.org/licenses/by-nc-nd/&quot;&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Reproduction&quot;/&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Distribution&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Notice&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Attribution&quot;/&gt;&lt;prohibits rdf:resource=&quot;http://web.resource.org/cc/CommercialUse&quot;/&gt;&lt;/License&gt;&lt;/rdf:RDF&gt; --&gt;&lt;/div&gt;&lt;/fieldset&gt;</summary>
  </entry>
  <entry>
    <title type="html">리팩토링(Refactoring) #2</title>
    <link rel="alternate" type="text/html" href="http://www.nohungry.net/tt1/158" />
    <link rel="replies" type="application/atom+xml" href="http://www.nohungry.net/tt1/atom/response/158" thr:count="0"/>
    <category term="Refactoring" />
    <category term="Refactoring" />
    <category term="리팩톨링" />
    <author>
      <name>(노헝그리)</name>
    </author>
    <id>http://www.nohungry.net/tt1/158</id>
    <updated>2010-02-04T13:46:36+09:00</updated>
    <published>2010-02-04T12:41:02+09:00</published>
    <summary type="html">첫 포스팅을 하고 두 달만에 포스팅을 한다는;; 그동안 얼마나 게을렀는가를 스스로 반성.ㅠㅠ 앞으로 두 번의 포스팅에 걸쳐 리팩토링의 정의... 리팩토링을 왜 해야 되고, 리팩토링을 할 때 어려운 점 등을 정리하고; 그 다음부터 실제 기술적인 면을 정리할 생각이다.&lt;br&gt;&lt;br&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;color: rgb(0, 51, 102);&quot;&gt;리팩토링&lt;/span&gt; - 소프트웨어를 보다 쉽게 이해할 수 있고, 적은 비용으로 수정할 수 있도록 겉으로 보이는 동작의 변화 없이 내부 구조를 변경하는 것.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&amp;nbsp;리팩토링은 소프트웨어의 모든 문제점을 해결할 수 있는 방법은 아니지만, 많은 문제점을 해결할 수 있는 유용한 도구가 될 수 있으며, 다양한 목적으로 사용할 수 있다.&lt;br&gt;&lt;br&gt;구체적으로 리팩토링을 적용할 수 있는 사례를 살펴보자면~&lt;br&gt;&lt;br&gt;&lt;span style=&quot;color: rgb(0, 51, 102); font-weight: bold;&quot;&gt;- 리팩토링은 소프트웨어의 디자인을 개선 시킨다.&lt;/span&gt;&lt;br&gt;앞서 얘기 했듯이 단기적인 목적을 이루기 위해서, 또는 코드 전체의 디자인을 제대로 이해하지 못하는 상태에서 코드를 변경할 때, 결국 그 코드는 원래의 구조를 잃을 것이며, 시간이 흐르면 이 효과는 누적되어, 종국에는 어떻게 이도 저도 건드리지 못하는 몬스터가 되는 경우가 발생한다. 정기적인 리팩토링 작업은 이런 문제를 미연에 방지할 수 있으며, 코드의 디자인을 유지하도록 도와준다. 가장 간단한 리팩토링의 예는 중복된 코드를 제거하는 것!&lt;br&gt;&lt;br&gt;&lt;span style=&quot;font-weight: bold; color: rgb(0, 51, 102);&quot;&gt;- 리팩토링은 소프트웨어를 더 이해하기 쉽게 만든다.&lt;/span&gt;&lt;br&gt;굳이 남이 이해하기 쉽도록 이타적인 생각을 할 필요도 없다. 그 대상은 미래의 자신이 될 수도 있다. 아마 누구나 자신이 코딩한 프로그램을 시간이 흘러 다시 봤을 때, 쉽게 이해하지 못하는 경험이 있을 것이다.&lt;br&gt;&lt;br&gt;&lt;span style=&quot;font-weight: bold; color: rgb(0, 51, 102);&quot;&gt;- 리팩토링은 버그를 찾도록 도와준다.&lt;/span&gt;&lt;br&gt;당연한 얘기로 이해하기 쉬운 소프트웨어가 버그를 찾기도 쉽다.&lt;br&gt;&lt;br&gt;&lt;span style=&quot;color: rgb(0, 51, 102); font-weight: bold;&quot;&gt;- 리팩토링은 프로그램을 빨리 작성하도록 도와준다.&lt;/span&gt;&lt;br&gt;개발 이외에 리팩토링을 해야되는데, 그것이 정말 시간을 단축시켜 주는 것일까? 하지만, 정기적인 리팩토링을 통해 코드의 디자인이 유지되고, 코드의 가독성이 높아진다면, 이후 새로운 기능을 추가하거나 기능을 수정 변경할 때 훨씬 수월하다.&lt;br&gt;&lt;br&gt;&amp;nbsp;&lt;span style=&quot;font-weight: bold; color: rgb(255, 0, 0);&quot;&gt;그럼, 언제 리팩토링을 해야될까?&lt;/span&gt;&lt;br&gt;&amp;nbsp;사실 날을 잡고, 리팩토링을 하는 것은 개발자에게 너무 많은 부담이 될 수 있다. (정말 부지런한 사람만이 할 수 있을 것 같다.) &lt;br&gt;&lt;br&gt;&lt;span style=&quot;font-weight: bold; color: rgb(155, 24, 193);&quot;&gt;- 기능을 추가할 때 리팩토링을 하라.&lt;/span&gt;&lt;br&gt;새로운 기능을 추가하는 경우, 지금의 디자인이 기능 추가가 쉽지 않은 디자인일 수 있다. 그 때 아 예전에 디자인을 할 때 이런 식으로 했었다면, 후회를 하지 말고, 새로이 리팩토링을 하라. 그것이 미래에 똑같은 후회를 방지 할 수 있는 방법이다.&lt;br&gt;&lt;br&gt;&lt;span style=&quot;font-weight: bold; color: rgb(155, 24, 193);&quot;&gt;- 버그를 수정할 때 리팩토링을 하라.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style=&quot;color: rgb(155, 24, 193); font-weight: bold;&quot;&gt;- 코드 리뷰를 할 때 리팩토링을 하라.&lt;/span&gt;&lt;br&gt;코드 리뷰는 지식이 개발팀 전체로 확산되는 것을 돕는 좋은 방법이다.&lt;br&gt;&lt;br&gt;리팩토링을 공부하면서, 정말 나에게 뼈져리게 와닿는 내용이 많다. 시간에 쫓겨서란 변명을 일단 급한대로 코딩을 해오다, 시간이 흘러 기능 추가나 수정이 발생했을 때, 정말 후회한 기억이 지금도 새록 새록 난다. 리팩토링의 가장 큰 적은 귀차니즘이다.&lt;br&gt;&lt;fieldset style=&quot;margin:20px 0px 20px 0px;padding:5px;&quot;&gt;&lt;legend&gt;&lt;span&gt;&lt;strong&gt;크리에이티브 커먼즈 라이센스&lt;/strong&gt;&lt;/span&gt;&lt;/legend&gt;&lt;!--Creative Commons License--&gt;&lt;div style=&quot;float: left; width: 88px; margin-top: 3px;&quot;&gt;&lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;&lt;img alt=&quot;Creative Commons License&quot; style=&quot;border-width: 0&quot; src=&quot;http://i.creativecommons.org/l/by-nc-nd/2.0/kr/88x31.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: 92px; margin-top: 3px; text-align: justify;&quot;&gt;이 저작물은 &lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스&lt;/a&gt;에 따라 이용하실 수 있습니다.
			&lt;!-- Creative Commons License--&gt;
			&lt;!-- &lt;rdf:RDF xmlns=&quot;http://web.resource.org/cc/&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;&gt;
			&lt;Work rdf:about=&quot;&quot;&gt;
			&lt;license rdf:resource=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; /&gt;
			&lt;/Work&gt;
			&lt;License rdf:about=&quot;http://creativecommons.org/licenses/by-nc-nd/&quot;&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Reproduction&quot;/&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Distribution&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Notice&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Attribution&quot;/&gt;&lt;prohibits rdf:resource=&quot;http://web.resource.org/cc/CommercialUse&quot;/&gt;&lt;/License&gt;&lt;/rdf:RDF&gt; --&gt;&lt;/div&gt;&lt;/fieldset&gt;</summary>
  </entry>
  <entry>
    <title type="html">리팩토링(Refactoring) #1</title>
    <link rel="alternate" type="text/html" href="http://www.nohungry.net/tt1/157" />
    <link rel="replies" type="application/atom+xml" href="http://www.nohungry.net/tt1/atom/response/157" thr:count="1"/>
    <category term="Refactoring" />
    <category term="Refactoring" />
    <category term="리팩토링" />
    <category term="마틴 파울러" />
    <author>
      <name>(노헝그리)</name>
    </author>
    <id>http://www.nohungry.net/tt1/157</id>
    <updated>2010-02-04T12:22:40+09:00</updated>
    <published>2009-12-07T17:15:46+09:00</published>
    <summary type="html">&lt;p&gt;&amp;nbsp;직장인은 3년차쯤 되면... 슬럼프가 온다고 하는데, 내가 딱 그 모양인 것 같다;&lt;br&gt;할 일은 많은데, 일도 잘 되지 않고; 일을 하더라도 왠지 모르게 어수선하고, 깔끔하지가 못 하다;&lt;br&gt;&lt;br&gt;과연 내 문제는 무엇이고, 해결책은 뭘까... 곰곰히 생각해보다 내린 결론은 공부다; 아무리 일이 바쁘지만...&lt;br&gt;일이 바쁘지 않더라도 마냥 놀다보니 발전이 없다. 늘 하던 짓만 하다보니, 결국 매너리즘에 빠지게 되는 것;&lt;br&gt;&lt;br&gt;그래서 입사 초기에 했던 것 처럼... 한가지 주제를 잡고, 공부를 해보기로 마음을 먹었다; 그래야 내 스스로도&lt;br&gt;발전이 있을게 아닌가;&lt;br&gt;&lt;br&gt;어떤 주제로 공부하는 것이 좋을까... 고민하다; 진즉에 사놓고 읽지 못하고 있던 &lt;strong&gt;&lt;font color=&quot;#003366&quot;&gt;&quot;리팩토링(Refactoriing) - 나쁜 디자인의 코드를 좋은 디자인으로 바꾸는 방법 / 마틴 파울러 저/ 윤성준, 조재박 역&quot;&lt;/font&gt;&lt;/strong&gt;을 대상으로 삼기로 했다.&lt;br&gt;&lt;br&gt;1주일에 하루 정도 날짜를 정해, 한 Chapter씩 읽고, 공부를 했다는 의미를 되살리기 위해 블로그에 요약을 적기로 결정했다;&lt;br&gt;&lt;br&gt;Chapter 1은 간단한 비디오 대여 프로그램의 일부를 가지고, 왜 리팩토링이 필요한가에 대해서 다루고 있다. 저자의 언급대로 간단한 프로그램이고, 재사용성이나 확장성을 염두에 두고 있지 않다면, 리팩토링은 무의미 할 것이다.&lt;br&gt;&lt;br&gt;하지만 학창 시절에 숙제를 위해 만든 프로그램이 아니라면... 대부분의 경우, 확장 또는 재사용성을 당연히 고려해야 마땅하다. 매우 이상적인 경우라면, 프로그램 디자인 단계에서 완벽한 클래스의 구조를 만들어, 정말 읽기 쉽고, 어디든지 붙이기 쉽게 만들 수도 있지만 현실적으로는 불가능하다.&lt;br&gt;&lt;br&gt;프로젝트를 진행하다보면 처음 설계된 프로그램 디자인과 별개로 코딩해 나가면서 맞딱드리는 여러 요인에 의해 시스템 본래의 모습과 디자인을 따른 구조는 점점 사라지고, 결국 완벽한 보안을 갖춘 (경쟁사에서 이 코드를 가져가도 해독이 불가능한...) 코드가 된다.&lt;br&gt;&lt;br&gt;리팩토링은 이러한 관례와 반대로 다소 서투른 디자인을 취해 재작업하여 잘 디자인된 코드를 만드는 과정이라 이해할 수 있다. 각각의 단계는 A 클래스의 멤버 변수를 B 클래스로 옮기거나, 클래스 코드의 일부를 수퍼 클래스나 서브 클래스로 옮기거나 하는 것이다. 이러한 작업들이 모여 근본적으로 디자인을 개선하게 된다.&lt;br&gt;&lt;br&gt;&lt;strong&gt;리팩토링에서 가장 중요한 개념은 내부(코드 및 디자인)를 바꾸면서 외부(기능)을 바꾸지 않는 것이기 때문에, 코드 변경에 문제가 없는지 확인을 위한 강력한 테스트가 필수&lt;/strong&gt;적이다.&lt;br&gt;&lt;br&gt;보다 구체적인 리팩토링 테크닉은 다음에 또 정리하기로 하고, 저자가 1장에서 강조한 말이 기억에 남아 여기도 남기고자 한다.&lt;br&gt;&lt;br&gt;&lt;strong&gt;&lt;em&gt;&lt;font color=&quot;#d41a01&quot;&gt;&quot;컴퓨터가 이해할 수 있는 코드는 어느 바보나 다 짤 수 있다. 좋은 프로그래머는 사람이 이해할 수 있는 코드를 짠다.&quot;&lt;/font&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;fieldset style=&quot;margin:20px 0px 20px 0px;padding:5px;&quot;&gt;&lt;legend&gt;&lt;span&gt;&lt;strong&gt;크리에이티브 커먼즈 라이센스&lt;/strong&gt;&lt;/span&gt;&lt;/legend&gt;&lt;!--Creative Commons License--&gt;&lt;div style=&quot;float: left; width: 88px; margin-top: 3px;&quot;&gt;&lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;&lt;img alt=&quot;Creative Commons License&quot; style=&quot;border-width: 0&quot; src=&quot;http://i.creativecommons.org/l/by-nc-nd/2.0/kr/88x31.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: 92px; margin-top: 3px; text-align: justify;&quot;&gt;이 저작물은 &lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스&lt;/a&gt;에 따라 이용하실 수 있습니다.
			&lt;!-- Creative Commons License--&gt;
			&lt;!-- &lt;rdf:RDF xmlns=&quot;http://web.resource.org/cc/&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;&gt;
			&lt;Work rdf:about=&quot;&quot;&gt;
			&lt;license rdf:resource=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; /&gt;
			&lt;/Work&gt;
			&lt;License rdf:about=&quot;http://creativecommons.org/licenses/by-nc-nd/&quot;&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Reproduction&quot;/&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Distribution&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Notice&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Attribution&quot;/&gt;&lt;prohibits rdf:resource=&quot;http://web.resource.org/cc/CommercialUse&quot;/&gt;&lt;/License&gt;&lt;/rdf:RDF&gt; --&gt;&lt;/div&gt;&lt;/fieldset&gt;</summary>
  </entry>
  <entry>
    <title type="html">EP 3. 이게 물고기야... 짐승이야....</title>
    <link rel="alternate" type="text/html" href="http://www.nohungry.net/tt1/156" />
    <link rel="replies" type="application/atom+xml" href="http://www.nohungry.net/tt1/atom/response/156" thr:count="3"/>
    <category term="어류생활" />
    <category term="각시붕어" />
    <category term="쌀미꾸리" />
    <category term="어류 생활" />
    <category term="칼납자루" />
    <author>
      <name>(노헝그리)</name>
    </author>
    <id>http://www.nohungry.net/tt1/156</id>
    <updated>2009-12-07T16:50:19+09:00</updated>
    <published>2009-12-04T12:29:15+09:00</published>
    <summary type="html">&lt;DIV style=&quot;TEXT-ALIGN: center&quot;&gt;&lt;object type=&#039;application/x-shockwave-flash&#039; width=&quot;502&quot; height=&quot;399&quot; align=&#039;middle&#039; classid=&#039;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&#039; codebase=&#039;http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0&#039;&gt;&lt;param name=&#039;movie&#039; value=&#039;http://flvs.daum.net/flvPlayer.swf?vid=G6tFimrjuTk$&#039; /&gt;&lt;param name=&#039;allowScriptAccess&#039; value=&#039;always&#039; /&gt;&lt;param name=&#039;allowFullScreen&#039; value=&#039;true&#039; /&gt;&lt;param name=&#039;bgcolor&#039; value=&#039;#000000&#039; /&gt;&lt;embed src=&#039;http://flvs.daum.net/flvPlayer.swf?vid=G6tFimrjuTk$&#039; width=&quot;502&quot; height=&quot;399&quot; allowScriptAccess=&#039;always&#039; type=&#039;application/x-shockwave-flash&#039; allowFullScreen=&#039;true&#039; bgcolor=&#039;#000000&#039; &gt;&lt;/embed&gt;&lt;/object&gt;&lt;/DIV&gt;&lt;BR&gt;&amp;nbsp;내 방에 수조를 놓고, 생선들을 풀어놓은지도 어언 3주가 지났다; 은근히 신경 써줘야 할 것들이 많아, 여간 귀찮은 일이 아니지만... 그래도 아직은 참을만 하다;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;내 수조에서 살고 있는 어종은 총 3가지로 캅납자루, 각시붕어, 쌀미꾸리가 그 주인공이다. &lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1159586184.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;399&quot; width=&quot;600&quot; /&gt;&lt;/div&gt; 
&lt;DIV style=&quot;TEXT-ALIGN: center&quot;&gt;[사진 출처: encyber.com]&lt;BR&gt;&lt;/DIV&gt;&lt;BR&gt;내 수조의 주인공인 칼납자루는 사진에서 볼 수 있듯이 붕어를 닮았다; 한마디로 말해서 돼지같은 식성을 지녔다. 자연에서의 칼납자루는 보통 겁이 많아, 사람을 보면 잘 숨는다고 하는데... 우리집 애들은 내가 수조로 다가가면 밥을 줄 것이라 생각하는지 돌 틈에서 기어나온다.&lt;BR&gt;&amp;nbsp; 
&lt;DIV&gt;그리고 가끔 이것들이 거칠게 수조를 돌아다녀 수초가 뽑히는 일이 생기는데, 내가 수초를 다시 심기 위해 수조에 손을 집어넣어도 도망도 안간다. 특히, 먹이를 넣어준 상태라면 먹이 먹느라도 내가 손을 집어 넣었는지도 모르는 것 같다.&lt;BR&gt;&lt;BR&gt;그런데 얘네들도 영리하다고 해야할지... 나랑 마찬가지로 생선을 키우는 울 팀 차장님께 분양 해드리려고 2마리를 건지려고 뜰채를 넣으니 안 잡히려고 도망 다녀서.. 잡느라고 진땀을 뺐다-_-&lt;BR&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1346218699.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;399&quot; width=&quot;600&quot; /&gt;&lt;/div&gt; &lt;/DIV&gt;
&lt;DIV style=&quot;TEXT-ALIGN: center&quot;&gt;[사진 출처: encyber.com]&lt;/DIV&gt;&lt;BR&gt;&amp;nbsp;각시 붕어는 레알 붕어의 사촌 동생쯤 되는 녀석인데...; 크기는 4cm 정도 된다; 칼납자루랑 마찬가지로 사실 수조 바닥층에 가까이 살며... 바닥에 떨어졌거나 아래 쪽으로 가라앉는 먹이를 잘 먹는데..; 가끔 내가 장난 삼아 얘네들이 좋아하는 냉짱(냉동 장구벌레)을 녹여서 젓가락으로 집은 다음 수면 가까이 가져가면... 수면 위를 점프해서 물고 간다. (요즘 내가 이런 재롱을 보는 재미로 비싼 냉동짱구를 먹인다.-_-)&lt;BR&gt;&lt;BR&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1311427558.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;401&quot; width=&quot;600&quot; /&gt;&lt;/div&gt; 
&lt;DIV style=&quot;TEXT-ALIGN: center&quot;&gt;[사진 출처: encyber.com]&lt;BR&gt;&lt;BR&gt;
&lt;DIV style=&quot;TEXT-ALIGN: left&quot;&gt;&amp;nbsp;끝으로 쌀미꾸리는 수조의 청소부쯤 된다. 바닥에 떨어진 먹이 찌거기들을 주로 먹고 사는데...; 우리집 먹보들 칼납자루와 각시붕어들이 먹이가 바닥에 떨어질 틈을 주지 않아...; 맨날 쫄쫄 굶는 것 처럼 보인다;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;그리고 각시붕어나 칼납자루에 비해 느려 늘 먹이 경쟁에서 뒤쳐져... 나의 안타까움을 사던 차에.. 냉짱을 주니.. 이것들이 알아서 수면 위로 올라와 먹이를 찾는다. 생존 본능이랠까...?&lt;BR&gt;&lt;BR&gt;&amp;nbsp;다음 포스팅에는 내가 젓가락으로 먹이를 주면 그걸 물고 가는 재롱 잔치를 동영상으로 찍어서 한 번 올려야겠다;&lt;/DIV&gt;&lt;/DIV&gt;&lt;fieldset style=&quot;margin:20px 0px 20px 0px;padding:5px;&quot;&gt;&lt;legend&gt;&lt;span&gt;&lt;strong&gt;크리에이티브 커먼즈 라이센스&lt;/strong&gt;&lt;/span&gt;&lt;/legend&gt;&lt;!--Creative Commons License--&gt;&lt;div style=&quot;float: left; width: 88px; margin-top: 3px;&quot;&gt;&lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;&lt;img alt=&quot;Creative Commons License&quot; style=&quot;border-width: 0&quot; src=&quot;http://i.creativecommons.org/l/by-nc-nd/2.0/kr/88x31.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: 92px; margin-top: 3px; text-align: justify;&quot;&gt;이 저작물은 &lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스&lt;/a&gt;에 따라 이용하실 수 있습니다.
			&lt;!-- Creative Commons License--&gt;
			&lt;!-- &lt;rdf:RDF xmlns=&quot;http://web.resource.org/cc/&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;&gt;
			&lt;Work rdf:about=&quot;&quot;&gt;
			&lt;license rdf:resource=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; /&gt;
			&lt;/Work&gt;
			&lt;License rdf:about=&quot;http://creativecommons.org/licenses/by-nc-nd/&quot;&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Reproduction&quot;/&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Distribution&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Notice&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Attribution&quot;/&gt;&lt;prohibits rdf:resource=&quot;http://web.resource.org/cc/CommercialUse&quot;/&gt;&lt;/License&gt;&lt;/rdf:RDF&gt; --&gt;&lt;/div&gt;&lt;/fieldset&gt;</summary>
  </entry>
  <entry>
    <title type="html">EP 2. 수조 데코레이션</title>
    <link rel="alternate" type="text/html" href="http://www.nohungry.net/tt1/155" />
    <link rel="replies" type="application/atom+xml" href="http://www.nohungry.net/tt1/atom/response/155" thr:count="11"/>
    <category term="어류생활" />
    <category term="수조 꾸미기" />
    <category term="어류 생활" />
    <author>
      <name>(노헝그리)</name>
    </author>
    <id>http://www.nohungry.net/tt1/155</id>
    <updated>2009-11-23T16:32:28+09:00</updated>
    <published>2009-11-23T10:29:54+09:00</published>
    <summary type="html">2009년 11월 19일&lt;BR&gt;EP 2. 수조 데코레이션;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;수조를 결제하고 무려; 6일이 지나서야 수조와 수초가 왔다; 수조 재고가 없어서 늦었다는 직원의 이야기에 잠시 분노가 치솟았지만; 난 지성인이니까... 참기로 했다; &lt;BR&gt;&lt;BR&gt;&amp;nbsp;수조 꾸미기의 난관은 처음부터 시작되었다; 수조 꾸미기에 필요한 각종 도구와 모래 등등을 다 합치니 무게가 꽤 만만치 않은 것이다; 거기다... 택배를 받은 곳이 회사인지라...; 퇴근 후, 들고 가는데 팔이 빠지는 고통을 느꼈다.&lt;BR&gt;&lt;BR&gt;&amp;nbsp;집에 도착한 후, 가장 먼저 한 작업은 우선 수조를 씻는 일이었다. 이 때, 중요한 것은 세제로 빡빡 문지르는 것이 아니라...; 수돗물로 깨끗이 헹궈야 한다; 혹시...; 수조에 상처가 생기면 안되니까-ㅁ-; 그런 다음 수조를 한 쪽 구석에 젖혀두고, 바닥재를 씻었다. 바닥재는 흑사 1포 반과 금사 반포(1mm 이하의 고운 모래)를 사용했다. 금사를 사용한 이유는 미꾸리나 모래 무지를 키울 수도 있기 때문에... 걔네들을 고려해 질렀다;&lt;BR&gt;&amp;nbsp;바닥재 역시... 세제가 아닌 쌀 씻듯이 물로만 헹궈냈다; 그런 다음.. 수조에 바닥재를 5cm 두께 정도로 깔고..&lt;BR&gt;수조를 장식할 돌멩이 등등을 깨끗이 씻은 다음 배치를 한 후, 책상 위에 수조를 놓았다;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;이제, 수조에 물을 채울 시간인데; 내 수조에는 약 45리터의 물이 필요한데... 이 물을 채워서 수조를 옮길 경우, 수조의 무게가 모래 및 장식품을 합쳐 대략 50kg가 넘기 때문에; 무리하지 않기로 했다. 그래서 물은 노가다지; 1.5리터 패트병에 넣어서 30번 왕복하는 수고를 했다.&lt;BR&gt;&lt;BR&gt;&amp;nbsp;이 때 유의할 점은... 물을 채울 때 손등을 이용해 물이 떨어지는 충격 에너지를 한 번 흡수해주는 것이 키포인트다. 그렇지 않으면.. 기껏 골라놓은 바닥도 패이고; 장식도 나자빠지는 사태가 발생한다;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;물을 채운 이후에 수초를 심었는데...; 이 때 대충 심으면... 물고기들에 의해 다 뽑힐 수가 있기 때문에; 깊숙히 잘... 심어야 한다; 그리고, 여과기 달고, 히터를 설치하고, 수질을 안정시키기 위해 아쿠아 플러스랑 사이클러를 투입했다.&lt;BR&gt;&lt;BR&gt;&amp;nbsp;대략, 한자반짜리 수조의 경우, 한 뚜껑 정도로 넣어주면 된다길래; 그렇게 했다. 끝으로 조명까지 설치하고.. 시계를 보니 대략 4시간 가까이 소요되었다-ㅁ-;&lt;BR&gt;&lt;BR&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://www.nohungry.net/tt1/attach/1/1157521501.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;452&quot; width=&quot;600&quot; /&gt;&lt;p class=&quot;cap1&quot;&gt;완성된 수조의 모습;&lt;/p&gt;&lt;/div&gt;&lt;BR&gt;참 힘들었다;&lt;fieldset style=&quot;margin:20px 0px 20px 0px;padding:5px;&quot;&gt;&lt;legend&gt;&lt;span&gt;&lt;strong&gt;크리에이티브 커먼즈 라이센스&lt;/strong&gt;&lt;/span&gt;&lt;/legend&gt;&lt;!--Creative Commons License--&gt;&lt;div style=&quot;float: left; width: 88px; margin-top: 3px;&quot;&gt;&lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;&lt;img alt=&quot;Creative Commons License&quot; style=&quot;border-width: 0&quot; src=&quot;http://i.creativecommons.org/l/by-nc-nd/2.0/kr/88x31.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: 92px; margin-top: 3px; text-align: justify;&quot;&gt;이 저작물은 &lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스&lt;/a&gt;에 따라 이용하실 수 있습니다.
			&lt;!-- Creative Commons License--&gt;
			&lt;!-- &lt;rdf:RDF xmlns=&quot;http://web.resource.org/cc/&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;&gt;
			&lt;Work rdf:about=&quot;&quot;&gt;
			&lt;license rdf:resource=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; /&gt;
			&lt;/Work&gt;
			&lt;License rdf:about=&quot;http://creativecommons.org/licenses/by-nc-nd/&quot;&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Reproduction&quot;/&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Distribution&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Notice&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Attribution&quot;/&gt;&lt;prohibits rdf:resource=&quot;http://web.resource.org/cc/CommercialUse&quot;/&gt;&lt;/License&gt;&lt;/rdf:RDF&gt; --&gt;&lt;/div&gt;&lt;/fieldset&gt;</summary>
  </entry>
  <entry>
    <title type="html">EP 1. 어류 생활을 위한 지름신 강림</title>
    <link rel="alternate" type="text/html" href="http://www.nohungry.net/tt1/154" />
    <link rel="replies" type="application/atom+xml" href="http://www.nohungry.net/tt1/atom/response/154" thr:count="0"/>
    <category term="어류생활" />
    <category term="수조 꾸미기" />
    <category term="어류 생활" />
    <author>
      <name>(노헝그리)</name>
    </author>
    <id>http://www.nohungry.net/tt1/154</id>
    <updated>2009-11-23T10:14:37+09:00</updated>
    <published>2009-11-23T10:14:37+09:00</published>
    <summary type="html">&lt;DIV style=&quot;TEXT-ALIGN: left&quot;&gt;&amp;nbsp;문득 책상 위에 서로를 벗삼아 너무 난잡하게 누워 있는 책들과 가뜩이나 좁아터진 책상 위를 메우고 있는 모니터와 PC의 본체의 꼬라지들이 차마 볼 수가 없어; 나도 나름의 방식으로 내 방을 새로이 정리할 필요가 있다고 느꼈다;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;그리고 내 방에 무언가 큰 변화를 주는 동시에 최근 스스로가 느끼게 된 나의 정서 불안을 어떻게 좀 가다듬을 방법을 찾던 중... 결심한 것이 바로.. 수조 꾸미기 &amp;amp; 어류 사육이다!! 두둥...&lt;BR&gt;&lt;BR&gt;&amp;nbsp;황씨랑 열정이 말하길, 혼자 사는 남자가 무슨 생선 키우는 꼬라지는 참 볼만하겠다며, 부정적 의사를 나타냈지만; 어짜피 이 인간들의 의견은 나에게 전혀 고려 사항이 아니었기에 내 맘대로 걍 질렀다; 그리고 세나는 내 고집을 말리려고 했지만... 이내 포기했다.&lt;BR&gt;&lt;BR&gt;&amp;nbsp;하지만... 나의 이런 돈지.랄이 낭비가 되지 않도록 하기 위해서... 나름의 사육 일기와 경험담을 써보기로 했다. 두둥..&lt;BR&gt;&lt;BR&gt;&amp;nbsp;2009년 11월 13일 &lt;BR&gt;&amp;nbsp;EP 1. 수조 꾸미기를 위한 지름신 강림;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;처음부터 내가 방을 꾸미기 위한 키포인트로 수조를 생각한 것은 절대 아니었다; 그러다 우연히 눈에 띄인 것이 울 팀 차장님이 책상 위에 질러놓은 수조와 물고기! &quot;그래 이거야!&quot; 나는 바로 점심 시간 때 결심하고, 바로 쇼핑에 들어갔다;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;나는 단지 수조에 물고기만 키운다는 단순한 생각(?)을 탈피하고... 수초와 물고기를 같이 키우기로 결심했다; 그리고 쇼핑을 시작했는데... 헉-ㅁ-; 생각보다 비용이 만만치 않았다.&lt;BR&gt;&lt;BR&gt;&amp;nbsp;내가 1차 지름에서 소요한 비용은 다음과 같다.&lt;BR&gt;&amp;nbsp;물고기와 수초를 키우기 위한 Kellan 수조(45 * 32 * 30) : 47,000원&lt;BR&gt;&amp;nbsp;물고기의 배설물을 제거하기 위한 여과기: 12,000원&lt;BR&gt;&amp;nbsp;한 겨울에도 물고기와 수초가 살기 적합한 온도를 유지하기 위한 히터: 11,500원&lt;BR&gt;&amp;nbsp;초보자가 키우기 쉬운 수초 5종 세트: 12,000원&lt;BR&gt;&amp;nbsp;수조 바닥에 깔기 위한 바닥재 흑사 2포: 8,000원&lt;BR&gt;&amp;nbsp;물갈이를 할 때 물고기를 낚을(?) 뜰채&quot; 4,000원&lt;BR&gt;&amp;nbsp;수초에 필요한 빛을 공급하기 위한 조명: 17,000원&lt;BR&gt;&amp;nbsp;수조에 산소를 공급하기 위한 산소기: 9,000원&lt;BR&gt;&amp;nbsp;수조의 온도를 측정하기 위한 온도계: 5,000원&lt;BR&gt;&amp;nbsp;수조에 공급할 수돗물의 중금속 성분 및 염소 등을 제거하기 위한 싸이클 아쿠아 플러스 세트: 12,000원&lt;BR&gt;&amp;nbsp;내가 맘에 들어하는 수조 펄글라서: 3,000원&lt;BR&gt;&amp;nbsp;수초에 공급할 액체 비료: 13,000원&lt;BR&gt;&lt;BR&gt;&amp;nbsp;덜덜덜-ㅁ-; 아직 물고기도 사지 않은 채로 150,500원을 썼다;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;그리고 며칠 뒤; 수초에 공급할 조명의 광량이 부족한 나머지 추가 구입: 17,000원&lt;BR&gt;&amp;nbsp;수초의 광합성에 필수적인 CO2를 위한 캔 및 디퓨터 세트: 18,000원&lt;BR&gt;&lt;BR&gt;&amp;nbsp;그래서.. 추가로 35,000원을 더 질렀다;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;하지만 아직 물고기는 사지 않았다;&lt;/DIV&gt;&lt;fieldset style=&quot;margin:20px 0px 20px 0px;padding:5px;&quot;&gt;&lt;legend&gt;&lt;span&gt;&lt;strong&gt;크리에이티브 커먼즈 라이센스&lt;/strong&gt;&lt;/span&gt;&lt;/legend&gt;&lt;!--Creative Commons License--&gt;&lt;div style=&quot;float: left; width: 88px; margin-top: 3px;&quot;&gt;&lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;&lt;img alt=&quot;Creative Commons License&quot; style=&quot;border-width: 0&quot; src=&quot;http://i.creativecommons.org/l/by-nc-nd/2.0/kr/88x31.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: 92px; margin-top: 3px; text-align: justify;&quot;&gt;이 저작물은 &lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스&lt;/a&gt;에 따라 이용하실 수 있습니다.
			&lt;!-- Creative Commons License--&gt;
			&lt;!-- &lt;rdf:RDF xmlns=&quot;http://web.resource.org/cc/&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;&gt;
			&lt;Work rdf:about=&quot;&quot;&gt;
			&lt;license rdf:resource=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; /&gt;
			&lt;/Work&gt;
			&lt;License rdf:about=&quot;http://creativecommons.org/licenses/by-nc-nd/&quot;&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Reproduction&quot;/&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Distribution&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Notice&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Attribution&quot;/&gt;&lt;prohibits rdf:resource=&quot;http://web.resource.org/cc/CommercialUse&quot;/&gt;&lt;/License&gt;&lt;/rdf:RDF&gt; --&gt;&lt;/div&gt;&lt;/fieldset&gt;</summary>
  </entry>
  <entry>
    <title type="html">Stack overflow</title>
    <link rel="alternate" type="text/html" href="http://www.nohungry.net/tt1/153" />
    <link rel="replies" type="application/atom+xml" href="http://www.nohungry.net/tt1/atom/response/153" thr:count="2"/>
    <category term="신변잡기" />
    <category term="나를 죽일셈인가?" />
    <category term="신변잡기" />
    <author>
      <name>(노헝그리)</name>
    </author>
    <id>http://www.nohungry.net/tt1/153</id>
    <updated>2009-10-30T15:54:09+09:00</updated>
    <published>2009-10-30T15:54:07+09:00</published>
    <summary type="html">&lt;P&gt;월요일 주간 회의를 통해 나온... 우리 기술2팀이 연말까지 수행해야할 프로젝트 리스트가 나왔다.&lt;BR&gt;&lt;BR&gt;2달 가량 남은 올해까지 해야할 업무들이 대략 12개... 그 중 내가 메인이든... 곁다리든... 해야할 Job들이&lt;BR&gt;&lt;BR&gt;9개나 된다ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ; &lt;BR&gt;&lt;BR&gt;&amp;nbsp;연초부터 진행되던 장기성 프로젝트들도 있고... 중간 중간 갑자기... 불쑥 내 Job이 되어 버린 것들도 있다.&lt;BR&gt;&lt;BR&gt;뭐... 상당 수의 프로젝트들은 8~90% 완성된 녀석들이지만... 화룡점정이란 말도 있듯이... 마무리가 중요하기&lt;BR&gt;&lt;BR&gt;때문에... 더 골치가 아프다.&lt;BR&gt;&lt;BR&gt;&amp;nbsp;오... 신이시여... 왜 나를 이렇게나 시험하나이까;&lt;/P&gt;&lt;fieldset style=&quot;margin:20px 0px 20px 0px;padding:5px;&quot;&gt;&lt;legend&gt;&lt;span&gt;&lt;strong&gt;크리에이티브 커먼즈 라이센스&lt;/strong&gt;&lt;/span&gt;&lt;/legend&gt;&lt;!--Creative Commons License--&gt;&lt;div style=&quot;float: left; width: 88px; margin-top: 3px;&quot;&gt;&lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;&lt;img alt=&quot;Creative Commons License&quot; style=&quot;border-width: 0&quot; src=&quot;http://i.creativecommons.org/l/by-nc-nd/2.0/kr/88x31.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: 92px; margin-top: 3px; text-align: justify;&quot;&gt;이 저작물은 &lt;a rel=&quot;license&quot; href=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; target=_blank&gt;크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스&lt;/a&gt;에 따라 이용하실 수 있습니다.
			&lt;!-- Creative Commons License--&gt;
			&lt;!-- &lt;rdf:RDF xmlns=&quot;http://web.resource.org/cc/&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;&gt;
			&lt;Work rdf:about=&quot;&quot;&gt;
			&lt;license rdf:resource=&quot;http://creativecommons.org/licenses/by-nc-nd/2.0/kr/&quot; /&gt;
			&lt;/Work&gt;
			&lt;License rdf:about=&quot;http://creativecommons.org/licenses/by-nc-nd/&quot;&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Reproduction&quot;/&gt;
			&lt;permits rdf:resource=&quot;http://web.resource.org/cc/Distribution&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Notice&quot;/&gt;
			&lt;requires rdf:resource=&quot;http://web.resource.org/cc/Attribution&quot;/&gt;&lt;prohibits rdf:resource=&quot;http://web.resource.org/cc/CommercialUse&quot;/&gt;&lt;/License&gt;&lt;/rdf:RDF&gt; --&gt;&lt;/div&gt;&lt;/fieldset&gt;</summary>
  </entry>
</feed>

