<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.1.3" -->
<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/"
	>

<channel>
	<title>Thomas Holl</title>
	<link>http://www.thomas-holl.com/wordpress</link>
	<description>RIA experiences</description>
	<pubDate>Mon, 25 Jun 2007 21:13:50 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.1.3</generator>
	<language>en</language>
			<item>
		<title>Red5 Application Deployment with Capistrano</title>
		<link>http://www.thomas-holl.com/wordpress/red5-application-deployment-with-capistrano/</link>
		<comments>http://www.thomas-holl.com/wordpress/red5-application-deployment-with-capistrano/#comments</comments>
		<pubDate>Mon, 25 Jun 2007 21:12:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Red5]]></category>

		<category><![CDATA[Deployment]]></category>

		<guid isPermaLink="false">http://www.thomas-holl.com/wordpress/red5-application-deployment-with-capistrano/</guid>
		<description><![CDATA[Introduction
To deploy the applications for Red5, I found that Rubys Capistrano really fits very nice. This is an abstract on how we did it.
Basic Requirements
Subversion repository with your Red5 Application checked in (the compiled .class files) with the following structure (or adjust the script below):

webapps/config
webapps/MyRed5Application
webapps/red5-default.xml

On the server

Installed and configured Red5 server
Secure socket shell access to [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>To deploy the applications for <a href="http://www.osflash.org/red5">Red5</a>, I found that Rubys <a href="http://manuals.rubyonrails.com/read/book/17">Capistrano</a> really fits very nice. This is an abstract on how we did it.</p>
<h2>Basic Requirements</h2>
<p>Subversion repository with your Red5 Application checked in (the compiled .class files) with the following structure (or adjust the script below):</p>
<ul>
<li>webapps/config</li>
<li>webapps/MyRed5Application</li>
<li>webapps/red5-default.xml</li>
</ul>
<p>On the server</p>
<ul>
<li>Installed and configured Red5 server</li>
<li>Secure socket shell access to the server</li>
<li>Subversion client (svn)</li>
</ul>
<p>On the client from which to deploy</p>
<ul>
<li>Ruby &gt;1.8.4</li>
<li>Gems</li>
<li>Capistrano (gem install capistrano)</li>
</ul>
<h2>deploy.rb</h2>
<p>The following Capistrano recipe will provide you with the functionality of automatic deployment and rollback (it uses Capistranos out-of-the-box features where possible). Put this file (&#8221;deploy.rb&#8221;) in a directory called &#8220;config&#8221;. Be sure to adjust all parameters starting with a &#8220;#&#8221;.</p>
<div class="codesnip-container" >set :application, &#8220;webapps&#8221;<br />
set :repository, &#8220;#svn-path-to-your-webapps&#8221;        # i.e. https://server.com/repos/red5apps/webapps<br />
set :svn_username, &#8220;#svn_user&#8221;                      # svn user to use for checking out the application<br />
set :svn_password, Proc.new { Capistrano::CLI.password_prompt(&#8217;SVN Password: &#8216;) }<br />
# app roles<br />
role :app, &#8220;#example.com&#8221;                           # domain with s.s.h. access to deploy to<br />
set :user, &#8220;#user&#8221;                                  # user used for login<br />
# directories<br />
red5_dir = &#8220;#/etc/red5&#8243;                             # path on the server to your red5 directory<br />
set :deploy_to, &#8220;#/etc/red5/deploy_to_directory&#8221;    # directory where to check out your svn code<br />
# tasks<br />
task :restart do<br />
run &#8220;cd #{red5_dir} ; #{red5_dir}/red5-shutdown.sh &gt;&gt; #{red5_dir}/red5.log&#8221;<br />
run &#8220;cd #{red5_dir} ; nohup #{red5_dir}/red5.sh &gt;&gt; #{red5_dir}/red5.log &amp;\nsleep 5&#8243;<br />
end<br />
# overridden task<br />
desc &lt;&lt;-DESC<br />
Update all servers with the latest release of the source code. All this does<br />
is do a checkout (as defined by the selected scm module).<br />
DESC<br />
task :update_code, :except =&gt; { :no_release =&gt; true } do<br />
on_rollback { delete release_path, :recursive =&gt; true }<br />
source.checkout(self)<br />
set_permissions<br />
# uncache the list of releases, so that the next time it is called it will<br />
# include the newly released path.<br />
@releases = nil<br />
end</div>
<h2>Now what</h2>
<p>First step is to create the initial directory layout for your application on the server. Run the following command in the terminal/shell in the &#8220;webapps&#8221; directory:</p>
<div class="codesnip-container" >cap setup</div>
<p>When started, Capistrano will ask for your password to log into the server and create the appropriate directories you specified in the deploy.rb recipe. You can read more about this in the <a href="http://manuals.rubyonrails.com/read/book/17">Capistrano manual</a>, but basically it creates subdirectories like &#8220;releases&#8221;, &#8220;shared&#8221; where the application is going to be placed. Each deploy will create a new release and the directory &#8220;current&#8221; will be a symlink to the current release.</p>
<p>Next step on the server is to replace the Red5 &#8220;webapps&#8221; directory and create a symbolic link:</p>
<div class="codesnip-container" >cd #/etc/red5<br />
rm -rf webapps<br />
ln -s #/etc/red5/deploy_to_directory/current webapps</div>
<p>This makes sure that Red5 will always take the latest deployed release.</p>
<p>The final step is to deploy the application:</p>
<div class="codesnip-container" >cap deploy</div>
<p>This will checkout the latest release to the server, change the &#8220;current&#8221; symlink to this release (Red5 was configured to use the &#8220;current&#8221; directory) and will restart the Red5 server to use the latest version. If you&#8217;re running Tomcat it should be easy to change the task :restart&#8230;</p>
<p>And finally, in case you want to roll back to your previous version, just execute</p>
<div class="codesnip-container" >cap rollback</div>
<p>on your client and Capistrano will take care of it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomas-holl.com/wordpress/red5-application-deployment-with-capistrano/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Convert Generic Objects into Class Instances using JSON Schema</title>
		<link>http://www.thomas-holl.com/wordpress/convert-generic-objects-into-class-instances-using-json-schema/</link>
		<comments>http://www.thomas-holl.com/wordpress/convert-generic-objects-into-class-instances-using-json-schema/#comments</comments>
		<pubDate>Sat, 09 Jun 2007 18:12:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Actionscript]]></category>

		<guid isPermaLink="false">http://www.thomas-holl.com/wordpress/convert-generic-objects-into-class-instances-using-json-schema/</guid>
		<description><![CDATA[To convert plain old Actionscript objects into Value Objects I&#8217;ve created a generator (still in internal pre alpha mode) that will take (what I call) a &#8220;JSON Schema definition&#8221; file and generate the Actionscript Value Object classes.
In the &#8220;JSON Schema definition&#8221; (like XML Schema), the data structure is declared (but unlike XSDs, this is lightweight [...]]]></description>
			<content:encoded><![CDATA[<p>To convert plain old Actionscript objects into Value Objects I&#8217;ve created a generator (still in internal pre alpha mode) that will take (what I call) a &#8220;JSON Schema definition&#8221; file and generate the Actionscript Value Object classes.<br />
In the &#8220;JSON Schema definition&#8221; (like XML Schema), the data structure is declared (but unlike XSDs, this is lightweight and human readable). In fact, its valid <a href="http://www.json.org/">JSON</a> itself (so the parsing code in the generator reduces itself to a simple <i>json.parse(&#8230;)</i>). </p>
<p>You can also define nested structures (typed objects containing other typed objects) as well as typed arrays (array containing typed objects).</p>
<p>To proceed with an example, feed the generator the following JSON definition file:</p>
<div class="codesnip-container" >
<div class="codesnip"><span class="br0">&#123;</span> <br />
&nbsp; <span class="st0">&#8220;_class&#8221;</span>: <span class="st0">&#8220;Book&#8221;</span>,<br />
&nbsp; <span class="st0">&#8220;title&#8221;</span>: <span class="st0">&#8220;String&#8221;</span>,<br />
&nbsp; <span class="st0">&#8220;author&#8221;</span>: <span class="st0">&#8220;String&#8221;</span>,<br />
&nbsp; <span class="st0">&#8220;chapters&#8221;</span>: <br />
&nbsp; <span class="br0">&#91;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="st0">&#8220;_class&#8221;</span>: <span class="st0">&#8220;Chapter&#8221;</span>,<br />
&nbsp; &nbsp; &nbsp; <span class="st0">&#8220;name&#8221;</span>: <span class="st0">&#8220;String&#8221;</span>,<br />
&nbsp; &nbsp; &nbsp; <span class="st0">&#8220;pages&#8221;</span>: <span class="st0">&#8220;Int&#8221;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="br0">&#93;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p>And it will generate the following classes (package declarations omitted for readability):</p>
<div class="codesnip-container" >
<div class="codesnip"><span class="kw3">public</span> <span class="kw2">class</span> Book<br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw3">public</span> <span class="kw2">var</span> title:<span class="kw3">String</span>;<br />
&nbsp; <span class="kw3">public</span> <span class="kw2">var</span> author:<span class="kw3">String</span>;<br />
&nbsp; <span class="kw3">public</span> <span class="kw2">var</span> chapters:ChapterArray;</p>
<p>&nbsp; <span class="kw3">public</span> <span class="kw2">function</span> Book<span class="br0">&#40;</span>o:<span class="kw3">Object</span><span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; title = o.<span class="me1">title</span>;<br />
&nbsp; &nbsp; author = o.<span class="me1">author</span>;<br />
&nbsp; &nbsp; chapters = <span class="kw2">new</span> ChapterArray<span class="br0">&#40;</span>o.<span class="me1">chapters</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="kw3">public</span> <span class="kw2">class</span> Chapter<br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw3">public</span> <span class="kw2">var</span> <span class="kw3">name</span>:<span class="kw3">String</span>;<br />
&nbsp; <span class="kw3">public</span> <span class="kw2">var</span> pages:<span class="kw3">int</span>;</p>
<p>&nbsp; <span class="kw3">public</span> <span class="kw2">function</span> Chapter<span class="br0">&#40;</span>o:<span class="kw3">Object</span><span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw3">name</span> = o.<span class="kw3">name</span>;<br />
&nbsp; &nbsp; pages = o.<span class="me1">pages</span>;<br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="kw3">public</span> <span class="kw3">dynamic</span> <span class="kw2">class</span> ChapterArray <span class="kw3">extends</span> <span class="kw3">Array</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw3">public</span> <span class="kw2">function</span> ChapterArray<span class="br0">&#40;</span>o:<span class="kw3">Object</span><span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw3">super</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">for</span> each<span class="br0">&#40;</span><span class="kw2">var</span> item:<span class="kw3">Object</span> <span class="kw1">in</span> o<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw2">var</span> chapter:Chapter = <span class="kw2">new</span> Chapter<span class="br0">&#40;</span>item<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="kw3">this</span>.<span class="kw3">push</span><span class="br0">&#40;</span>chapter<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p>Now all you have to do when receiving plain old objects (via a webservice, json/http or any other method), all you have to do to convert them to typed objects is to call </p>
<div class="codesnip-container" >
<div class="codesnip"><span class="kw2">var</span> book:Book = <span class="kw2">new</span> Book<span class="br0">&#40;</span>event.<span class="me1">result</span><span class="br0">&#41;</span>;</div>
</div>
<p>And you&#8217;ll have all the benefits of having typed objects (like complete IDE support, etc.) as well as having your interface documented!</p>
<p>I&#8217;m interested in feedback about this method, so feel invited to comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomas-holl.com/wordpress/convert-generic-objects-into-class-instances-using-json-schema/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Managing Flex Modules</title>
		<link>http://www.thomas-holl.com/wordpress/managing-flex-modules/</link>
		<comments>http://www.thomas-holl.com/wordpress/managing-flex-modules/#comments</comments>
		<pubDate>Sun, 13 May 2007 14:11:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Flex]]></category>

		<category><![CDATA[Design]]></category>

		<category><![CDATA[MXML]]></category>

		<guid isPermaLink="false">http://www.thomas-holl.com/wordpress/managing-flex-modules/</guid>
		<description><![CDATA[When working with modules the &#8220;edit-compile-run&#8221; cycle can get in your way: Compiling the main application and then the separate modules, managing multiple Flex Builder/Ant projects, etc. For developing, it would be best to have just one big project. Here is how we do it&#8230;

Keep each of your modules in a separate directory, declaring it [...]]]></description>
			<content:encoded><![CDATA[<p>When working with modules the &#8220;edit-compile-run&#8221; cycle can get in your way: Compiling the main application and then the separate modules, managing multiple Flex Builder/Ant projects, etc. For developing, it would be best to have just one big project. Here is how we do it&#8230;</p>
<ul>
<li>Keep each of your modules in a separate directory, declaring it as <i>mx:Module</i> (in this example the module is <i>ImageManager</i>)</li>
<li>In your main application beneath your <i>src</i> directory, have the following two source directories:<br />
  <img src='http://www.thomas-holl.com/wordpress/wp-content/uploads/2007/05/directory-layout.png' alt='Directory Layout' /></p>
<ol>
<li>mod-access/extern<br />
  The ImageManagerAccess.mxl here is just a wrapper for the <i>mx:ModuleLoader</i>:</p>
<div class="codesnip-container" >
<div class="codesnip"><span class="sc3"><span class="re1">&lt;mx</span>:ModuleLoader xmlns:<span class="re0">mx</span>=<span class="st0">&#8220;http://www.adobe.com/2006/mxml&#8221;</span> <span class="re0">width</span>=<span class="st0">&#8220;100%&#8221;</span> <span class="re0">height</span>=<span class="st0">&#8220;100%&#8221;</span> <span class="re0">creationComplete</span>=<span class="st0">&#8220;url=&#8217;ImageManager.swf&#8217;; loadModule()&#8221;</span><span class="re2">/&gt;</span></span></div>
</div>
</li>
<li>mod-access/embed<br />
   The ImageManagerAccess.xml includes the Module <i>ImageManager</i> itself:</p>
<div class="codesnip-container" >
<div class="codesnip"><span class="sc3"><span class="re1">&lt;local</span>:ModAccessEmbed xmlns:<span class="re0">imageManager</span>=<span class="st0">&#8220;imageManager.*&#8221;</span> xmlns:<span class="re0">local</span>=<span class="st0">&#8220;*&#8221;</span> <span class="re0">width</span>=<span class="st0">&#8220;100%&#8221;</span> <span class="re0">height</span>=<span class="st0">&#8220;100%&#8221;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;imageManager</span>:imageManager<span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/local</span>:ModAccessEmbed<span class="re2">&gt;</span></span></div>
</div>
<p>  The class ModAccessEmbed mimics the behavior of the <i>mx:ModuleLoader</i> class. The code shows an excerpt </p>
<div class="codesnip-container" >
<div class="codesnip"><span class="kw3">public</span> <span class="kw2">class</span> ModAccessEmbed <span class="kw3">extends</span> Canvas<br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> loadModule<span class="br0">&#40;</span><span class="br0">&#41;</span> : <span class="kw3">void</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>&nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &#8230;<br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">var</span> <span class="kw3">url</span>:<span class="kw3">String</span>;<br />
&nbsp; &nbsp; &nbsp; &#8230; <span class="co1">// additional methods from mx:ModuleLoader as needed&nbsp; </span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</div>
</li>
</ol>
</li>
<li>Wherever you want the module to appear, don&#8217;t use a <i>mx:ModuleLoader</i>, but the corresponding <i>ImageManagerAccess</i></li>
<li>If you want your Flex project to contain all modules code in the main .swf, put <i>mod-access/embed</i> into your projects source path. If you want to build it separately, put <i>mod-access/extern</i> into your source path and remove the <i>mod-access/embed</i> line.</li>
</ul>
<p>This way, you can easily switch (by just swapping the source pathes) between building one swf that contains the complete modules and compiling main application and modules separately. Or use Flex Builder to develop the integrated version and an <i>Ant build.xml</i> for compiling the final application.swf as well as the swf for the modules.</p>
<h2>Useful links for working with modules/RSLs:</h2>
<ul>
<li><a href="http://weblogs.macromedia.com/pent/archives/2007/01/building_module.cfm">Peter Ent gives an overview about how to use modules</a></li>
<li><a href="http://flexblog.faratasystems.com/?p=147">Farata Systems has an article about various Flex tricks</a></li>
<li><a href="http://www.jamesward.org/wordpress/2007/02/19/faster-flex-applications-shrink-your-rsls/">James Ward shares his insights into compiling RSLs in order to to shrink them</a></li>
<li><a href="http://thanksmister.com/?p=56">This one describes problems with sharing stuff between the main application and the modules</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.thomas-holl.com/wordpress/managing-flex-modules/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Humble MXML</title>
		<link>http://www.thomas-holl.com/wordpress/the-humble-mxml/</link>
		<comments>http://www.thomas-holl.com/wordpress/the-humble-mxml/#comments</comments>
		<pubDate>Sat, 12 May 2007 09:18:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Flex]]></category>

		<category><![CDATA[Design]]></category>

		<category><![CDATA[MXML]]></category>

		<guid isPermaLink="false">http://thomas-holl.com/wordpress/the-humble-mxml/</guid>
		<description><![CDATA[While thinking about how to separate logic and user interface code on my current Flex project, I rerun into Michael Feathers great article about the &#8220;Humble Dialog Box&#8221;. I used this approach a couple of years before on a C++ project, was happy with it and I am now implementing it again. This article is [...]]]></description>
			<content:encoded><![CDATA[<p>While thinking about how to separate logic and user interface code on my current Flex project, I rerun into <a href="http://www.michaelfeathers.com/">Michael Feathers</a> great article about the <a href="http://www.objectmentor.com/resources/articles/TheHumbleDialogBox.pdf">&#8220;Humble Dialog Box&#8221;</a>. I used this approach a couple of years before on a C++ project, was happy with it and I am now implementing it again. This article is about how to realize this separation in a Flex/MXML environment.</p>
<p>The basic idea of separating logic and ui code is propably as old as the first graphical user interfaces itself. Even older is the tendency to &#8220;just add the cool new feature&#8221; then &#8220;applying a fix here&#8221; and before your realize it, you&#8217;re stuck with the ui class handling everything. To cite from the article: <em>&#8220;It is easy to just override an event from a component and drop your interaction logic right there in the dialog box class.&#8221;</em></p>
<p>And the Flex/MXML ecosystem is no exception: As easy as Flex makes it to chum out MXML code that looks and work like a charm, it is also really easy to be led into a design which puts everything into the MXML file itself. The examples by Adobe are leading you exactly there. To be fair, their goal is coming to the point of showing off what the Flex Framework can do and not educating you about proper practices.</p>
<h2>Example</h2>
<p>I&#8217;ll describe the concepts with my component <em>ImageManager</em> as an example. First a screenshot of the component:</p>
<p><a href="http://thomasholl.files.wordpress.com/2007/04/imagemanager.png" title="ImageManager component"><img src="http://thomasholl.files.wordpress.com/2007/04/imagemanager.png" alt="ImageManager component" /></a></p>
<p><em>ImageManager</em> will provide the user a list of tags (the list on the left hand side) and (depending on which tag was chosen by the user) display a TileList of Images according to the tag. Search tags can also be entered manually by the user via the TextInput field. The real search is done on a <a href="http://www.rubyonrails.org">Ruby on Rails</a> server in the background (but that&#8217;s another topic). If a user clicks on a tag, the TextInput field will be updated with the search tags (could be words more than just the tag from the list).</p>
<h2>Concept and Realisation</h2>
<p>The Humble Dialog Box (in this case The Humble MXML) suggests to refactor the .MXML file into 3 entities which each have exactly one reason to exist (and only one reason to change):</p>
<ol>
<li><em>ImageManager.mxml:</em> The user interface itself, the MXML class. This file should contain mostly MXML Nodes and almost no code</li>
<li><em>ImageManagerLogic.as:</em> The class handling the logic and only the logic. It communicates with the interface via the 3rd element, the interface</li>
<li><em>IImageManager.as:</em> The protocol to transfer information from the logic to the user interface</li>
</ol>
<p>Taking the logic out of the MXML and putting it into a separate class is pretty obvious. The <em>ImageManager.mxml</em> uses the <em>ImageManagerLogic</em> directly via a member-instance.</p>
<p>The interesting point in &#8220;The Humble MXML&#8221; is how to do the communication from the logic to the mxml. We don&#8217;t want the logic to depend on the user interface, so we obviously can&#8217;t reference the MXML file from the <em>ImageManagerLogic</em>. This is where the interface comes in: Put all callbacks from the logic into the <em>IImageManager</em> interface. In this example, when a user clicks the tags the TextInput has to be filled with the tags calculated by <em>ImageManagerLogic</em>. The <em>IImageManager</em> then looks like this:</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip"><span class="kw3">interface</span> IImageManager
<span class="br0">&#123;</span>
&nbsp; <span class="kw2">function</span> <span class="kw3">set</span> searchTags<span class="br0">&#40;</span>t:<span class="kw3">String</span><span class="br0">&#41;</span>:<span class="kw3">void</span>;
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>The <em>ImageManagerLogic</em> uses the <em>IImageManager</em> by calling <em>_view.searchTags = &#8230;</em>:</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip"><span class="kw2">class</span> ImageManagerLogic
<span class="br0">&#123;</span>
&nbsp; <span class="kw3">private</span> <span class="kw2">var</span> _view : IImageManager;

&nbsp; <span class="kw3">public</span> <span class="kw2">function</span> <span class="kw3">set</span> view<span class="br0">&#40;</span>v:IImageManager<span class="br0">&#41;</span>:<span class="kw3">void</span>
&nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; _view = v;
&nbsp; <span class="br0">&#125;</span>

&nbsp; <span class="kw3">public</span> <span class="kw2">function</span> selectTag<span class="br0">&#40;</span><span class="kw3">index</span>:<span class="kw3">int</span><span class="br0">&#41;</span>:<span class="kw3">void</span>
&nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; _view.<span class="me1">searchTags</span> = tags<span class="br0">&#91;</span><span class="kw3">index</span><span class="br0">&#93;</span>.<span class="me1">label</span>;
&nbsp; &nbsp; <span class="co1">// then go on and trigger the search</span>
&nbsp; <span class="br0">&#125;</span>

&nbsp; <span class="co1">// various private methods hidden</span>
&nbsp; <span class="kw3">public</span> <span class="kw2">function</span> searchForTags<span class="br0">&#40;</span>tags:<span class="kw3">String</span><span class="br0">&#41;</span>:<span class="kw3">void</span>
&nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="co1">// do the search</span>
&nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>In the implementation of <em>ImageManager.mxml</em> the following happens:</p>
<ul>
<li>The ImageManager.mxml implements the IImageManager interface (<em>implements=&#8221;IImageManager&#8221;</em>) and tells the logic to use it (<em>logic.view = this</em>)</li>
<li>The implementation of the IImageInterface just puts the tags into the TextInput field</li>
<li>All event handlers in the Layout just call the logic directly</li>
</ul>
<div class="codesnip-container" >
<div class="codesnip"><span class="sc3"><span class="re1">&lt;mx</span>:module <span class="re0">implements</span>=<span class="st0">&#8220;IImageManager&#8221;</span> <span class="re0">initialize</span>=<span class="st0">&#8220;logic.view = this&#8221;</span><span class="re2">&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;mx</span>:script<span class="re2">&gt;</span></span><br />
<span class="sc3"><span class="coMULTI">&lt;!&#8211;[CDATA[<br />
ImageManagerLogic logic;</p>
<p>// implements IImageManager<br />
public function set searchTags(tags:String):void<br />
{<br />
inputSearchTags.text = tags;<br />
}<br />
]]&#8211;&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;/mx</span>:script<span class="re2">&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;mx</span>:hdividedbox <span class="re0">width</span>=<span class="st0">&#8220;100%&#8221;</span> <span class="re0">height</span>=<span class="st0">&#8220;100%&#8221;</span><span class="re2">&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;mx</span>:list <span class="re0">width</span>=<span class="st0">&#8220;200&#8243;</span> <span class="re0">height</span>=<span class="st0">&#8220;100%&#8221;</span> <span class="re0">id</span>=<span class="st0">&#8220;list&#8221;</span><span class="re2">&gt;</span></span><br />
dataProvider=&quot;{logic.tags}&quot;<br />
click=&quot;logic.selectTag(list.selectedIndex)&quot; /<span class="sc1">&amp;gt;</span><br />
<span class="sc3"><span class="re1">&lt;mx</span>:vbox <span class="re0">width</span>=<span class="st0">&#8220;100%&#8221;</span> <span class="re0">height</span>=<span class="st0">&#8220;100%&#8221;</span><span class="re2">&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;mx</span>:hbox<span class="re2">&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;mx</span>:textinput <span class="re0">id</span>=<span class="st0">&#8220;inputSearchTags&#8221;</span><span class="re2">&gt;</span></span><br />
enter=&quot;logic.searchForTags(inputSearchTags.text)&quot;/<span class="sc1">&amp;gt;</span><br />
<span class="sc3"><span class="re1">&lt;mx</span>:button <span class="re0">label</span>=<span class="st0">&#8220;search&#8221;</span><span class="re2">&gt;</span></span><br />
click=&quot;logic.searchForTags(inputSearchTags.text)&quot;/<span class="sc1">&amp;gt;</span><br />
<span class="sc3"><span class="re1">&lt;/mx</span>:button<span class="re2">&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;mx</span>:tilelist <span class="re0">dataprovider</span>=<span class="st0">&#8220;{logic.images}&#8221;</span><span class="re2">&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;/mx</span>:tilelist<span class="re2">&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;/mx</span>:textinput<span class="re2">&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;/mx</span>:hbox<span class="re2">&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;/mx</span>:vbox<span class="re2">&gt;</span></span><span class="sc3"><span class="re1">&lt;/mx</span>:list<span class="re2">&gt;</span></span><span class="sc3"><span class="re1">&lt;/mx</span>:hdividedbox<span class="re2">&gt;</span></span><span class="sc3"><span class="re1">&lt;/mx</span>:module<span class="re2">&gt;</span></span></div>
</div>
<h2>So, what do you get?</h2>
<ul>
<li><strong>Clear design:</strong> It is pretty obvious where to put stuff and where to look for it. If it is how something should look like (layout, formatting), it belongs into the .mxml file. If it processes data or calculates stuff, it belongs to the logic</li>
<li><strong>Reusability:</strong> It is easy to e.g. create an advanced ui/dialog by just wiring a new MXML class with the existing logic code. Or use the logic somewhere else, perhaps reusing it in another, more complex logic block</li>
<li><strong>Testability of the logic</strong> (by using a mock object for the view): Because the MXML just contains call to the logic if something happens, it is very probably the bug is in the logic - there you can have automated tests and need not to worry about the gui</li>
</ul>
<h2>Some things to consider</h2>
<ul>
<li>The only code allowed in the markup part of the .MXML file are calls to the logic layer. If you need complex calculations of input data (e.g. combining strings) for the logic layer this could be a sign that this functionality belongs into the logic. If it really doesn&#8217;t, put it in the Script part</li>
<li>If there are no callbacks from the logic layer to the gui, you don&#8217;t need the interface <em>IImageManager</em></li>
</ul>
<h2>What does it cost?</h2>
<ul>
<li>You end up with 3 files instead of having just one. For small projects this may look like overkill, but even small projects can grow up real fast</li>
<li>Having to abstract the communication between the logic and the ui via an interface. For more complex patterns, this can be a real pain, but it is better to think about the protocol before instead of trying to seperate logic and ui at a later time when things got messed up</li>
</ul>
<h2>Opinions?</h2>
<ul>
<li>Do you consider this overkill?</li>
<li>Which unit testing frameworks do you use? Experiences?</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.thomas-holl.com/wordpress/the-humble-mxml/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
