<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
>

<channel>
	<title>EMSTONE Bebop &#187; Agile</title>
	<atom:link href="http://bebop.emstone.com/tags/agile/feed/" rel="self" type="application/rss+xml" />
	<link>http://bebop.emstone.com</link>
	<description>엠스톤 개발팀 블로그</description>
	<lastBuildDate>Sun, 29 Jan 2012 05:25:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
		<item>
		<title>라자냐 코드 (Lasagna Code)</title>
		<link>http://lethean.pe.kr/2011/06/10/lasagna-code/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lasagna-code&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25eb%259d%25bc%25ec%259e%2590%25eb%2583%2590-%25ec%25bd%2594%25eb%2593%259c-lasagna-code</link>
		<comments>http://lethean.pe.kr/2011/06/10/lasagna-code/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lasagna-code#comments</comments>
		<pubDate>Fri, 10 Jun 2011 07:37:05 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1677</guid>
		<description><![CDATA[요즘은 예전에 작성한 라자냐 코드(Lasagna Code)의 굴레에서 벗어나기 위해 노력하고 있습니다. 스파게티 코드(Spaghetti Code)가 아닌 라자냐 코드라고? 처음 들어보시는 분을 위해 위키피디어 설명을 날림으로 번역해 보면 다음과 같습니다. 라자냐 코드는 일종의 프로그램 구조인데, 잘 정의되어 분리된 여러 계층(layer)을 가지는 것이 &#8230; <a href="http://lethean.pe.kr/2011/06/10/lasagna-code/">Continue reading <span>&#8594;</span></a> <a href="http://lethean.pe.kr/2011/06/10/lasagna-code/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=lasagna-code">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://lethean.pe.kr/wp-content/uploads/2011/06/400px-Lasagna_NIH.jpg" rel="lightbox[1677]"><img class="aligncenter" title="Lasagna" src="http://lethean.pe.kr/wp-content/uploads/2011/06/400px-Lasagna_NIH-266x400.jpg" alt="Lasagna" width="266" height="400" /></a><br />
요즘은 예전에 작성한 <a href="http://en.wikipedia.org/wiki/Spaghetti_code#Lasagna_code">라자냐 코드(Lasagna Code)</a>의 굴레에서 벗어나기 위해 노력하고 있습니다. 스파게티 코드(Spaghetti Code)가 아닌 라자냐 코드라고? 처음 들어보시는 분을 위해 위키피디어 설명을 날림으로 번역해 보면 다음과 같습니다.</p>
<blockquote><p>라자냐 코드는 일종의 프로그램 구조인데, 잘 정의되어 분리된 여러 계층(layer)을 가지는 것이 특징입니다. 각각의 코드 계층은 잘 정의된 인터페이스를 통해 아래 계층의 서비스에 접근합니다. 이 용어는 프로그램 구조를 파스타에 비유하는 스파케티 코드와 비교되곤 하는데, 다른 재료(고기, 소스, 채소, 치즈 등)가 각각 파스타 조각으로 분리되어 하나의 접시에 담긴 라자냐의 계층 구조에 기인합니다.</p>
<p>라자냐 코드의 흔한 예 중 하나는 다른 하부 시스템 , 가령 웹 어플리케이션과 비즈니스 로직, 관계형 데이터베이스 사이에 존재하는 인터페이스입니다. 또한 프로그래밍 기법 중에, 프로그램 전체 구조에서 레벨마다 다른 프로그래밍 언어를 사용하는 경우에도 이를 연결하는 계층이 존재하는데 이 역시 라자냐 코드의 일종입니다. 일반적인 클라이언트-서버 응용 프로그램 역시 대부분 잘 정의된 인터페이스를 통해 통신하므로 라자냐 코드라고 할 수 있습니다.</p>
<p>대개 라자냐 코드는 다른 계층간에 인캡슐레이션(encapsulation)을 강요하기 때문에, 문제의 하부 시스템은 잘 정의된 메카니즘(SQL, RPC, FFI 등)을 제외한 다른 통신 수단이 없습니다. 물론, 시스템의 개별적인 레이어는 덜 구조화되어 있거나 엉망으로 조직화되어 있을 수도 있습니다.</p></blockquote>
<p>위 설명을 보면 라자냐 코드는 전혀 나쁜 것 같지 않은데 도대체 무슨 굴레를 벗어난다고 하는 걸까, 모든 진리가 말하듯이, 과하면 부족함만 못한 법입니다. 너무 많은 계층화는 성능 개선 / 기능 확장 / 유지 보수 디버깅에 오히려 방해가 되어 버리고 맙니다. 예를 들어 GNOME 2 플랫폼에서는 용도별로 개발된 수많은 libgnome* 라이브러리가 존재했지만 GNOME 3 개발 과정에서 대부분 기능을 GLib / GTK+ 라이브러리에 통합한 이유 중 하나도 마찬가지일 겁니다. 여담이지만, 사실 그래서 GTK+는 모든 기능이 종합 선물 셋트처럼 제공되는 QT 애호가들에게 많은 비난을 받아왔었던 것도 사실입니다. 무슨 라이브러리 의존성이 이렇게 많고 복잡한지&#8230; 물론 아직도 GTK+ 툴킷 자체는 여전히 기능별 라이브러리에 의존하고 있지만 예전에 비해 정말 많이 정리된 셈입니다.</p>
<p>아무튼, 스스로 만든 라자냐 코드의 굴레 중에서 가장 문제가 되는 부분은, 멀티 플랫폼을 고려하는 것과 더불어 향후 라이브러리 교체시 수고를 덜기 위해 어떤 라이브러리 API를 그대로 사용하지 않고 일종의 확장성있는 랩퍼(wrapper) API를 따로 만들어 사용한 점입니다.  결과적으로, 라이브러리 자체도 계속 업그레이드 되기 때문에 이를 반영해야 하고, 다른 라이브러리로 교체하는 경우도 별로 없고, 성능 개선이나 기능 추가를 위해 끊임없이 랩퍼 API를 추가하면서, 디버깅할 때는 한 동작을 위해 두 세 단계 이상의 계층을 따라 가야하고&#8230; 배보다 배꼽이 더 커지는 경우가 발생해 버리는 상황에 이르게 됩니다.</p>
<p>두번째로 문제가 되는 부분은, 기능 하나를 구현할때 구성 모듈을 너무 세분하게 나눈 점입니다. 특히, 수평적이 아닌 수직적으로 기능을 나눌때 적절한 범위를 넘어가버리면, 새 기능 추가시 매우 많은 모듈에 대한 의존성 검사, 부작용 검사 등의 작업이 몇 배나 어렵습니다. 예를 들어 상위 계층에 있는 기능을 하위 계층에서 사용해야 하는 경우가 발생하면 이를 위한 인터페이스를 설계하는데 시간이 더 걸리는 경우도 많습니다. 그냥 간단하게 하나의 모듈로 작성하면 되었을 걸&#8230;</p>
<p>과하면 부족함만 못하다&#8230; 언제 어떻게 무엇이 될 지 모르는 미래를 위해 미리 고민해서 확장성 있는 구조를 설계하는데 노력하는 것보다, 지금 당장의 요구 사항 수준에서 아무 문제없이 잘 돌아가는, 향후 쉽게 이해하고 확장할 수 있는 간단한 구조의 코드를 작성하는게 맞는 것 같습니다. 게다가 향후 발생할 요구사항을 미리 알 지 못하는데 미리 확장성있게 설계한다는 것 자체가 모순이 아닌가 하는 생각도 들고&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2011/06/10/lasagna-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>Gource 소스 저장소 시각화 프로그램</title>
		<link>http://lethean.pe.kr/2010/04/23/gource-source-visualization/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gource-source-visualization&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gource-%25ec%2586%258c%25ec%258a%25a4-%25ec%25a0%2580%25ec%259e%25a5%25ec%2586%258c-%25ec%258b%259c%25ea%25b0%2581%25ed%2599%2594-%25ed%2594%2584%25eb%25a1%259c%25ea%25b7%25b8%25eb%259e%25a8</link>
		<comments>http://lethean.pe.kr/2010/04/23/gource-source-visualization/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gource-source-visualization#comments</comments>
		<pubDate>Fri, 23 Apr 2010 01:59:16 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1304</guid>
		<description><![CDATA[LWN.net 기사 중에서 소스 코드 작업 시각화 관련 기사를 보고 재미있을 것 같아 Gource 프로그램을 이용해 회사에서 진행중인 프로젝트에 적용해 보았습니다. http://www.youtube.com/watch?v=RUwDxM28EBA 만... <a href="http://lethean.pe.kr/2010/04/23/gource-source-visualization/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=gource-source-visualization">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[LWN.net 기사 중에서 소스 코드 작업 시각화 관련 기사를 보고 재미있을 것 같아 Gource 프로그램을 이용해 회사에서 진행중인 프로젝트에 적용해 보았습니다. http://www.youtube.com/watch?v=RUwDxM28EBA 만드는 방법은 우선 필요한 패키지를 설치하고(Ubuntu 기준) $ sudo apt-get install gource ffmpeg Git 저장소가 있는 디렉토리로 이동해서 &#8230; <a href="http://lethean.pe.kr/2010/04/23/gource-source-visualization/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2010/04/23/gource-source-visualization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>GObject 속성 직렬화(Serialization)하기</title>
		<link>http://lethean.pe.kr/2010/04/07/serialize-gobject-properties/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=serialize-gobject-properties&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gobject-%25ec%2586%258d%25ec%2584%25b1-%25ec%25a7%2581%25eb%25a0%25ac%25ed%2599%2594serialization%25ed%2595%2598%25ea%25b8%25b0</link>
		<comments>http://lethean.pe.kr/2010/04/07/serialize-gobject-properties/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=serialize-gobject-properties#comments</comments>
		<pubDate>Wed, 07 Apr 2010 12:33:58 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[GLib]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1273</guid>
		<description><![CDATA[GObject 객체의 속성(properties)을 자동으로 저장하고 다시 자동으로 불러들이는 일련의 작업을 자동화할 수 있다면 편하지 않을까 생각해 본 적이 있을겁니다. 이러한 과정을 직렬화(serialization) <a href="http://lethean.pe.kr/2010/04/07/serialize-gobject-properties/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=serialize-gobject-properties">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[GObject 객체의 속성(properties)을 자동으로 저장하고 다시 자동으로 불러들이는 일련의 작업을 자동화할 수 있다면 편하지 않을까 생각해 본 적이 있을겁니다. 이러한 과정을 직렬화(serialization)라고 부른다면, 오브젝티브-C, 자바 등과 같은 많은 언어가 이미 기본적으로 직렬화를 지원하거나 관련 라이브러리를 제공하고 있는만큼, GObject 객체 직렬화 &#8230; <a href="http://lethean.pe.kr/2010/04/07/serialize-gobject-properties/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2010/04/07/serialize-gobject-properties/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>GLib 테스트 프레임워크 사용하기</title>
		<link>http://lethean.pe.kr/2010/02/12/using-glib-test-framework/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-glib-test-framework&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=glib-%25ed%2585%258c%25ec%258a%25a4%25ed%258a%25b8-%25ed%2594%2584%25eb%25a0%2588%25ec%259e%2584%25ec%259b%258c%25ed%2581%25ac-%25ec%2582%25ac%25ec%259a%25a9%25ed%2595%2598%25ea%25b8%25b0</link>
		<comments>http://lethean.pe.kr/2010/02/12/using-glib-test-framework/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-glib-test-framework#comments</comments>
		<pubDate>Thu, 11 Feb 2010 18:33:45 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[Clutter]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[GLib]]></category>
		<category><![CDATA[GTK+]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1236</guid>
		<description><![CDATA[GLib 라이브러리 2.16 버전부터 지원하는 테스트 프레임워크는 C 언어용 유닛테스트 도구입니다. 물론 많은 유닛 테스트 도구가 이미 존재하지만, GLib 라이브러리 기반 C 언어 프로그램이라면  <a href="http://lethean.pe.kr/2010/02/12/using-glib-test-framework/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=using-glib-test-framework">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[GLib 라이브러리 2.16 버전부터 지원하는 테스트 프레임워크는 C 언어용 유닛테스트 도구입니다. 물론 많은 유닛 테스트 도구가 이미 존재하지만, GLib 라이브러리 기반 C 언어 프로그램이라면 굳이 다른 라이브러리를 사용하는 것보다는 이미 지원하는 훌륭한 도구를 사용하는게 더 좋겠지요. 참고로, GTK+, Clutter 등 &#8230; <a href="http://lethean.pe.kr/2010/02/12/using-glib-test-framework/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2010/02/12/using-glib-test-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>싱글턴(Singleton) GObject 객체 만들기</title>
		<link>http://lethean.pe.kr/2010/02/11/how-to-make-a-gobject-singleton/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-make-a-gobject-singleton&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25ec%258b%25b1%25ea%25b8%2580%25ed%2584%25b4singleton-gobject-%25ea%25b0%259d%25ec%25b2%25b4-%25eb%25a7%258c%25eb%2593%25a4%25ea%25b8%25b0</link>
		<comments>http://lethean.pe.kr/2010/02/11/how-to-make-a-gobject-singleton/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-make-a-gobject-singleton#comments</comments>
		<pubDate>Thu, 11 Feb 2010 14:46:45 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[GLib]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1244</guid>
		<description><![CDATA[좋은 블로그 포스트가 올라왔길래, 우리말로 정리해 보았습니다. GObject 기반 객체 지향 프로그래밍에서 싱글턴 패턴을 사용하려면 대개 다음과 같은 함수를 추가합니다. FooBar* foo_bar_get_default... <a href="http://lethean.pe.kr/2010/02/11/how-to-make-a-gobject-singleton/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=how-to-make-a-gobject-singleton">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[좋은 블로그 포스트가 올라왔길래, 우리말로 정리해 보았습니다. GObject 기반 객체 지향 프로그래밍에서 싱글턴 패턴을 사용하려면 대개 다음과 같은 함수를 추가합니다. FooBar* foo_bar_get_default &#40;void&#41; &#123; static FooBar *self = NULL; &#160; if &#40;self == NULL&#41; self = foo_bar_new &#40;&#41;; &#160; return &#8230; <a href="http://lethean.pe.kr/2010/02/11/how-to-make-a-gobject-singleton/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2010/02/11/how-to-make-a-gobject-singleton/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>GObject 객체 지향 프로그래밍 (4)</title>
		<link>http://lethean.pe.kr/2009/08/24/oop-with-gobject-4/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gobject-%25ea%25b0%259d%25ec%25b2%25b4-%25ec%25a7%2580%25ed%2596%25a5-%25ed%2594%2584%25eb%25a1%259c%25ea%25b7%25b8%25eb%259e%2598%25eb%25b0%258d-4</link>
		<comments>http://lethean.pe.kr/2009/08/24/oop-with-gobject-4/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 05:07:11 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[GLib]]></category>
		<category><![CDATA[GTK+]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1018</guid>
		<description><![CDATA[이전 글에 계속 이어집니다.
객체 속성 정보 얻기
EdcHost 객체의 속성 정보를 실행 중에 얻어볼까 합니다.
왜 또 갑자기 불필요한 예제를 꺼내냐고 물어보실 분이 있을 것 같아 말하자면, 가끔 요긴한 경우가 있기 때문입니다. 예를 들어 EdcHost 객체를 상속받은 EdcHostDoosan, EdcHostKia, EdcHostLitte 객체가 여러 개 존재할 경우, 이 객체들은 EdcHost의 공통 속성 뿐 아니라 본인의 속성도 따로 가집니다. 이러한 [...] <a href="http://lethean.pe.kr/2009/08/24/oop-with-gobject-4/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[이전 글에 계속 이어집니다.
객체 속성 정보 얻기
EdcHost 객체의 속성 정보를 실행 중에 얻어볼까 합니다.
왜 또 갑자기 불필요한 예제를 꺼내냐고 물어보실 분이 있을 것 같아 말하자면, 가끔 요긴한 경우가 있기 때문입니다. 예를 들어 EdcHost 객체를 상속받은 EdcHostDoosan, EdcHostKia, EdcHostLitte 객체가 여러 개 존재할 경우, 이 객체들은 EdcHost의 공통 속성 뿐 아니라 본인의 속성도 따로 가집니다. 이러한 [...]]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2009/08/24/oop-with-gobject-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>GObject 객체 지향 프로그래밍 (3)</title>
		<link>http://lethean.pe.kr/2009/08/18/oop-with-gobject-3/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gobject-%25ea%25b0%259d%25ec%25b2%25b4-%25ec%25a7%2580%25ed%2596%25a5-%25ed%2594%2584%25eb%25a1%259c%25ea%25b7%25b8%25eb%259e%2598%25eb%25b0%258d-3</link>
		<comments>http://lethean.pe.kr/2009/08/18/oop-with-gobject-3/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 01:33:43 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[GLib]]></category>
		<category><![CDATA[GTK+]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=980</guid>
		<description><![CDATA[이 글은 회사 개발팀 내부 세미나를 위해 작성중인 글입니다. 하지만, 블로그란 매체의 특성상 외부에도 공개되고 있는데, 댓글은 달지 않아도 접속하는 사람들 대부분이 제가 아는 분일 거라 생각하고 한마디 하자면, 세상에 공짜가 어디 있는가, 주저하지 말고 내게 연락해서 술 한 잔 사게! (언젠가부터 술 강요 청탁 협박 블로그가 되어 가고 있군&#8230;)
속성 (Properties) 추가하기
이제, GObject 속성(properties) 기능을 [...] <a href="http://lethean.pe.kr/2009/08/18/oop-with-gobject-3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[이 글은 회사 개발팀 내부 세미나를 위해 작성중인 글입니다. 하지만, 블로그란 매체의 특성상 외부에도 공개되고 있는데, 댓글은 달지 않아도 접속하는 사람들 대부분이 제가 아는 분일 거라 생각하고 한마디 하자면, 세상에 공짜가 어디 있는가, 주저하지 말고 내게 연락해서 술 한 잔 사게! (언젠가부터 술 강요 청탁 협박 블로그가 되어 가고 있군&#8230;)
속성 (Properties) 추가하기
이제, GObject 속성(properties) 기능을 [...]]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2009/08/18/oop-with-gobject-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>Presenter First 개발</title>
		<link>http://lethean.pe.kr/?p=290&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=presenter-first-%25ea%25b0%259c%25eb%25b0%259c</link>
		<comments>http://lethean.pe.kr/?p=290#comments</comments>
		<pubDate>Tue, 16 Dec 2008 17:55:54 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Agile]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=290</guid>
		<description><![CDATA[프리젠터 먼저하기(Presenter First)는모델-뷰-프리젠터(MVP) 디자인 패턴과 테스트 주고 개발(TDD) 등의 아이디어를 버무린  소프트웨어 개발 방법론입니다. 이에 대해 설명하기에 앞서 먼저 모델-뷰-컨트롤러(MVC) 패턴과 비교하여 모델-뷰-프리젠터(MVP) 개념을 정리하면 대략 다음과 같습니다.

모델(Model) : 실제 다루고자 하는 데이터 읽기 / 쓰기. 관찰자(Observer) 패턴처럼 이벤트를 제공하면 더 좋습니다. MVC 패턴에서는 모델이 실제 데이터 뿐 아니라 사용자 인터페이스(View)와 연관된 데이터까지 처리하지만, MVP [...] <a href="http://lethean.pe.kr/?p=290">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Presenter_First">프리젠터 먼저하기(Presenter First)</a>는<a href="http://en.wikipedia.org/wiki/Model_View_Presenter">모델-뷰-프리젠터(MVP)</a> 디자인 패턴과 테스트 주고 개발(TDD) 등의 아이디어를 버무린  소프트웨어 개발 방법론입니다. 이에 대해 설명하기에 앞서 먼저 모델-뷰-컨트롤러(MVC) 패턴과 비교하여 모델-뷰-프리젠터(MVP) 개념을 정리하면 대략 다음과 같습니다.</p>
<ul>
<li><strong>모델(Model)</strong> : 실제 다루고자 하는 데이터 읽기 / 쓰기. 관찰자(Observer) 패턴처럼 이벤트를 제공하면 더 좋습니다. MVC 패턴에서는 모델이 실제 데이터 뿐 아니라 사용자 인터페이스(View)와 연관된 데이터까지 처리하지만, MVP 패턴에서 모델은 순수하게 데이터만 처리합니다. 즉, 모델은 뷰나 프리젠터(사용자 인터페이스)에 대해서는 알 필요도 없고 알아서도 안됩니다.</li>
<li><strong>뷰(View)</strong> : 사용자 인터페이스. 데이터 표시 뿐 아니라 사용자 입력까지 모두 처리합니다. MVC 패턴에서는 사용자 입력을 컨트롤러(Controller)에서 처리하지만 MVP 패턴에서는 뷰가 모두 처리합니다. 사용자 이벤트는 프리젠터에게 전달합니다. (관찰자 패턴을 사용합니다) 모델의 데이터가 변경되었다는 이벤트가 발생하면 데이터를 표시합니다. 하지만 초기 MVP 패턴과 달리 요즘에는 뷰와 모델간의 의존성까지 아예 없애버리고, 프리젠터가 디스플레이까지 제어합니다. 프리젠터 먼저하기 방법론에서 특히 이 방식을 이용합니다.</li>
<li><strong>프리젠터(Presenter)</strong> : 뷰가 전달한 사용자 이벤트에 기반하여 시나리오에 따라 모델 데이터를 조작합니다. MVC 패턴에서 어플리케이션 역할을 하는 부분이며, 사용자 요구사항이 변경되거나 로직이 변경되면 수정이 되어야 하는 부분이기도 합니다. 결과적으로, 모델과 뷰에 대해 알고있는 건 오직 프리젠터 뿐이고, 모델과 뷰는 프리젠터를 모릅니다. 뷰는 모델에 대해 알 수도 있지만, 프리젠터 먼저하기 방법론에서는 이 의존성도 없애버립니다.</li>
</ul>
<p>뷰를 오버로딩 가능한 추상 인터페이스로 만들고 프리젠터가 이 인터페이스를 사용하도록 하면, 뷰를 구현한(implementation) 객체는 플러그인처럼 교체 가능합니다. 즉, 뷰는 어쩔 수 없이 플랫폼이나 GUI 라이브러리에 의존하게 구현해야 하지만 모델과 프리젠터, 추상 뷰는 이와 상관없이 구현할 수 있습니다. 따라서 쉽게 이식 가능할 뿐 이나라, 하나의 데이터에 대해 여러가지 모양의 사용자 인터페이스를 지원하는 소프트웨어 개발이 쉬워집니다. 물론 모델 역시 추상 인터페이스로 만들고 같은 방식으로 프리젠터가 이 인터페이스를 사용하도록 하면 모델 구현 역시 쉽게 교체 가능한 구조가 됩니다. 그리고, 이러한 추상화는 테스트 주도 개발에도 응용할 수 있습니다.</p>
<p>결과적으로, 프리젠터 먼저하기 방법론에서 모델-뷰-프리젠터의 관계는 다음 그림과 같습니다.</p>
<pre> [M]  -----&gt;    [P]    &lt;----- [V]
Model &lt;===== Presenter =====&gt; View

  (---&gt; : Events, ===&gt; : Messages)</pre>
<p>모델과 뷰는 프리젠터에게 이벤트를 전달하고, 프리젠터는 모델과 객체를 제어하기 위한 메시지를 전달합니다. 즉, 프리젠터만 모델과 뷰에 대해 알고 있을 뿐, 모델과 뷰는 다른 구성 요소를 알지 못합니다. 뷰는 비즈니스 로직에서 완전히 분리하고 모든 로직은 프리젠터에서 처리합니다.  뷰 인터페이스는 가능한 얇고 단순해야 하고, 이상적인 경우 사용자 이벤트를 그대로 프리젠터에게 전달하고, 표시할 내용을 읽고 쓰는 동작만 해야 합니다.</p>
<p>프리젠터에게 전달하는 이벤트는 비즈니스 로직에서 사용하는 용어를 사용하여 전달되어야 합니다. 엔지니어 관점의 이벤트가 아닌 사용자 관점의 이벤트를 사용해야 한다는 점입니다. 예를 들어, 비즈니스 로직이 &#8220;추가 버튼을 누르면 텍스트 입력 내용이 할일목록에 추가되어야 함&#8221;이라면, 뷰는 &#8220;save-button-clicked&#8221; 이벤트가 정의되어야 하고, 프리젠터는 이 이벤트가 발생했을때 호출할 핸들러를 연결합니다. 핸들러에서는 뷰의 &#8220;get_text()&#8221; 함수를 호출하여 텍스트 내용을 얻은 뒤 모델의 &#8220;add_to_list()&#8221; 함수를 이용해 모델에 추가합니다. 여기서 만일 버튼 대신 예쁜 아이콘으로 뷰가 달라졌다고 이벤트 이름을 &#8220;save-image-clicked&#8221;로 변경하거나 새로운 이벤트를 추가하면 안됩니다. 사용자가 팝업 메뉴를 원해 메뉴 선택을 이용해 동일한 처리를 하게 되더라도 &#8220;save-menu-activated&#8221;로 변경하거나 새로 추가할 필요도 없습니다.  또는 실제로 버튼의 &#8220;clicked&#8221; 이벤트가 아닌 &#8220;button-pressed&#8221; 이벤트를 사용하더라도 프리젠터에게 전달하는 이벤트 이름은 변경하면 안된다는 점이 중요합니다.</p>
<p>위 예를 조금 더 이어보면, 모델의 &#8220;add_to_list()&#8221; 함수 내에서는 데이터에 새로운 텍스트 내용을 추가한 뒤 내용이 변경되었음을 알리는 &#8220;list-changed&#8221; 이벤트를 발생하고, 프리젠터에서 미리 이 이벤트에 연결한 핸들러는 모델의 &#8220;get_list()&#8221; 함수를 호출해 목록을 얻은 뒤, 뷰의 &#8220;set_list()&#8221; 함수를 이용해 변경된 데이터를 화면에 표시합니다. 여기까지 설명에서 중요한 점은, 모든 변경사항은 관찰자 패턴처럼 이벤트를 이용해 전달한다는 점이고, 프리젠터가 모델과 뷰 간의 중재 작업을 통해 비즈니스 로직을 완성한다는 점입니다. 만일 할일 목록과 할 일 목록 편집 화면이 분리되어 구현되어 있을 경우 서로 의존성을 가지고 싶지 않을 수도 있습니다. 이런 경우 두 모델을 중재(coordinator)해서 연결하는 새로운 프리젠터, 혹은 어플리케이션 객체를 새로 만들어 이벤트 처리를 하면 두 모델간의 의존성도 사라질 수 있습니다.</p>
<p>프리젠터 먼저하기 방법론은 지금까지 설명한 MVP 패턴으로 프로그램을 할때 프리젠터 객체를 가장 먼저 코딩합니다. 어차피 모델과 뷰 객체의 인터페이스(API)와 이벤트는 프리젠터 객체 구현이 마무리 될때까지 계속 수정되므로, 모델과 뷰는 가짜 객체(Mock Object)로 구현합니다. 가짜 객체라고 해도 프리젠터가 원하는 작업은 실제로 수행하는 것처럼 동작해야 하므로 가능한 단순한 자료구조를 이용해야 합니다.  이렇게 해서 비즈니스 로직을 모두 프리젠터에 구현한 뒤에, 모델과 뷰를 실제로 데이터 베이스에 접근하거나 파일에 읽고 쓰든, GTK+ 위젯 라이브러리를 이용하거나 콘솔 GUI를 이용하든 해서 구현하면 됩니다.</p>
<p>하지만 유닛 테스트 도구를 사용하지 않는다면 뷰 없이 프리젠터 동작을 확인하는 코드를 만들기는 조금 불편합니다. 이런 경우 뷰를 가짜 객체 방식으로 만들더라도 어느 정도 기본적인 사용자 입출력이 가능하도록 만들면서 해야 합니다.</p>
<p><strong>참고한 자료</strong></p>
<ol>
<li><a href="http://www.wildcrest.com/Potel/Portfolio/mvp.pdf">&#8220;MVP: Model-View-Presenter, The Taligent Programming Model for C++ and Java&#8221;</a>, Mike Potel, 1996</li>
<li><a href="http://www.object-arts.com/papers/TwistingTheTriad.PDF">&#8220;TWISTING THE TRIAD, The evolution of the Dolphin Smalltalk MVP application framework&#8221;</a>, Andy Bower, Blair McGlashan, Tutorial Paper for ESUG 2000</li>
<li><a href="http://atomicobject.com/files/PresenterFirstAgile2006.pdf">&#8220;Presenter First: Organizing Complex GUI Applications for Test-Drivn Development&#8221;</a>, agile, pp. 276-288, AGILE 2006 (AGILE&#8217;06), 2006.</li>
<li><a href="http://atomicobject.com/files/BigComplexTested_Feb07.pdf">&#8220;Big, Complex, and Tested? Just Say &#8216;When&#8217;&#8221;</a>, Better Software Magazine February, 2007</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/?feed=rss2&#038;p=290</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
	</channel>
</rss>

