<?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>MadeInFlex &#187; Cairngorm</title>
	<atom:link href="http://www.madeinflex.com/categoria/cairngorm/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.madeinflex.com</link>
	<description>Creando Soluciones RIA...</description>
	<lastBuildDate>Wed, 30 Nov 2011 16:04:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Cairngorm 3 Overview</title>
		<link>http://www.madeinflex.com/2011/01/22/cairngorm-3-overview/</link>
		<comments>http://www.madeinflex.com/2011/01/22/cairngorm-3-overview/#comments</comments>
		<pubDate>Sat, 22 Jan 2011 10:15:57 +0000</pubDate>
		<dc:creator>Sergi Dote Teixidor</dc:creator>
				<category><![CDATA[Artículos]]></category>
		<category><![CDATA[Cairngorm]]></category>
		<category><![CDATA[Flex 4]]></category>

		<guid isPermaLink="false">http://www.madeinflex.com/?p=2136</guid>
		<description><![CDATA[<!-- matched  --><!-- final 0 -->Ahora que Cairngorm 3  desde hace un tiempo ya es una realidad, on este artículo queremos mostrar que es, que nos aporta respecto a sus versiones anteriores y daremos un vistazo a su evolución.

Las versiones anteriores de Cairngorm se basaban en una implementación específica del patrón Model-View-Controller, en cambio Cairngorm 3, debido a la [...]]]></description>
			<content:encoded><![CDATA[<!-- matched  --><!-- final 0 --><p>Ahora que Cairngorm 3  desde hace un tiempo ya es una realidad, on este artículo queremos mostrar que es, que nos aporta respecto a sus versiones anteriores y daremos un vistazo a su evolución.<br />
<span id="more-2136"></span></p>
<p>Las versiones anteriores de Cairngorm se basaban en una implementación específica del patrón Model-View-Controller, en cambio Cairngorm 3, debido a la experiencia, quiere darnos una serie de guías, buenas prácticas y nos aporta unas librerías y herramientas para ayudarnos en el desarrollo.<br />
Esto implica que el paso de Cairngorm 2 a 3 no sea un simple un cambio de versión si no un cambio de paradigma.</p>
<p>El objetivo de Cairngorm 3 es dar unas bases para conseguir unos desarrollos limpios, consistentes, testeables y fácilmente escalables.</p>
<h2 id="toc-arquitectura-de-cairngorm"><strong>Arquitectura de Cairngorm</strong></h2>
<p>Para aproximarnos a un diseño simple y testeable, Cairngorm recomienda una arquitectura concreta para las aplicaciones Flex. Esta arquitectura tiene como objetivo que la estructura de la aplicación se desglose en pequeñas unidades de funcionalidad.</p>
<p>Antes de ver la separación arquitectural, entendamos como concibe Cairngorm una aplicación. Está compuesta de 3 capas de alto nivel: </p>
<ul>
<li>Capas de arquitectura: responsables de separar las clases según su responsabilidad</li>
<li>Áreas funcionales: agrupan clases que atañen el mismo ámbito funcional</li>
<li>Patrones de diseño: nos permiten coordinar los objetos de manera consistente</li>
</ul>
<h2 id="toc-capas-de-arquitectura"><strong>Capas de Arquitectura</strong></h2>
<p>Las clases con diferentes tipos de responsabilidad en las diferentes capas, pueden cambiarse separadamente por otras. De esta manera, si el diseño visual necesita ser ajustado, la mayoría de los cambios se limitan a clases de la capa de presentación y no a otras partes del código. </p>
<p>Cairngorm recomienda esta separación de capas según la responsabilidad general de cada una de ellas:</p>
<ul>
<li>Presentation: se encarga de la apariencia visual y del comportamiento de la presentación. Cairngorm recomienda el uso del patrón de presentación Presentation Model, que se encarga de controlar el estado y comportamiento de la capa de visualización.</li>
<li>Application: coordina la presentación y la infraestructura de componentes. Coordina los componentes de distintas capas y los enlaza con los Domain Objects mediante el concepto de Controller que ya veremos.</li>
<li>Domain: se centra en las tareas sobre el modelo de negocio. Representa una abstracción del mundo real mediante un modelo de datos. Sus responsabilidades suelen ser: la validación, cálculos sobre los datos, filtro, ordenación y formateo de datos…</li>
<li>Infrastructure: coordina los objetos y su integración con otros sistemas, como el servidor y sus servicios remotos.</li>
</ul>
<p>En la siguiente figura vemos la jerarquía de capas. De arriba hacia abajo, la comunicación entre una capa y su contigua es directa; en dirección contraria, la comunicación se realiza mediante eventos, callback functions u otras soluciones similares.<br />
<img src="http://www.madeinflex.com/wp-content/uploads/2011/01/layers.png" alt="layers" title="layers" width="186" height="193" class="aligncenter size-full wp-image-2140" /></p>
<h4 id="toc-areas-funcionales">Áreas funcionales</h4>
<p>Las aplicaciones se suelen dividir en diferentes áreas funcionales. La codificación de cada área funcional suele estar agrupada y separada de otras áreas funcionales, para que así sean desarrolladas y probadas de manera independiente. Podemos tener una aplicación de ejemplo que esté compuesta por tres áreas funcionales: contactos, mensajes y gastos. Entonces, cada una de estas áreas es subdividida según las distintas capas de arquitectura, según sea conveniente, como podemos ver en la siguiente imagen:<br />
<a href="http://www.madeinflex.com/wp-content/uploads/2011/01/areas-funcionales.png"><img src="http://www.madeinflex.com/wp-content/uploads/2011/01/areas-funcionales-300x162.png" alt="areas-funcionales" title="areas-funcionales" width="300" height="162" class="aligncenter size-medium wp-image-2143" /></a></p>
<p>Cada área funcional suele estar contenida en un package. Ciertas áreas funcionales, según su grado de relación, pueden estar contenidas en un proyecto separado y así extraerse en  módulos. El código que suele usarse en diferentes partes de la aplicación, como componentes, suelen ponerse dentro de un proyecto de librería.</p>
<p>Las áreas funcionales suelen tener sus capas de presentación y aplicación. A menudo contienen sus propias capas de dominio, pero otras veces comparten conocimiento del modelo de dominio de otras áreas. En este caso, estos modelos de dominio suelen ser encapsulados en proyectos de librería. Las áreas funcionales pueden interactuar con otras mediante interfaces y eventos AS3. </p>
<h2 id="toc-capa-de-presentacion"><strong>Capa de presentación</strong></h2>
<h4 id="toc-presentation-model">Presentation Model</h4>
<p>Una de las cosas que nos recomienda Cairngorm 3 es tender a minimizar el código dentro de los mxml. Si es posible debemos intentar no tener código ni funciones, así las vistas reducen su tamaño y se centran solo en la disposición de sus componentes; haciendo más fácil la lectura. </p>
<p>La manera de hacerlo es extrayendo las variables y funciones que estarían en el Script-block en presentation models.<br />
Cada componente o vista MXML significativa debe tener su propio presentation model. El PM se centra en el estado y comportamiento requeridos para representar los datos en la vista.</p>
<p>Un PM no debe saber nada de otro, ni de la vista relacionada ni de qué sirve a la aplicación. Un PM no debe tener referencia a la vista a la cual sirve, sino que es la vista que observa al PM relacionado. La comunicación entre ambos se realiza mediante Bindings o eventos. </p>
<p>Con esta aproximación minimizamos los errores en la vista y la lógica se localiza en el PM, que es fácilmente testeable.</p>
<h2 id="toc-coordinacion-entre-pms"><strong>Coordinación entre PMs</strong></h2>
<p>Cairngorm nos muestra dos entidades para coordinar los presentation models con otras entidades: Presenter y Controller. A continuación los vemos con mayor detalle.</p>
<h4 id="toc-presenters">Presenters</h4>
<p>Su ámbito se centra en la capa de presentación. Se encarga de la coordinación local entre Presentation Models de una misma área funcional o de una región de ésta. Entendemos pues que su rol está por encima de los PMs. </p>
<p>Sus principales objetivos son:</p>
<p>Desacoplar la presentación del Dominio<br />
<a href="http://www.madeinflex.com/wp-content/uploads/2011/01/presenter1.png"><img src="http://www.madeinflex.com/wp-content/uploads/2011/01/presenter1-300x210.png" alt="presenter1" title="presenter1" width="300" height="210" class="aligncenter size-medium wp-image-2150" /></a></p>
<p>Coordinación de PMs<br />
<a href="http://www.madeinflex.com/wp-content/uploads/2011/01/presenter2.png"><img src="http://www.madeinflex.com/wp-content/uploads/2011/01/presenter2-300x202.png" alt="presenter2" title="presenter2" width="300" height="202" class="aligncenter size-medium wp-image-2151" /></a><br />
Como vemos en la figura anterior, reducen el acoplamiento entre PMs y los domains, escuchando eventos procedentes de los domains y comunicándolos a los PMs. </p>
<p>También son usados para manejar los eventos procedentes de PMs y delegarlos a otros PMs.<br />
Las razones que nos pueden motivar a usar Presenters son:</p>
<ul>
<li>Facilitan la lectura y control a alto nivel de la coordinación entre PMs</li>
<li>Se encargan de asegurar el orden en la gestión de los eventos lanzados por los distintos PMs, ya que los mecanismos de mensajería, normalmente no suelen definir un orden</li>
<li>Evitan el código de gestión de eventos (event-handling) en cada PM para escuchar a las peticiones de los otros</li>
</ul>
<h4 id="toc-controllers">Controllers</h4>
<p>Los Controllers se sitúan en la capa de Application. Tienen la responsabilidad de gestionar la coordinación general de los Presenters, no en un ámbito local, sino más global de un grupo específico de PMs. Se encargan de:</p>
<ul>
<li>Traducir los eventos procedentes de un área funcional a eventos de otras áreas funcionales</li>
<li>Interceptar eventos a nivel de aplicación</li>
<li>Traducir los eventos de aplicación a llamadas de la API de dominio con la finalidad de mantener los objetos de dominio libres de cualquier conocimiento relacionado con otras capas arquitecturales</li>
</ul>
<p><a href="http://www.madeinflex.com/wp-content/uploads/2011/01/controller.png"><img src="http://www.madeinflex.com/wp-content/uploads/2011/01/controller-218x300.png" alt="controller" title="controller" width="218" height="300" class="aligncenter size-medium wp-image-2152" /></a></p>
<p>En situaciones determinadas, los PMs pueden comunicarse directamente con los objetos de dominio y recibir sus cambios mediante eventos, como podemos ver en la siguiente figura:<br />
<a href="http://www.madeinflex.com/wp-content/uploads/2011/01/pm-dm.png"><img src="http://www.madeinflex.com/wp-content/uploads/2011/01/pm-dm-300x196.png" alt="pm-dm" title="pm-dm" width="300" height="196" class="aligncenter size-medium wp-image-2153" /></a></p>
<h2 id="toc-aplicaciones-modulares"><strong>Aplicaciones Modulares</strong></h2>
<p>La modularidad va más allá de los conceptos de Flex Module y ModuleLoader. Implica la separación de aplicaciones en unidades pequeñas que pueden ser desarrolladas y testeadas independientemente. </p>
<h4 id="toc-beneficios-de-la-modularizacion">Beneficios de la Modularización</h4>
<ul>
<li>Un modulo puede ser desarrollado, y probado con una relativa independencia</li>
<li>Los tiempos de compilación se minimizan, ya que los cambios en un módulo no requieren de otros módulos</li>
<li>Los módulos pueden ser cargados bajo demanda, lo que hace que la carga inicial de la aplicación es mucho menor</li>
<li>Si un usuario no usa un determinado módulo, no es necesario cargarlo</li>
<li>Se pueden cargar diferentes módulos para distintos usuarios, según sus privilegios</li>
<li>Un modulo es más fácil de entender y mantener que una aplicación monolítica, consiguiendo una mejor cohesión funcional</li>
<li>La interacción entre módulos puede determinarse con APIs, independientemente del crecimiento de la aplicación</li>
</ul>
<h4 id="toc-modularizacion-y-cairngorm-3">Modularización y Cairngorm 3</h4>
<p>Como hemos visto, una de las claves de Cairngorm 3 es separa las aplicaciones en diferentes áreas funcionales que pueden ser desarrolladas independientemente; viene a ser una arquitectura modular, donde cada área funcional sería un módulo. Cairngorm recomienda que la comunicación entre las distintas áreas funcionales se haga mediante APIs definidas por interfaces, eventos y DTOs. Así minimizamos las dependencias entre las distintas áreas.</p>
<h2 id="toc-tendencia-hacia-el-bajo-acoplamiento"><strong>Tendencia hacia el bajo acoplamiento</strong></h2>
<p>Cairngorm 3 da mucha importancia a que las capas arquitecturales tengan un mínimo acoplamiento, asumiendo que cada capa cambia por motivos diferentes. Con un bajo acoplamiento en las distintas capas, éstas pueden tolerar mejor el cambio. Por otro lado, el bajo acoplamiento tiene un precio: cuanto menos acoplado esté un objeto a otro, se incrementa la dificultad de lectura.<br />
Hay distintas opciones para conseguir un bajo acoplamiento que los desarrolladores deben tener en cuenta.</p>
<h2 id="toc-opciones-para-construir-recuperar-y-aislar-objetos"><strong>Opciones para construir, recuperar y aislar objetos</strong></h2>
<p>La manera en que creamos, recuperamos o aislamos los objetos en una aplicación Flex, es un aspecto importante.<br />
Por ejemplo, creando un objeto de dominio dentro de un PM, provocamos una dependencia directa. Implica que el objeto queda aislado y si otra parte de la aplicación requiere este objeto, no tendrá acceso directo para consultarlo.</p>
<p>Además con esta dependencia forzada con el objeto de modelo dentro del PM, estamos atando fuertemente la capa de presentación a una implementación concreta del dominio. Con una interface del dominio y usando eventos, podemos bajar el acoplamiento, desacoplando las capas arquitecturales.</p>
<p>La implementación de un objeto de dominio no puede cambiarse sin cambiar la implementación del PM, lo cual puede restringir la flexibilidad de la aplicación.<br />
Los objetos de modelo tienen un significado a más alto nivel que el PM. Cuando el dominio puede abstraerse y controlarse con objetos de más alto nivel, conseguimos una inversión de control, que se opone a la aproximación usual de que objetos de bajo nivel controlan a otros.</p>
<h4 id="toc-opciones-de-separacion-de-la-construccion-y-comportamiento-de-los-objetos">Opciones de separación de la construcción y comportamiento de los objetos</h4>
<p>Puede ser muy incómodo para el PM substituir el objeto de dominio con una implementación diferente cuando el PM crea al objeto de dominio. Puede también ser muy incómodo el hecho de recuperar una misma instancia del dominio en un determinado lugar de la aplicación. Tenemos diferentes opciones de separar la creación del comportamiento de un objeto para simplificarlo, a continuación mostramos las dos más comunes.</p>
<ul>
<li>Aproximación transversal: El modelo de dominio se instancia en el PM o Vista de más alto nivel y se va propagando jerárquicamente a las subvistas o PMs relacionados.</li>
<li>Aproximación con framework de IoC: Se responsabilizan de la construcción de los objetos. El desarrollador especifica los objetos que se necesitan en el container de IoC.<br />
Así el framework IoC puede proporcionar estos objetos mediante inyección de dependencias o dependency lookup.</li>
</ul>
<h2 id="toc-librerias-que-nos-proporciona-cairngorm"><strong>Librerías que nos proporciona Cairngorm</strong></h2>
<p>Cairngorm 3 proporciona diferentes librerías, alguna de ellas construidas sobre frameworks existentes como Parsley, Swiz y Spring ActionScript.<br />
Estas librerías son interesantes, tenemos librerías para validación, para la gestión de popups, de navegación, gestión de módulos, etc. Recomiendo que leáis este apartado para que veáis que nos proporciona. </p>
<p>Para entender más como funciona Cairgorm 3 y los distintos conceptos, es necesario mirar y analizar un poco el código de las aplicaciones de ejemplo. </p>
<p>La información de Cairngorm 3 está en este <a href="http://sourceforge.net/adobe/cairngorm/home/">link</a>. </p>]]></content:encoded>
			<wfw:commentRss>http://www.madeinflex.com/2011/01/22/cairngorm-3-overview/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Cairngorm: Secuenciado de Commands</title>
		<link>http://www.madeinflex.com/2007/09/07/cairngorm-secuenciado-de-commands/</link>
		<comments>http://www.madeinflex.com/2007/09/07/cairngorm-secuenciado-de-commands/#comments</comments>
		<pubDate>Thu, 06 Sep 2007 23:08:00 +0000</pubDate>
		<dc:creator>Joan Garnet</dc:creator>
				<category><![CDATA[Cairngorm]]></category>
		<category><![CDATA[Casos de uso]]></category>

		<guid isPermaLink="false">http://www.madeinflex.com/2007/09/07/cairngorm-secuenciado-de-commands/</guid>
		<description><![CDATA[<!-- matched  --><!-- final 0 -->En según qué ocasiones podemos requerir que nuestra aplicación ejecute una serie de  Commands de forma asíncrona siguiendo un órden determinado.
Cairngorm viene de serie con la capacidad de encadenar Commands asíncronamente. La clase com.adobe.cairngorm.commands.SequenceCommand es la que se ocupa de que esto sea posible.
En esta entrada veremos dos formas de implementar el secuenciado. Una [...]]]></description>
			<content:encoded><![CDATA[<!-- matched  --><!-- final 0 --><p>En según qué ocasiones podemos requerir que nuestra aplicación ejecute una serie de  Commands de forma asíncrona siguiendo un órden determinado.<br />
<a href="http://www.madeinflex.com/2006/10/15/cairngorm-i-introduccion/">Cairngorm</a> viene de serie con la capacidad de encadenar Commands asíncronamente. La clase <strong>com.adobe.cairngorm.commands.SequenceCommand</strong> es la que se ocupa de que esto sea posible.<br />
En esta entrada veremos dos formas de implementar el secuenciado. Una de forma estática y la otra de forma dinámica.</p>
<p><span id="more-482"></span></p>
<div class="toc">
<ol>
<li><a href="http://www.madeinflex.com/2007/09/07/cairngorm-secuenciado-de-commands/#toc-encadenado-estatico">Encadenado estático</a></li>
<li><a href="http://www.madeinflex.com/2007/09/07/cairngorm-secuenciado-de-commands/#toc-encadenado-dinamico">Encadenado dinámico</a></li>
<li><a href="http://www.madeinflex.com/2007/09/07/cairngorm-secuenciado-de-commands/#toc-proyectos-de-ejemplo">Proyectos de ejemplo</a></li>
</ol>
</div>
<h2 id="toc-encadenado-estatico">Encadenado estático</h2>
<p>De forma nativa Cairngorm soporta encadenado estático de Commands, esto significa que para una secuencia dada deberemos crear una serie de Commands exclusiva para ésta.<br />
El principal problema que se nos puede plantear en este caso es que si queremos reutilizar un Command que ya forma parte de una secuencia no podremos. Nos veremos forzados a duplicar código.<br />
La causa de este problema viene del hecho que la clase SequenceCommand, la clase de la que extienden nuestros Commands a secuenciar, utiliza una propiedad <strong>nextEvent</strong> que es la que decide cuál es el siguiente Evento (y por consiguiente Command) que se va a ejecutar. La forma en la que los Commands son lanzados hace que sea imposible parametizar esta propiedad y por lo tanto se mantega estática.</p>
<p>Un ejemplo de un Command que forma parte de una secuencia:</p>
<p><b>HolaCommand.as (ejemplo estático)</b></p>
<div class="igBar"><span id="lactionscript3-5"><a href="#" onclick="javascript:showPlainTxt('actionscript3-5'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">Actionscript 3:</span>
<div id="actionscript3-5">
<div class="actionscript3">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #9900cc; font-weight: bold;">package</span> com.madeinflex.command</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> com.adobe.cairngorm.commands.ICommand;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> com.adobe.cairngorm.commands.SequenceCommand;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> com.adobe.cairngorm.control.CairngormEvent;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> com.madeinflex.event.MundoEvent;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> mx.controls.Alert;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> mx.events.CloseEvent;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #9900cc; font-weight: bold;">class</span> HolaCommand <span style="color: #0033ff; font-weight: bold;">extends</span> SequenceCommand implements ICommand</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> HolaCommand<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nextEvent = <span style="color: #0033ff; font-weight: bold;">new</span> MundoEvent<span style="color: #000000;">&#40;</span> MundoEvent.MOSTRAR_MUNDO <span style="color: #000000;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">override</span> <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> execute<span style="color: #000000;">&#40;</span> evt:CairngormEvent <span style="color: #000000;">&#41;</span>:<span style="color: #0033ff; font-weight: bold;">void</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Alert.<span style="color: #004993;">show</span><span style="color: #000000;">&#40;</span> <span style="color: #990000;">"Hola"</span>, <span style="color: #990000;">"HolaCommand"</span>, Alert.OK, <span style="color: #0033ff; font-weight: bold;">null</span>, onClose <span style="color: #000000;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> onClose<span style="color: #000000;">&#40;</span> evt:CloseEvent <span style="color: #000000;">&#41;</span>:<span style="color: #0033ff; font-weight: bold;">void</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; executeNextCommand<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000000;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #000000;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<h2 id="toc-encadenado-dinamico">Encadenado dinámico</h2>
<p>El encadenado dinámico es mucho más flexible que el estático dado que permite crear de forma dinámica las secuencias de Commands, de este modo podremos reutilizar un mismo Command para formar parte de diferentes secuencias o para ser lanzado individualmente.<br />
Para conseguir este objetivo nos vamos a servir de una <a href="http://cairngormdocs.org/blog/?p=27">colaboración que Bjorn Schultheiss</a> ha hecho al repositorio de recursos para Cairngorm: <a href="http://cairngormdocs.org/">cairngormdocs.com</a>.<br />
Se trata de dos clases: <strong>com.bjorn.event.ChainEvent</strong> y <strong>com.bjorn.event.EventChainFactory</strong>.<br />
La clase ChainEvent es un <em>wrapper</em> de com.adobe.cairngorm.control.CairngormEvent que añade la propiedad <strong>nextChainedEvent:ChainEvent</strong>, y la clase EventChainFactory es la que se ocupa de enlazar dinámicamente las diferentes instancias de eventos que queremos secuenciar. Se le pasa un Array de instancias de ChainEvent y va asignando de mayor a menor (en índice) cual es su <strong>nextEvent</strong>.</p>
<p>Un ejemplo de un Command que se añade dinámicamente a una secuencia, su evento relacionado y la forma de crear la secuencia:</p>
<p><b>HolaCommand.as (ejemplo dinámico)</b></p>
<div class="igBar"><span id="lactionscript3-6"><a href="#" onclick="javascript:showPlainTxt('actionscript3-6'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">Actionscript 3:</span>
<div id="actionscript3-6">
<div class="actionscript3">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #9900cc; font-weight: bold;">package</span> com.madeinflex.command</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> com.adobe.cairngorm.commands.ICommand;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> com.adobe.cairngorm.commands.SequenceCommand;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> com.adobe.cairngorm.control.CairngormEvent;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> com.bjorn.event.ChainEvent;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> com.madeinflex.event.MundoEvent;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> mx.controls.Alert;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> mx.events.CloseEvent;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #9900cc; font-weight: bold;">class</span> HolaCommand <span style="color: #0033ff; font-weight: bold;">extends</span> SequenceCommand implements ICommand</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">override</span> <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> execute<span style="color: #000000;">&#40;</span> evt:CairngormEvent <span style="color: #000000;">&#41;</span>:<span style="color: #0033ff; font-weight: bold;">void</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nextEvent = ChainEvent<span style="color: #000000;">&#40;</span> evt <span style="color: #000000;">&#41;</span>.nextChainedEvent;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Alert.<span style="color: #004993;">show</span><span style="color: #000000;">&#40;</span> <span style="color: #990000;">"Hola"</span>, <span style="color: #990000;">"HolaCommand"</span>, Alert.OK, <span style="color: #0033ff; font-weight: bold;">null</span>, onClose <span style="color: #000000;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> onClose<span style="color: #000000;">&#40;</span> evt:CloseEvent <span style="color: #000000;">&#41;</span>:<span style="color: #0033ff; font-weight: bold;">void</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; executeNextCommand<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000000;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #000000;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p><b>HolaEvent.as (ejemplo dinámico)</b></p>
<div class="igBar"><span id="lactionscript3-7"><a href="#" onclick="javascript:showPlainTxt('actionscript3-7'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">Actionscript 3:</span>
<div id="actionscript3-7">
<div class="actionscript3">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #9900cc; font-weight: bold;">package</span> com.madeinflex.event</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> com.bjorn.event.ChainEvent;&nbsp; </div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.events</span>.<span style="color: #004993;">Event</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #9900cc; font-weight: bold;">class</span> HolaEvent <span style="color: #0033ff; font-weight: bold;">extends</span> ChainEvent</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">public</span> static const MOSTRAR_HOLA:<span style="color: #004993;">String</span> = <span style="color: #990000;">"mostrar_hola"</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> HolaEvent<span style="color: #000000;">&#40;</span> <span style="color: #004993;">type</span>:<span style="color: #004993;">String</span> <span style="color: #000000;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">super</span><span style="color: #000000;">&#40;</span> <span style="color: #004993;">type</span> <span style="color: #000000;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">override</span> <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> <span style="color: #004993;">clone</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>:<span style="color: #004993;">Event</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">return</span> <span style="color: #0033ff; font-weight: bold;">new</span> HolaEvent<span style="color: #000000;">&#40;</span> <span style="color: #004993;">type</span> <span style="color: #000000;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000000;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #000000;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p><b>Creación dinámico de la secuencia</b></p>
<div class="igBar"><span id="lactionscript3-8"><a href="#" onclick="javascript:showPlainTxt('actionscript3-8'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">Actionscript 3:</span>
<div id="actionscript3-8">
<div class="actionscript3">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900; font-style: italic;">//(...)</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> empezarSecuencia1<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>:<span style="color: #0033ff; font-weight: bold;">void</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #000000;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #6699cc; font-weight: bold;">var</span> evts:<span style="color: #004993;">Array</span> = </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000000;">&#91;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">new</span> HolaEvent<span style="color: #000000;">&#40;</span> HolaEvent.MOSTRAR_HOLA <span style="color: #000000;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">new</span> MundoEvent<span style="color: #000000;">&#40;</span> MundoEvent.MOSTRAR_MUNDO <span style="color: #000000;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">new</span> ExclamacionEvent<span style="color: #000000;">&#40;</span> ExclamacionEvent.MOSTRAR_EXCLAMACION <span style="color: #000000;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000000;">&#93;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #6699cc; font-weight: bold;">var</span> chainEvent:ChainEvent = EventChainFactory.chainEvents<span style="color: #000000;">&#40;</span> evts <span style="color: #000000;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; chainEvent.dispatch<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #000000;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900; font-style: italic;">//(...) </span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<h2 id="toc-proyectos-de-ejemplo">Proyectos de ejemplo</h2>
<p>Incluyo dos proyectos muy simples de ejemplo. Uno para secuenciado estático y otro para secuenciado dinámico:</p>
<div class="files"><a href='http://www.madeinflex.com/img/entries/2007/09/cairngorm_sequencecommand_1.zip' title='Secuenciado estático de Commands'><img src="http://www.madeinflex.com/img/file_icons/zip_file_icon.jpg" alt="Secuenciado estático de Commands" title="Secuenciado estático de Commands" /></a><a href='http://www.madeinflex.com/img/entries/2007/09/cairngorm_sequencecommand_1.zip' title='Secuenciado estático de Commands'>Secuenciado estático de Commands</a></div>
<div class="files"><a href='http://www.madeinflex.com/img/entries/2007/09/cairngorm_sequencecommand_2.zip' title='Secuenciado dinámico de Commands'><img src="http://www.madeinflex.com/img/file_icons/zip_file_icon.jpg" alt="Secuenciado dinámico de Commands" title="Secuenciado dinámico de Commands" /></a><a href='http://www.madeinflex.com/img/entries/2007/09/cairngorm_sequencecommand_2.zip' title='Secuenciado dinámico de Commands'>Secuenciado dinámico de Commands</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.madeinflex.com/2007/09/07/cairngorm-secuenciado-de-commands/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Caso de estudio: FlexStore con Cairngorm</title>
		<link>http://www.madeinflex.com/2007/05/31/caso-de-estudio-flex-store-simplificado-version-cairngorm/</link>
		<comments>http://www.madeinflex.com/2007/05/31/caso-de-estudio-flex-store-simplificado-version-cairngorm/#comments</comments>
		<pubDate>Wed, 30 May 2007 22:23:46 +0000</pubDate>
		<dc:creator>Angel Blesa</dc:creator>
				<category><![CDATA[Cairngorm]]></category>
		<category><![CDATA[Casos de uso]]></category>

		<guid isPermaLink="false">http://www.madeinflex.com/2007/05/31/caso-de-estudio-flex-store-simplificado-version-cairngorm/</guid>
		<description><![CDATA[<!-- matched  --><!-- final 0 -->Con la idea de preparar varias aproximaciones a la solución de un mismo problema he pasado la aplicación Flex Store simplificada desarrollada por Joan Garnet tanto a cairngorm como a guasax.
En la primera versión que desarrolló Joan mostraba en el ejemplo una serie de buenas practicas en cuanto a la organización de código y separación [...]]]></description>
			<content:encoded><![CDATA[<!-- matched  --><!-- final 0 --><p>Con la idea de preparar varias aproximaciones a la solución de un mismo problema he pasado la <a href="http://www.madeinflex.com/2007/04/22/caso-de-estudio-flex-store-simplificado/">aplicación Flex Store simplificada</a> desarrollada por <a href="http://www.madeinflex.com/team/#toc-joan-garnet">Joan Garnet</a> tanto a <a href="http://www.cairngormdocs.org/">cairngorm</a> como a <a href="http://www.guasax.com/blog/">guasax</a>.</p>
<p>En la primera versión que desarrolló Joan mostraba en el ejemplo una serie de buenas practicas en cuanto a la organización de código y separación de conceptos dentro de una aplicación Flex simulando una Flex Store simplificada.</p>
<p>En este ejemplo vemos esa misma aplicación pasada, con los mínimos cambios posibles, a Cairngorm. </p>
<p><span id="more-441"></span></p>
<div class="toc">
<ol>
<li><a href="http://www.madeinflex.com/2007/05/31/caso-de-estudio-flex-store-simplificado-version-cairngorm/#toc-preparando-el-proyecto">Preparando el proyecto</a></li>
<li><a href="http://www.madeinflex.com/2007/05/31/caso-de-estudio-flex-store-simplificado-version-cairngorm/#toc-el-controlador-en-cairngorm">El controlador en Cairngorm</a></li>
<li><a href="http://www.madeinflex.com/2007/05/31/caso-de-estudio-flex-store-simplificado-version-cairngorm/#toc-creacion-de-las-clases-evento-y-commands">Creación de las clases Evento y Commands</a></li>
<li><a href="http://www.madeinflex.com/2007/05/31/caso-de-estudio-flex-store-simplificado-version-cairngorm/#toc-lanzando-los-eventos">Lanzando los eventos</a></li>
<li><a href="http://www.madeinflex.com/2007/05/31/caso-de-estudio-flex-store-simplificado-version-cairngorm/#toc-conclusiones">Conclusiones</a></li>
<li><a href="http://www.madeinflex.com/2007/05/31/caso-de-estudio-flex-store-simplificado-version-cairngorm/#toc-enlaces-y-recursos">Enlaces y recursos</a></li>
</ol>
</div>
<p>En primer lugar decir simplemente que debido al gran trabajo de joan , pasarlo a cairngorm ha resultado extremadamente directo, ya que la aplicación estaba muy preconcebida para ello.</p>
<p>Como punto de partida recomendamos leer nuevamente <a href="http://www.madeinflex.com/2007/04/22/caso-de-estudio-flex-store-simplificado/">el articulo </a>de Joan para centrar el tema de discusión.<br />
En este articulo simplemente mostraremos algunos cambios relevantes en el código entre las dos versiones. Esperamos que tanto esta versión como la basada en guasax sirva como piedra de toque para la adopción de determinado framework, si todavía no utilizamos uno,  entorno al cual organizar y hacer crecer nuestros proyectos de la mejor manera posible.</p>
<p>El ejemplo de la aplicación con (acceso al código fuente para descarga y visualización ) <a href="http://www.guasax.com/examples/tiendavirtualcairngorm/Main.html">se puede ver aqui.</a></p>
<p>La podéis <a href="http://guasax.googlecode.com/files/TiendaVirtualCairngorm.rar">descargar directamente aquí como proyecto</a> para importar directamente en Flex Builder , con la libreria de Cairngorm incluida.</p>
<h3 id="toc-preparando-el-proyecto">Preparando el proyecto</h3>
<p>Como podemos ver en la estructura de la aplicación, tenemos un directorio swclibs en el que tenemos la libreria swc de cairngorm que deberos cargar en el Flex Build Path de nuestra aplicación.<br />
Además en el fichero principal de la aplicación , en este caso el Main.mxml, debemos cargar el Controlador que se encargará de crear y añadir los eventos necesarios para el funcionamiento de la aplicación:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="450" height="250" id="ftf_wp" align="middle">
		  <param name="movie" value="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" />
		  <param name="quality" value="high" />
		  <param name="scale" value="noscale" />
		  <param name="bgcolor" value="#ffffff" />
		  <param name="flashvars" value="w=450&h=250&file=http://www.madeinflex.com/index.php&ftf=true&postID=441&no=0&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		  <embed src="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" quality="high" scale="noscale" bgcolor="#ffffff" width="450" height="250" name="ftf_wp" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="w=450&h=250&file=http://www.madeinflex.com/index.php&ftf=true&postID=441&no=0&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		</object></p>
<p>Como podemos ver en el código, a través de la instrucción "control:Controller"  inicializamos el singleton del Controller ,lo que hará que este declare los eventos, vincule los comandos que los van a atender , y los añada al FrontController. Una nota importante, si un evento no es añadido al FrontController , aunque lo disparemos , NO se ejecutará el Comando que tiene asociado. Por ello si disparáis un evento y veis que no se ejecuta el Comando asociado, revisar si habéis añadido esta relación en el Controller.<br />
Una vez cargado el Controller, vemos que en el método inicializaModeloDeDatos lanzamos el primer evento para que se ejecute una acción. En la linea comentada podéis observar la forma de hacerlo en la versión anterior.</p>
<h3 id="toc-el-controlador-en-cairngorm">El controlador en Cairngorm</h3>
<p>Cairngorm nos aporta un FrontController del cual podemos heredar para crear nuestro propio Controlador, en este controlador declararemos nuestros eventos y les asignaremos una clase Comando a cada uno de estos para que desarrollen su función.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="450" height="250" id="ftf_wp" align="middle">
		  <param name="movie" value="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" />
		  <param name="quality" value="high" />
		  <param name="scale" value="noscale" />
		  <param name="bgcolor" value="#ffffff" />
		  <param name="flashvars" value="w=450&h=250&file=http://www.madeinflex.com/index.php&ftf=true&postID=441&no=1&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		  <embed src="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" quality="high" scale="noscale" bgcolor="#ffffff" width="450" height="250" name="ftf_wp" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="w=450&h=250&file=http://www.madeinflex.com/index.php&ftf=true&postID=441&no=1&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		</object></p>
<h3 id="toc-creacion-de-las-clases-evento-y-commands">Creación de las clases Evento y Commands</h3>
<p>Partiendo de la clase Controlador del ejemplo inicial, en la que teníamos declarados los eventos que va a disparar la aplicación, así como los métodos que atienden a dichos eventos, podemos crear las clases comando para atender a cada uno de estos eventos que vamos a lanzar desde el código.<br />
Las clases Evento tiene pocos cambios respecto a la version anterior, simplemente heredan de la clase de Cairngorm CairngormEvent, la que les permitirá entre otras cosas, poder disparase directamente sin necesidad de utilizar la clase CairngormEventDispatcher.<br />
Para cada uno de los eventos y casos de uso que queremos lanzar en nuestra aplicación nos creamos una clase Comando. Para ello debemos implementar la interface ICommand.<br />
Aqui podemos ver un ejemplo de uno de los comandos de la aplicación:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="450" height="250" id="ftf_wp" align="middle">
		  <param name="movie" value="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" />
		  <param name="quality" value="high" />
		  <param name="scale" value="noscale" />
		  <param name="bgcolor" value="#ffffff" />
		  <param name="flashvars" value="w=450&h=250&file=http://www.madeinflex.com/index.php&ftf=true&postID=441&no=2&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		  <embed src="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" quality="high" scale="noscale" bgcolor="#ffffff" width="450" height="250" name="ftf_wp" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="w=450&h=250&file=http://www.madeinflex.com/index.php&ftf=true&postID=441&no=2&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		</object></p>
<p>Los métodos que en el ejemplo anterior teníamos en el Controlador , los hemos encapsulado en clases comando. Si desde estas clases comando tenemos que realizar llamadas a servicios remotos , estas llamadas se delegan en un BusinessDelegate que es el encargado de hacer la invocación al servicio remoto.</p>
<h3 id="toc-lanzando-los-eventos">Lanzando los eventos</h3>
<p>Para lanzar los eventos de Cairngorm lo podemos hacer a través del CairngormEventDispatcher  o directamente desde el propio evento , llamando al método dispatch();</p>
<p>Como podemos ver en esta porción de codigo:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="450" height="250" id="ftf_wp" align="middle">
		  <param name="movie" value="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" />
		  <param name="quality" value="high" />
		  <param name="scale" value="noscale" />
		  <param name="bgcolor" value="#ffffff" />
		  <param name="flashvars" value="w=450&h=250&file=http://www.madeinflex.com/index.php&ftf=true&postID=441&no=3&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		  <embed src="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" quality="high" scale="noscale" bgcolor="#ffffff" width="450" height="250" name="ftf_wp" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="w=450&h=250&file=http://www.madeinflex.com/index.php&ftf=true&postID=441&no=3&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		</object></p>
<p>vemos como desde una parte de la vista de nuestra aplicación, en el manejador del evento click, sobre un botón ponemos el disparo de algunos eventos. Desde el click del boton estamos desencadenando el evento que hará que se ejecute el comando que tenga asociado dicho evento, desde este comando llevaremos a cabo nuestra lógica de negocio , llamada a servicios remotos , y actualización de nuestro modelo de datos.</p>
<h3 id="toc-conclusiones">Conclusiones</h3>
<p>En este ejemplo hemos podido ver como Cairngorm nos aporta una cierta organización de código en torno a unos patrones de diseño. En el ejemplo preliminar el codigo ya estaba organizado en torno a unas practicas programativas similares por lo que la diferencia no es excesiva. Cairngorm nos aporta como valía añadida un FrontController con alguna función añadida, una forma de definir y consumir servicios remotos (a través del ServiceLocator) y una forma de vincular una evento con una clase que implemente el patrón Comando.</p>
<p>En el siguiente post mostraremos el mismo ejemplo en guasax para empezar a trabajar en algunas de las problemáticas que se plantean cuando creamos proyectos con un volumen de clases considerable  y debemos primar la reutilización de código así como la mantenibilidad de la aplicación.</p>
<p>Finalmente, agradecer a Joan las facilidades prestadas para utilizar su ejemplo como plataforma para trabajar este tipo de problemáticas en el desarrollo de  aplicaciones Flex.</p>
<h3 id="toc-enlaces-y-recursos">Enlaces y recursos</h3>
<p>- Articulo de <a href="http://www.madeinflex.com/team/#toc-joan-garnet">Joan</a> con la primera versión del <a href="http://www.madeinflex.com/2007/04/22/caso-de-estudio-flex-store-simplificado/">ejemplo Flex Store simplificado</a>.</p>
<p>- <a href="http://www.guasax.com/examples/tiendavirtualcairngorm/Main.html">Enlace online al ejemplo</a> con opción de ver codigo fuente con el boton derecho del raton. </p>
<p>- <a href="http://guasax.googlecode.com/files/TiendaVirtualCairngorm.rar">Enlace para descarga del proyecto</a> para importar directamente en Flex Builder con la librería de cairngorm incluida.</p>]]></content:encoded>
			<wfw:commentRss>http://www.madeinflex.com/2007/05/31/caso-de-estudio-flex-store-simplificado-version-cairngorm/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Flex 2.0.1 HotFix 2</title>
		<link>http://www.madeinflex.com/2007/05/25/flex-201-hotfix-2/</link>
		<comments>http://www.madeinflex.com/2007/05/25/flex-201-hotfix-2/#comments</comments>
		<pubDate>Fri, 25 May 2007 20:58:43 +0000</pubDate>
		<dc:creator>Alberto Albericio</dc:creator>
				<category><![CDATA[Cairngorm]]></category>
		<category><![CDATA[Noticias]]></category>

		<guid isPermaLink="false">http://www.madeinflex.com/2007/05/25/flex-201-hotfix-2/</guid>
		<description><![CDATA[<!-- matched  --><!-- final 0 -->Hoy se ha sacado el segundo HotFix para Flex 2.0.1. Como siempre, se han solventado diferentes bugs que la gente ha ido reportando desde el HotFix 1. 
Este HotFix se lanza en conjunción con la nueva versión de Flex Data Services, LiveCycle® Data Services ES 2.5.
Además, para aquellos que utilicéis Cairngorm, como algunas de las [...]]]></description>
			<content:encoded><![CDATA[<!-- matched  --><!-- final 0 --><p><!-- flex update hotfix framework sdk --><br />
Hoy se ha sacado el segundo HotFix para Flex 2.0.1. Como siempre, se han solventado diferentes bugs que la gente ha ido reportando desde el HotFix 1. </p>
<p>Este HotFix se lanza en conjunción con la nueva versión de Flex Data Services, LiveCycle® Data Services ES 2.5.</p>
<p>Además, para aquellos que utilicéis Cairngorm, como algunas de las clases de Flex se han movido del SDK principal a LCDS, tambien se ha generado un nuevo release de Cairngorm a efectos de compatibilidad entre ambos.</p>
<p>Podéis descargaros el HotFix 2 en:</p>
<p><a href="http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=kb401825">Flex 2.0.1 HotFix 2</a></p>
<p>Para quien utilice Cairngorm, podréis encontrar la nueva versión en:</p>
<p><a href="http://labs.adobe.com/wiki/index.php/Cairngorm">Cairngorm</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.madeinflex.com/2007/05/25/flex-201-hotfix-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ejemplo Cairngorm 2.2 con AMFPHP 1.9</title>
		<link>http://www.madeinflex.com/2007/05/21/ejemplo-cairngorm-22-con-amfphp-19/</link>
		<comments>http://www.madeinflex.com/2007/05/21/ejemplo-cairngorm-22-con-amfphp-19/#comments</comments>
		<pubDate>Mon, 21 May 2007 17:29:23 +0000</pubDate>
		<dc:creator>Joan Garnet</dc:creator>
				<category><![CDATA[Cairngorm]]></category>
		<category><![CDATA[Casos de uso]]></category>

		<guid isPermaLink="false">http://www.madeinflex.com/2007/05/21/ejemplo-cairngorm-22-con-amfphp-19/</guid>
		<description><![CDATA[<!-- matched  --><!-- final 0 -->Presento un caso de uso de Cairngorm 2.2 incluyendo las últimas convenciones y funcionalidades. Ideal para iniciarse a la arquitectura por ser muy básico (es un formulario de Login).
El ejemplo consume servicios sobre AMFPHP 1.9 para poder mostrar también como pasar objetos tipados de Flex a PHP y viceversa.
Descargar ejemplo: Ejemplo Cairngorm 2.2 con amfphp [...]]]></description>
			<content:encoded><![CDATA[<!-- matched  --><!-- final 0 --><p>Presento un caso de uso de <a href="http://labs.adobe.com/wiki/index.php/Cairngorm:Cairngorm2.2:Release_Notes">Cairngorm 2.2</a> incluyendo las últimas convenciones y funcionalidades. Ideal para iniciarse a la arquitectura por ser muy básico (es un formulario de Login).<br />
El ejemplo consume servicios sobre AMFPHP 1.9 para poder mostrar también como pasar objetos tipados de Flex a PHP y viceversa.<br />
Descargar ejemplo: <a href='http://www.madeinflex.com/img/entries/2007/05/cairngorm2_2_loginsample.zip' title='Ejemplo Cairngorm 2.2 con amfphp 1.9 (Login)'>Ejemplo Cairngorm 2.2 con amfphp 1.9 (Login)</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.madeinflex.com/2007/05/21/ejemplo-cairngorm-22-con-amfphp-19/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Cairngorm 2.2</title>
		<link>http://www.madeinflex.com/2007/05/01/cairngorm-22/</link>
		<comments>http://www.madeinflex.com/2007/05/01/cairngorm-22/#comments</comments>
		<pubDate>Mon, 30 Apr 2007 23:41:02 +0000</pubDate>
		<dc:creator>Carlos Rovira</dc:creator>
				<category><![CDATA[Cairngorm]]></category>
		<category><![CDATA[LCDS]]></category>

		<guid isPermaLink="false">http://www.madeinflex.com/2007/05/01/cairngorm-22/</guid>
		<description><![CDATA[<!-- matched  --><!-- final 0 -->Hace unos días apareció una pequeña actualización de la micro-arquitectura de patrones Cairngorm. La nueva versión 2.2 la podeis descargar desde su página en Adobe Labs. La principal novedad es la separación del framework base de la parte empresarial representada por los Live Cycle Data Services, de forma que no exitan dependencias. Es decir, ahora [...]]]></description>
			<content:encoded><![CDATA[<!-- matched  --><!-- final 0 --><p>Hace unos días apareció una pequeña actualización de la micro-arquitectura de patrones Cairngorm. La nueva versión 2.2 la podeis descargar desde su página en <a href="http://labs.adobe.com/wiki/index.php/Cairngorm:Cairngorm2.2:Download">Adobe Labs</a>. La principal novedad es la separación del framework base de la parte empresarial representada por los <a href="http://www.madeinflex.com/2007/03/21/disponible-adobe-livecycle-data-services-25/">Live Cycle Data Services</a>, de forma que no exitan dependencias. Es decir, ahora tendremos también un <strong>Cairngorm Enterprise</strong> que usaremos si trabajamos con <strong>Live Cycle Data Services</strong>.</p>
<p><span id="more-357"></span></p>
<p>Algunos cambios interesantes son:</p>
<ul>
<li>Los eventos son capaces de despacharse ellos mismos mediante el método "<em>dispatch()</em>". Ya no es necesario usar <em>CairngormEventDispatcher</em>.</li>
<li>Como era de esperar la interface <em>ModelLocator</em> ha sido deprecada en favor de <em>IModelLocator</em>.</li>
<li>Los comandos son añadidos al controlador con <em>weak references</em> de forma que el GC sea más efectivo. Además podemos eliminar commandos registrados en el <em>FrontController</em> mediante "<em>removeCommand</em>".</li>
<li>Por fin los <em>SWC</em> ocupan unos pocos Kbs ya que no tienen las clases del framework de Flex linkadas.</li>
<li>Se arregla un bug en los <em>Web Services</em> que hacian imposible cargar un <em>WSDL</em></li>
</ul>
<p>Podeis leer el resto en las <a href="http://labs.adobe.com/wiki/index.php/Cairngorm:Cairngorm2.2:Release_Notes">release notes</a> de Adobe Labs. </p>]]></content:encoded>
			<wfw:commentRss>http://www.madeinflex.com/2007/05/01/cairngorm-22/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cairngorm VIII: Model Locator</title>
		<link>http://www.madeinflex.com/2007/01/24/cairngorm-viii-model-locator/</link>
		<comments>http://www.madeinflex.com/2007/01/24/cairngorm-viii-model-locator/#comments</comments>
		<pubDate>Wed, 24 Jan 2007 08:20:35 +0000</pubDate>
		<dc:creator>Xavi Beumala</dc:creator>
				<category><![CDATA[Cairngorm]]></category>

		<guid isPermaLink="false">http://www.madeinflex.com/2007/01/24/cairngorm-viii-model-locator/</guid>
		<description><![CDATA[<!-- matched  --><!-- final 0 -->En una aplicación se suele tratar con muchos datos que se visualizan de forma distinta dependiendo del punto de la navegación en el que se encuentre el usuario.  Además puede ser que un mismo conjunto de datos se muestre a la vez (gráfico + tabla). Supongamos el caso en el que se hace una [...]]]></description>
			<content:encoded><![CDATA[<!-- matched  --><!-- final 0 --><p>En una aplicación se suele tratar con muchos datos que se visualizan de forma distinta dependiendo del punto de la navegación en el que se encuentre el usuario.  Además puede ser que un mismo conjunto de datos se muestre a la vez (gráfico + tabla). Supongamos el caso en el que se hace una petición a un service a través de un command y se pintan los mismos datos en una taba y en un gráfico estadístico. Si en una petición posterior los datos variasen se tendrían que actualizar todas las vistas dependientes.</p>
<p><span id="more-94"></span><br />
Con el fin de no tener que gestionar todos los destinos de un mismo modelo de datos, se afronta el desarrollo de un ModelLocator, que viene a ser un repositorio común de datos implementado en forma de Singleton (GoF). Si un comando actualiza un determinado conjunto de datos las vistas que utilizan esos datos, serán notificadas, actualizando así su representación. Esto se hace a través de Bindings.</p>
<p>El ModelLocator no suele tener mucha lógica y en muchos casos se puede reducir a una clase con múltiples propiedades (modelo de datos de la aplicación). El acceso de escritura sobre estos atributos  se reserva (por convenio) a los commands, que cargarán en las propiedades los valores recibidos del servidor.</p>
<p>Una vez los datos estén censados en el ModelLocator, y casi siempre a través de Bindings, las distintas vistas suscritas a ellos se actualizarán de forma automática. Es una buena práctica que siempre que queramos hacer cambios sobre nuestras vistas, lo hagamos en el modelo de tal forma que los cambios se propaguen a todas las dependencias visuales que existan.</p>
<p>Tal y como comentamos en el punto de eventos, los bindings funcionan siguiendo el principio del patrón Observer (GoF). Con lo cual podríamos ver el ModelLocator como la entidad encargada de gestionar el modelo  consumidor / productor de datos. Los commands serían productores de datos mientras que las distintas vistas serían los consumidores de éstos mismos.</p>
<p>Con este artículo cerramos la serie teórica sobre Cairngorm. Espero en breve empezar con la serie de casos de usos prácticos. Dejo aquí links a todos los artículos de la serie.</p>
<ol>
<li><a  href="http://www.madeinflex.com/2006/10/15/cairngorm-i-introduccion/">Cairngorm I: Introducción.</a></li>
<li><a href="http://www.madeinflex.com/2006/10/15/cairngorm-ii-value-objects/">Cairngorm II: Value Objects.</a></li>
<li><a href="http://www.madeinflex.com/2006/10/21/cairngorm-iii-commands/">Cairngorm III: Commands.</a></li>
<li><a href="http://www.madeinflex.com/2006/10/26/cairngorm-iv-frontcontroller/">Cairngorm IV: FrontController.</a></li>
<li><a href="http://www.madeinflex.com/2006/11/15/cairngorm-v-eventos/">Cairngorm V: Eventos.</a></li>
<li><a href="http://www.madeinflex.com/2007/01/21/cairngorm-viservices-y-servicelocator/">Cairngorm VI: Services y ServiceLocator.</a></li>
<li><a href="http://www.madeinflex.com/2007/01/23/cairngorm-vii-business-delegate/">Cairngorm VII: Business Delegate.</a></li>
<li><a href="">Cairngorm VIII: Model Locator.</a></li>
</ol>]]></content:encoded>
			<wfw:commentRss>http://www.madeinflex.com/2007/01/24/cairngorm-viii-model-locator/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Cairngorm VII: Business Delegate</title>
		<link>http://www.madeinflex.com/2007/01/23/cairngorm-vii-business-delegate/</link>
		<comments>http://www.madeinflex.com/2007/01/23/cairngorm-vii-business-delegate/#comments</comments>
		<pubDate>Tue, 23 Jan 2007 08:59:13 +0000</pubDate>
		<dc:creator>Xavi Beumala</dc:creator>
				<category><![CDATA[Cairngorm]]></category>

		<guid isPermaLink="false">http://www.madeinflex.com/2007/01/23/cairngorm-vii-business-delegate/</guid>
		<description><![CDATA[<!-- matched  --><!-- final 0 -->En el post anterior vimos que los commands son stateless y que son el núcleo funcional de las distintas partes de una aplicación. Poniendo el ejemplo de  "cargar los datos de un usuario dadoÃ¯¿Â½? veamos cómo abordaríamos su implementación a alto nivel.
El command tendría que utilizar un service que le permitiera establecer una conexión [...]]]></description>
			<content:encoded><![CDATA[<!-- matched  --><!-- final 0 --><p><a href="http://www.madeinflex.com/2007/01/21/cairngorm-viservices-y-servicelocator/">En el post anterior</a> vimos que los commands son stateless y que son el núcleo funcional de las distintas partes de una aplicación. Poniendo el ejemplo de  "cargar los datos de un usuario dadoÃ¯¿Â½? veamos cómo abordaríamos su implementación a alto nivel.</p>
<p>El command tendría que utilizar un service que le permitiera establecer una conexión con la parte servidora. Si por ejemplo tenemos una página .aspx, .jsp, .php, un servlet, etc que pasándole como parámetro un id nos devuelve en formato xml la información de un usuario. Tendríamos que declarar este service en nuestro serviceLocator.<br />
<span id="more-93"></span><br />
Posteriormente podríamos invocar la petición desde cualquier command. Veamos un pequeño ejemplo:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="500" height="300" id="ftf_wp" align="middle">
		  <param name="movie" value="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" />
		  <param name="quality" value="high" />
		  <param name="scale" value="noscale" />
		  <param name="bgcolor" value="#ffffff" />
		  <param name="flashvars" value="w=500&h=300&file=http://www.madeinflex.com/index.php&ftf=true&postID=93&no=0&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		  <embed src="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" quality="high" scale="noscale" bgcolor="#ffffff" width="500" height="300" name="ftf_wp" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="w=500&h=300&file=http://www.madeinflex.com/index.php&ftf=true&postID=93&no=0&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		</object></p>
<p>La implementación podría quedar así y sería totalmente válida. Pero fijémonos que en ningún lado hemos hablado de lo que se hará una vez se obtenga la respuesta de la invocación del servicio. Seguramente un servicio o un método de este pueda invocarse de distintas formas (comando) y cada una de ellas tratará los resultados de una forma distinta. </p>
<p>Vemos entonces que la invocación de los servicios tiene que parametrizar siempre la forma de tratar la respuesta. Para solventar esto se introduce el concepto de Responder. A nivel implementacional no es más una interface que define un método result y otro fault que se ejecutarán cuando el resultado de la invocación del service sean satisfactoria o no.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="500" height="500" id="ftf_wp" align="middle">
		  <param name="movie" value="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" />
		  <param name="quality" value="high" />
		  <param name="scale" value="noscale" />
		  <param name="bgcolor" value="#ffffff" />
		  <param name="flashvars" value="w=500&h=500&file=http://www.madeinflex.com/index.php&ftf=true&postID=93&no=1&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		  <embed src="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" quality="high" scale="noscale" bgcolor="#ffffff" width="500" height="500" name="ftf_wp" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="w=500&h=500&file=http://www.madeinflex.com/index.php&ftf=true&postID=93&no=1&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		</object></p>
<p>Paralelamente a este problema en un desarrollo distribuido cliente/servidor normalmente trabajan distintos perfiles: especialistas cliente y especialistas servidor. Es muy normal que las fases de desarrollo cliente / servidor se paralelicen, de tal forma que el desarrollo de la parte cliente pueda continuar sin necesidad de que la parte servidora esté completa.<br />
Esta es una de las justificaciones del patrón Business Delegate, el cual permite crear una capa temporal que gestione las respuestas y que en determinadas situaciones pueda simular una parte del aplicativo aún por desarrollar devolviendo Mock Objects (Objetos generados de forma hard coded que emulan una posible respuesta).</p>
<p>Resumiendo, los Business Delegate nos permiten gestionar la forma en cómo tratar las respuestas recibidas desde el servidor así como el simularlas agilizando el desarrollo.</p>
<p>Tal como comentábamos en el punto uno (Value Objects), en un aplicativo se debería tratar siempre con ValueObjects transversales a la tecnología utilizada en las distintas capas, es conveniente tratar con objetos que no comprometan el futuro de nuestras aplicaciones. Tal como comentábamos aunque nuestro aplicativo consuma datos dinámicos en formato XML, SOAP, etc. es muy interesante convertirlos a VOÃ¢â‚¬â„¢s. Los delegates al tener el control sobre las invocaciones al servidor y a sus respuestas, es el sitio ideal donde hacer el tratamiento de la información recibida y por ejemplo parsear de XML a VOÃ¢â‚¬â„¢s.</p>
<p>Los delegates también son la parte que aislan la aplicacición de la tecnología utilizada en el servidor. Si tenemos un aplicativo que consume datos en formato XML y queremos pasar a utilizar FDS o cualquier otra solución basada en AMF sólo tendríamos que cambiar el delegate.<br />
Veamos un ejemplo de un delegate:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="500" height="500" id="ftf_wp" align="middle">
		  <param name="movie" value="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" />
		  <param name="quality" value="high" />
		  <param name="scale" value="noscale" />
		  <param name="bgcolor" value="#ffffff" />
		  <param name="flashvars" value="w=500&h=500&file=http://www.madeinflex.com/index.php&ftf=true&postID=93&no=2&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		  <embed src="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" quality="high" scale="noscale" bgcolor="#ffffff" width="500" height="500" name="ftf_wp" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="w=500&h=500&file=http://www.madeinflex.com/index.php&ftf=true&postID=93&no=2&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		</object></p>
<p>Un uso muy potente que podríamos dar a los delegates consistiría en definirlos implementando una interface. Si tenemos varias implementaciones, estas serían intercambiables. Si en los commands referenciármos al delegate a través de su interface y no a través de su implementación concreta obtendríamos un sistema capaz de consumir los mismos datos pero a partir de fuentes distintas. Esta solución se podría usar por ejemplo en sistemas de alto tráfico donde en determinados momentos convendría consumir datos de forma dinámica (FDS, xml dinámico a partir de .phh, .asp, .jsp, servlets, etc) o a partir de ficheros estáticos en formato xml previamente generados en el servidor.</p>]]></content:encoded>
			<wfw:commentRss>http://www.madeinflex.com/2007/01/23/cairngorm-vii-business-delegate/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Cairngorm VI:Services y ServiceLocator</title>
		<link>http://www.madeinflex.com/2007/01/21/cairngorm-viservices-y-servicelocator/</link>
		<comments>http://www.madeinflex.com/2007/01/21/cairngorm-viservices-y-servicelocator/#comments</comments>
		<pubDate>Sun, 21 Jan 2007 11:22:54 +0000</pubDate>
		<dc:creator>Xavi Beumala</dc:creator>
				<category><![CDATA[Cairngorm]]></category>

		<guid isPermaLink="false">http://www.madeinflex.com/2007/01/21/cairngorm-viservices-y-servicelocator/</guid>
		<description><![CDATA[<!-- matched  --><!-- final 0 -->Tal como comentábamos en el último artículo un Command es transversal a las capas de influencia. Aunque un command esté especializado en una tarea muy concreta, esta tarea puede afectar al modelo, a la capa visual o a la capa de negocio.
Es normal que muchos de los commands afecten al modelo de datos, el cual [...]]]></description>
			<content:encoded><![CDATA[<!-- matched  --><!-- final 0 --><p>Tal como comentábamos en <a href="http://www.madeinflex.com/2006/11/15/cairngorm-v-eventos/">el último artículo</a> un Command es transversal a las capas de influencia. Aunque un command esté especializado en una tarea muy concreta, esta tarea puede afectar al modelo, a la capa visual o a la capa de negocio.</p>
<p>Es normal que muchos de los commands afecten al modelo de datos, el cual podríamos ver como una capa compartida entre cliente y servidor, introduciendo así el canal de comunicación. Si por ejemplo realizamos una petición al servidor para cargar datos en formato xml, estos datos (modelo) quedarán cargados en el cliente pero los ha facilitado el servidor (modelo compartido).<br />
<span id="more-92"></span><br />
Por ejemplo, un comando podría ser el responsable de grabar los datos obtenidos a través de un formulario en una tabla de una BBDD (persistencia de datos) pasando a través de algún DAO. Al tratarse de una aplicación cliente, ésta desconoce 100% la lógica interna de la aplicación servidora que almacenará esta información (DAO). La aplicación cliente sólo sabe qué parámetros va a necesitar su homólogo en la parte servidora. Es por ello que desde el lado cliente se recogen los datos y se delega en la parte controladora del lado del servidor la serialización y la persistencia así como el resto de tareas asociadas a la BBDD de estos datos.</p>
<p>La parte cliente se ocupará de gestionar la transacción con el servidor (que la comunicación sea satisfactoria), que los datos tengan coherencia e integridad (filtros y validadores) y de pasarle en un formato conocido por ambas partes los datos necesarios (VOÃ¢â‚¬â„¢s si usamos RemoteObject, XML si usamos HttpService o SOAP).</p>
<p>Introducimos el concepto de Servicio como el homólogo, en la parte cliente, de la business logic de servidor. Por ejemplo el servidor es el responsable y conocedor de cómo trabajar con la BBDD a través de DAOÃ¢â‚¬â„¢s (Data Access Objects), de cómo crear nuevos registros, modificarlos y eliminarlos. En la parte cliente existe su homólogo pero en vez de saber cómo realizar estas acciones directamente, sabe cómo delegar la responsabilidad a la parte servidora. En algunos casos se utilizará HTTPService en otros RemoteObject o WebService, etc.</p>
<p>Por ejemplo, en el cliente tenemos un formulario de alta de usuario. Los campos de este formulario se tienen que terminar serializando en una BBDD. La forma en que podríamos hacerlo:</p>
<ul>
<li>Si la aplicación servidora está basada en URLÃ¢â‚¬â„¢s (dependiendo de los parámetros se ejecuta una acción u otra sobre los datos) como por ejemplo Spring, Struts, etc. nuestra aplicación constaría de un servicio HTTPService que referenrenciaría a la url pertinente.</li>
<li>Si la aplicación servidora funciona sobre FDS, openAMF, amfPHP, etc. nuestra aplicación constaría de un service por cada una de las clases mapeadas.</li>
<li>Si la aplicación servidora consiste en un servicio SOAP, nuestra aplicación constaría de un servicio WebService.</li>
</ul>
<p>Estos servicios simplemente ejecutan el código en el servidor pasándole los parámetros que requieran y recogen la respuesta que el servidor genere.</p>
<p>Estos servicios tienen que ser accesibles desde cualquier parte de la aplicación y tienen que ser únicos. Esto es, si queremos invocar dos veces a un servicio SOAP con paremetrización diferente y desde puntos distintos de nuestra aplicación no tendríamos que reinstanciar a los servicios.<br />
Para evitar la duplicidad de los servicios introducimos el patrón ServideLocator que implementa una singleton garantizando así una existencia única.</p>
<p>A través del ServiceLocator podremos acceder así a los servicios disponibles (declarados) para la aplicación sin tener que declararlos una y otra vez. Garantizando así la escalabilidad de su mantenimiento y la facilidad para el cambio (p.e cambio en la url de los servicios o un cambio de mapping).</p>]]></content:encoded>
			<wfw:commentRss>http://www.madeinflex.com/2007/01/21/cairngorm-viservices-y-servicelocator/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>El Tag &#8220;Observer&#8221;</title>
		<link>http://www.madeinflex.com/2006/12/17/el-tag-observer/</link>
		<comments>http://www.madeinflex.com/2006/12/17/el-tag-observer/#comments</comments>
		<pubDate>Sun, 17 Dec 2006 21:54:12 +0000</pubDate>
		<dc:creator>Carlos Rovira</dc:creator>
				<category><![CDATA[Cairngorm]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://www.madeinflex.com/2006/12/17/el-tag-observer/</guid>
		<description><![CDATA[<!-- matched  --><!-- final 0 -->En los últimos meses el uso de ViewHelpers ha ido disminuyendo en las aplicaciones creadas con Cairngorm. Otros frameworks del estilo como ARP, nunca llegaron a soportar esta estrategia debido a la propia naturaleza de las aplicaciones Flash (creadas con ActionScript 2.0), donde los objetos visuales estaban atados a su representación en la pantalla y [...]]]></description>
			<content:encoded><![CDATA[<!-- matched  --><!-- final 0 --><p>En los últimos meses el uso de <em>ViewHelpers</em> ha ido disminuyendo en las aplicaciones creadas con <a href="http://labs.adobe.com/wiki/index.php/Cairngorm">Cairngorm</a>. Otros frameworks del estilo como <a href="http://osflash.org/arp">ARP</a>, nunca llegaron a soportar esta estrategia debido a la propia naturaleza de las aplicaciones <strong>Flash</strong> (creadas con <em>ActionScript 2.0</em>), donde los objetos visuales estaban atados a su representación en la pantalla y podían soportar su propia <em>API</em> sin necesidad de clases de apoyo.</p>
<p>Hoy en día, una aproximación más acertada y elegante sería usar el <a href="http://weblogs.macromedia.com/paulw/archives/2006/05/the_worlds_smal.cfm">tag <em>Observer</em></a> de <a href="http://weblogs.macromedia.com/paulw/">Paul Williams</a> para provocar la llamada de ciertos métodos en la vista cuando cambie alguna parte de nuestro modelo.</p>
<p>El tag <em>Oberver</em> es una clase muy simple y pequeña (de hecho, <strong>Paul</strong> la propone como "el tag más pequeño del mundo"):</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="400" height="200" id="ftf_wp" align="middle">
		  <param name="movie" value="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" />
		  <param name="quality" value="high" />
		  <param name="scale" value="noscale" />
		  <param name="bgcolor" value="#ffffff" />
		  <param name="flashvars" value="w=400&h=200&file=http://www.madeinflex.com/index.php&ftf=true&postID=198&no=0&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		  <embed src="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" quality="high" scale="noscale" bgcolor="#ffffff" width="400" height="200" name="ftf_wp" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="w=400&h=200&file=http://www.madeinflex.com/index.php&ftf=true&postID=198&no=0&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		</object></p>
<p>Podemos instanciar esta pequeña clase en nuestra vista de la siguiente forma:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="400" height="70" id="ftf_wp" align="middle">
		  <param name="movie" value="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" />
		  <param name="quality" value="high" />
		  <param name="scale" value="noscale" />
		  <param name="bgcolor" value="#ffffff" />
		  <param name="flashvars" value="w=400&h=70&file=http://www.madeinflex.com/index.php&ftf=true&postID=198&no=1&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		  <embed src="http://www.madeinflex.com/./wp-content/plugins/FlashTextFormatter/ftf_wp.swf" quality="high" scale="noscale" bgcolor="#ffffff" width="400" height="70" name="ftf_wp" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="w=400&h=70&file=http://www.madeinflex.com/index.php&ftf=true&postID=198&no=1&def=http://www.madeinflex.com./wp-content/plugins/FlashTextFormatter/definitions/as2.xml&auto=true&" />
		</object></p>
<p>Como podeis observar, si consideramos que "<em>model</em>" es nuestro <strong>ModelLocator</strong>, cuando "myProperty" cambia de valor los <em>bindings</em> provocarán que se ejecute la función <em>myFunction</em> de nuestra vista.</p>]]></content:encoded>
			<wfw:commentRss>http://www.madeinflex.com/2006/12/17/el-tag-observer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

