<?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/"
	>

<channel>
	<title>masputih &#187; Repost</title>
	<atom:link href="http://masputih.com/category/repost/feed" rel="self" type="application/rss+xml" />
	<link>http://masputih.com</link>
	<description>Coder for Hire</description>
	<lastBuildDate>Mon, 24 May 2010 08:48:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>MVC Sederhana untuk Pemula</title>
		<link>http://masputih.com/2009/05/mvc-sederhana-untuk-pemula</link>
		<comments>http://masputih.com/2009/05/mvc-sederhana-untuk-pemula#comments</comments>
		<pubDate>Fri, 01 May 2009 08:30:57 +0000</pubDate>
		<dc:creator>Anggie Bratadinata</dc:creator>
				<category><![CDATA[ActionScript 3]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[Repost]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[pattern]]></category>

		<guid isPermaLink="false">http://masputih.com/?p=119</guid>
		<description><![CDATA[Repost artikel yg sudah pernah saya posting di blog yang lama. Kali ini saya jelaskan tentang cara membuat “struktur” MVC sederhana untuk menulis kode yang maintainable dengan memecah kode menjadi beberapa bagian berdasarkan fungsinya ( separation of concerns ). Saya anggap Anda sudah cukup mengetahui dasar OOP dan mempraktekkannya, jadi saya nggak perlu menjelaskan lagi [...]]]></description>
			<content:encoded><![CDATA[<p></p><blockquote><p>Repost artikel yg sudah pernah saya posting di <a href="http://old.masputih.com">blog yang lama</a>. </p></blockquote>
<p>Kali ini saya jelaskan tentang cara membuat “struktur” MVC sederhana untuk menulis kode yang maintainable dengan memecah kode menjadi beberapa bagian berdasarkan fungsinya ( <em>separation of concerns</em> ).</p>
<p>Saya anggap Anda sudah cukup mengetahui dasar OOP dan mempraktekkannya, jadi saya nggak perlu menjelaskan lagi apa itu <em>class</em>, <em>instance</em>, <em>static</em>, <em>getter/setter</em>, dsb. Saya juga nggak menjelaskan apa itu <em>custom events</em> dan bagaimana cara membuat &amp; menggunakannya karena sudah pernah saya jelaskan dalam artikel yang lain. Selain itu, Anda juga harus mengerti cara mendefinisikan &amp; membuat <em>custom class</em> untuk objek di <em>library</em>.</p>
<p><span id="more-119"></span></p>
<p>Di sini saya membuat aplikasi sederhana berupa sebuah kotak yang posisinya bisa dikontrol oleh 4 tombol seperti berikut:</p>
<div class="swfcontainer" style="text-align:center">
<div class="swf" style="margin:10px;border:1px solid #ccc;">
[kml_flashembed fversion=“9.0.124″ movie=“http://masputih.com/files/SimpleMVC.swf” targetclass=“flashmovie” publishmethod=“static” width=“320” height=“400”]</p>
<p><a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>
<p>[/kml_flashembed]
</p></div>
</div>
<h3>Design Patterns</h3>
<p><em>Design patterns</em> (DP) adalah sekumpulan solusi generik untuk masalah-masalah yang umum ditemui oleh para <em>developer</em> dalam membuat aplikasi. <em>Pattern</em> berarti pola, artinya DP bukan berupa kode, tetapi berupa panduan yang implementasinya terserah <em>developer</em> yang menggunakannya.</p>
<p>Info yang lebih lengkap bisa Anda baca di <a href="http://id.wikipedia.org/wiki/Pola_desain">wikipedia</a>.</p>
<h3>Model-View-Controller</h3>
<p>MVC adalah <em>meta-pattern</em> , artinya <span class="caps">MVC</span> bukan merupakan <em>pattern</em> yang berdiri sendiri tapi merupakan kumpulan dari beberapa <em>pattern</em> &amp; dalam buku <em>Head First Design Patterns</em> , MVC dimasukkan dalam kelompok <em>compound-pattern</em>.</p>
<p>Pada prinsipnya, implementasi MVC membagi kode ke dalam 3 bagian yaitu:</p>
<ul>
<li>Model sebagai sumber data</li>
<li>View sebagai representasi data dan <em>user interface</em></li>
<li>Controller yang berfungsi sebagai “otak” atau <em>business logic</em> yang memproses <em>user input</em> dan meng–<em>update</em> Model dan View ( kalau diperlukan ).</li>
</ul>
<h4>Apa keuntungan <span class="caps">MVC </span>?</h4>
<p>Sekilas MVC kelihatannya merepotkan karena kita harus menulis kode lebih banyak tapi keuntungannya adalah kode kita lebih <em>maintainable</em> karena kita bisa mengubah salah satu bagian tanpa harus mengubah bagian yang lain. Sebagai contoh, misalnya kita membuat aplikasi A yang memproses data berformat XML namun kemudian kita diharuskan menggunakan data berformat JSON. Dalam kasus seperti ini, kita cukup mengubah Model tanpa harus mengubah bagian yang lain.</p>
<p>MVC juga mempermudah <em>debugging</em> karena kita bisa memperkirakan bagian mana yang bermasalah tanpa harus membongkar seluruh kode yang sudah kita buat.</p>
<p>Jadi secara umum, keuntungan MVC jauh lebih besar daripada kerepotan yang ditimbulkannya. Di samping itu, kalo Anda nggak mau repot menulis berbaris-baris kode, mungkin menjadi <em>programmer</em> bukan profesi yang cocok buat Anda &amp; sebaiknya Anda <a href="http://www.google.co.id/search?q=lowongan+kerja">cari</a> pekerjaan <a href="http://bikinduit.com/">lain</a>. <img src='http://masputih.com/wordpress/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<h3>Struktur dasar</h3>
<p> 	Di dalam direktori projek, saya buat 4 buah sub-direktori/<em>package</em> seperti gambar di bawah ini.</p>
<div class="wp-caption aligncenter" style="width: 188px">
	<img alt="Direktori Project di FlashDevelop" src="http://old.masputih.com/images/75.jpg" title="Struktur Direktori" width="188" height="207" />
	<p class="wp-caption-text">Direktori Project di FlashDevelop</p>
</div>
<p>Berikut ini diagram dari aplikasi yang saya buat.</p>
<div class="wp-caption aligncenter" style="width: 497px">
	<img alt="Class Diagram" src="http://masputih.com/images/74.jpg" title="Class Diagram" width="497" height="515" />
	<p class="wp-caption-text">Class Diagram</p>
</div>
<h3>View &amp; ViewEvent</h3>
<p>	Package <code>view</code> berisi class yang berhubungan dengan library symbol yaitu <code>MainView</code> dan <code>ArrowButton</code>. <code>MainView</code> bertugas menyiarkan <code>ViewEvent</code> jika salah satu tombol navigasi diklik. <em>Event</em> ini ditangkap oleh <code>Controller</code> yang kemudian meng-update <code>Model</code>. Selain itu <code>MainView</code> juga menampilkan posisi kotak kuning.</p>
<p>Kenapa saya membuat <code>ViewEvent</code> dan nggak membuat <code>Controller</code> yang langsung mendengarkan <code>MouseEvent.CLICK</code> yang disiarkan oleh tombol kontrol ? Karena saya ingin meminimalkan coupling antara <code>MainView</code> dan <code>Controller</code> sehingga jika saya perlu mengubah <code>View</code>, selama event yang disiarkannya tetap bertipe <code>ViewEvent</code>, saya nggak perlu mengubah <code>Controller</code>.</p>
<p>[js]<br />
package simplemvc.view {</p>
<p>	import flash.display.MovieClip;<br />
	import flash.events.Event;<br />
	import flash.events.MouseEvent;<br />
	import flash.geom.Point;<br />
	import flash.text.TextField;<br />
	import simplemvc.events.ViewEvent;<br />
	import simplemvc.model.Model;</p>
<p>	/**<br />
	 * …<br />
	 * @author Anggie Bratadinata<br />
	 */<br />
	public class MainView extends MovieClip {</p>
<p>		//timeline objects<br />
		public var hero:MovieClip;<br />
		public var board:MovieClip;<br />
		public var leftBtn:ArrowButton;<br />
		public var rightBtn:ArrowButton;<br />
		public var upBtn:ArrowButton;<br />
		public var downBtn:ArrowButton;<br />
		public var positionTxt:TextField;</p>
<p>		private var _model:Model = Model.getInstance();</p>
<p>//———————————————————– INIT</p>
<p>		public function MainView() {</p>
<p>			initButtonListener();</p>
<p>			_model.addEventListener(Event.CHANGE, modelListener);</p>
<p>		}</p>
<p>		private function initButtonListener():void {<br />
			var i:int = 0;<br />
			while (i &lt; numChildren) {<br />
				if (this.getChildAt(i) is ArrowButton) {<br />
					this.getChildAt(i).addEventListener(MouseEvent.CLICK, buttonListener);<br />
				}<br />
				i++;<br />
			}</p>
<p>		}</p>
<p>		private function buttonListener(e:MouseEvent):void {</p>
<p>			switch(e.currentTarget) {<br />
				case leftBtn:<br />
					dispatchEvent(new ViewEvent(ViewEvent.MOVE_LEFT));<br />
				break;<br />
				case rightBtn:<br />
					dispatchEvent(new ViewEvent(ViewEvent.MOVE_RIGHT));<br />
				break;<br />
				case upBtn:<br />
					dispatchEvent(new ViewEvent(ViewEvent.MOVE_UP));<br />
				break;<br />
				case downBtn:<br />
					dispatchEvent(new ViewEvent(ViewEvent.MOVE_DOWN));<br />
				break;<br />
			}<br />
		}</p>
<p>		private function modelListener(e:Event):void {</p>
<p>			hero.x = _model.heroPos.x;<br />
			hero.y = _model.heroPos.y;</p>
<p>			positionTxt.text = _model.heroPos.toString();</p>
<p>		}</p>
<p>	}</p>
<p>}</p>
<p>[/js]</p>
<p>[js]<br />
package simplemvc.events {<br />
	import flash.events.Event;</p>
<p>	/**<br />
	 * …<br />
	 * @author Anggie Bratadinata<br />
	 */<br />
	public class ViewEvent extends Event {</p>
<p>		public static const MOVE_LEFT:String = “moveLeft”;<br />
		public static const MOVE_RIGHT:String = “moveRight”;<br />
		public static const MOVE_UP:String = “moveUp”;<br />
		public static const MOVE_DOWN:String = “moveDown”;</p>
<p>		public function ViewEvent(type:String) {<br />
			super(type, true);<br />
		} </p>
<p>		override public function clone():Event {<br />
			return new ViewEvent(type);<br />
		} </p>
<p>		override public function toString():String {<br />
			return formatToString(“ViewEvent”, “type”, “bubbles”, “cancelable”, “eventPhase”);<br />
		}</p>
<p>	}</p>
<p>}</p>
<p>[/js]</p>
<h3>Model</h3>
<p><code>Model</code> adalah bagian dimana data berada. Untuk data yang bersifat global, kita bisa mengimplementasikan <em>Singleton pattern</em>. <em>Singleton class</em> hanya bisa diinstansiasi satu kali selama aplikasi berjalan. Umumnya, referensi ke instance dari Singleton diakses dengan memanggil <em>static method</em><code> getInstance()</code>.</p>
<p>Kalo kita bekerja bersama developer lain, kita bisa mencegah mereka menginstansiasi/membuat objek Singleton dengan menggunakan <em>inner class</em> yaitu class yang didefinisikan diluar <em>package</em> tetapi masih di dalam file yang sama.</p>
<p>Model saya gunakan untuk menyimpan data berupa posisi kotak kuning. Pada saat data berubah, <code>Model</code> akan men-dispatch <code>Event.CHANGE</code> yang didengarkan oleh <code>MainView</code> yang kemudian meng-update posisi kotak kuning.</p>
<p>[js]<br />
package simplemvc.model {</p>
<p>	import flash.events.Event;<br />
	import flash.events.EventDispatcher;<br />
	import flash.geom.Point;</p>
<p>	/**<br />
	 * …<br />
	 * @author Anggie Bratadinata<br />
	 */<br />
	public class Model extends EventDispatcher {</p>
<p>		public var heroHeight:Number = 0;<br />
		public var heroWidth:Number = 0;<br />
//———————————————————– HERO VELOCITY</p>
<p>		public var vx:Number = 10;<br />
		public var vy:Number = 10;</p>
<p>//———————————————————– HERO POSITION</p>
<p>		private var _heroPos:Point = new Point();</p>
<p>		public function get heroPos():Point { return _heroPos; }</p>
<p>		public function set heroPos(value:Point):void {</p>
<p>			if (value.x &gt;= heroBounds.xMin &amp;&amp; value.x &lt;= heroBounds.xMax &amp;&amp;<br />
				value.y &gt;= heroBounds.yMin &amp;&amp; value.y &lt;= heroBounds.yMax ) {</p>
<p>				_heroPos = value;<br />
				dispatchEvent(new Event(Event.CHANGE));</p>
<p>			}<br />
		}</p>
<p>		public function moveDown():void {<br />
			heroPos = new Point(heroPos.x, heroPos.y + vy);<br />
		}</p>
<p>		public function moveUp():void {<br />
			heroPos = new Point(heroPos.x, heroPos.y — vy);<br />
		}</p>
<p>		public function moveLeft():void {<br />
			heroPos = new Point(heroPos.x — vx, heroPos.y);<br />
		}</p>
<p>		public function moveRight():void {<br />
			heroPos = new Point(heroPos.x + vx, heroPos.y );<br />
		}</p>
<p>//———————————————————– HERO BOUNDS</p>
<p>		private var _heroBounds:Object = {};</p>
<p>		public function get heroBounds():Object { return _heroBounds; }</p>
<p>		public function set heroBounds(value:Object):void {<br />
			//trace(value);<br />
			_heroBounds.xMin = value.x;<br />
			_heroBounds.xMax = value.x + value.width — heroWidth;<br />
			_heroBounds.yMin = value.y;<br />
			_heroBounds.yMax = value.y + value.height — heroHeight;</p>
<p>		}</p>
<p>//———————————————————– INIT<br />
		private static var _instance:Model;<br />
		public function Model(enf:SingletonEnforcer) {}<br />
		public static function getInstance():Model {<br />
			if (_instance == null) _instance = new Model(new SingletonEnforcer());<br />
			return _instance;<br />
		}</p>
<p>	}</p>
<p>}<br />
//INNER CLASS<br />
class SingletonEnforcer { };</p>
<p>[/js]</p>
<h3>Controller</h3>
<p><code>Controller</code> mendengarkan <code>ViewEvent</code> yang disiarkan oleh <code>MainView</code> dan meng-update <code>Model</code> berdasarkan event tersebut.</p>
<p>[js]<br />
package simplemvc.controller {<br />
	import flash.events.Event;<br />
	import flash.geom.Point;<br />
	import simplemvc.model.Model;<br />
	import simplemvc.view.*;<br />
	import simplemvc.events.*;</p>
<p>	/**<br />
	 * …<br />
	 * @author Anggie Bratadinata<br />
	 */<br />
	public class Controller {</p>
<p>		private var _model:Model = Model.getInstance();<br />
		private var _view:MainView;</p>
<p>//———————————————————– INIT</p>
<p>		public function Controller(view:MainView) {</p>
<p>			_view = view;</p>
<p>			_model.heroHeight = _view.hero.height;<br />
			_model.heroWidth = _view.hero.width;<br />
			_model.heroBounds = _view.board.getBounds(_view);</p>
<p>			_view.addEventListener(ViewEvent.MOVE_DOWN, viewListener);<br />
			_view.addEventListener(ViewEvent.MOVE_UP, viewListener);<br />
			_view.addEventListener(ViewEvent.MOVE_LEFT, viewListener);<br />
			_view.addEventListener(ViewEvent.MOVE_RIGHT, viewListener);</p>
<p>		}</p>
<p>		public function startUp():void {<br />
			_model.heroPos = new Point(0, 0);<br />
		}</p>
<p>		private function viewListener(e:ViewEvent):void {</p>
<p>			switch(e.type) {<br />
				case ViewEvent.MOVE_DOWN:<br />
					_model.moveDown();<br />
				break;<br />
				case ViewEvent.MOVE_LEFT:<br />
					_model.moveLeft();<br />
				break;<br />
				case ViewEvent.MOVE_RIGHT:<br />
					_model.moveRight();<br />
				break;<br />
				case ViewEvent.MOVE_UP:<br />
					_model.moveUp();<br />
				break;<br />
			}<br />
		}</p>
<p>	}</p>
<p>}</p>
<p>[/js]</p>
<h3>Document/Main Class</h3>
<p>[js]<br />
package  {</p>
<p>	import flash.display.MovieClip;<br />
	import simplemvc.controller.Controller;<br />
	import simplemvc.view.MainView;</p>
<p>	/**<br />
	 * …<br />
	 * @author Anggie Bratadinata<br />
	 */<br />
	public class Main extends MovieClip {</p>
<p>		public var mainView:MainView;<br />
		public var controller:Controller;</p>
<p>		public function Main() {<br />
			controller = new Controller(mainView);<br />
			controller.startUp();<br />
		}</p>
<p>	}</p>
<p>}</p>
<p>[/js]</p>
<p>Seperti Anda lihat, menulis kode dengan struktur MVC nggak terlalu sulit, hanya sedikit ngerepotin. <img src='http://masputih.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h3>Download</h3>
<a href="http://masputih.com/wordpress/wp-content/plugins/download-monitor/download.php?id=simple-mvc-src.zip" title="Downloaded 229 times" ><img src="http://masputih.com/images/disk.png" width="16" height="16"/> simple-mvc-src.zip</a> 
]]></content:encoded>
			<wfw:commentRss>http://masputih.com/2009/05/mvc-sederhana-untuk-pemula/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
