<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Let&#039;s code something up!</title>
	<atom:link href="https://danielggarcia.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://danielggarcia.wordpress.com</link>
	<description>Code once, run you fools!</description>
	<lastBuildDate>Wed, 13 Jul 2022 10:45:56 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<site xmlns="com-wordpress:feed-additions:1">7628136</site><cloud domain='danielggarcia.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>https://secure.gravatar.com/blavatar/90928bcb7928f814fd75def4d26325ff2c3514720ccbd09ec478d3ed7d6a9363?s=96&#038;d=https%3A%2F%2Fs0.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Let&#039;s code something up!</title>
		<link>https://danielggarcia.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="https://danielggarcia.wordpress.com/osd.xml" title="Let&#039;s code something up!" />
	<atom:link rel='hub' href='https://danielggarcia.wordpress.com/?pushpress=hub'/>
	<item>
		<title>Nueva etapa</title>
		<link>https://danielggarcia.wordpress.com/2022/07/13/nueva-etapa-2/</link>
					<comments>https://danielggarcia.wordpress.com/2022/07/13/nueva-etapa-2/#comments</comments>
		
		<dc:creator><![CDATA[Daniel García]]></dc:creator>
		<pubDate>Wed, 13 Jul 2022 10:45:56 +0000</pubDate>
				<category><![CDATA[Personal]]></category>
		<guid isPermaLink="false">http://danielggarcia.wordpress.com/?p=1127</guid>

					<description><![CDATA[La vida da muchas vueltas. Parpadeas y ha pasado tanto tiempo que miras hacia atrás y lees una entrada de un blog escrito por un chavalín que se creía un experto programador porque se había estudiado unos cuantos patrones de diseño y había decidido compartir sus descubrimientos con los cuatro gatos que acababan cayendo en [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">La vida da muchas vueltas. Parpadeas y ha pasado tanto tiempo que miras hacia atrás y lees una entrada de un blog escrito por un chavalín que se creía un experto programador porque se había estudiado unos cuantos patrones de diseño y había decidido compartir sus descubrimientos con los cuatro gatos que acababan cayendo en su blog porque Google así lo había decidido. </p>



<p class="wp-block-paragraph">Las visitas, a fin de cuentas, alimentan el ego, y por aquel entonces, ese sabor proporcionaba una impostada sensación de importancia en un mundo que se estaba volviendo digital. A día de hoy leo aquellas entradas con ternura, ya que soy consciente de que no tengo ni idea sobre nada, y que todos los días hay algo sobre lo que aprender.</p>



<p class="wp-block-paragraph">A medida de que mi carrera fue virando (abandoné el desarrollo en .NET y me pasé a la calidad del software), mi motivación por compartir información que más o menos dominaba fue decreciendo, ya que la sensación de seguridad que te ofrece creer que dominas una materia se fue desvaneciendo. Si unimos todo eso a la formación de una familia, es fácil imaginarse que mantener el blog pasó a un completo segundo plano.</p>



<p class="wp-block-paragraph">En cualquier caso, hace poco decidí volver a retomar mi pequeño espacio personal, pero desde otro enfoque distinto. No creo que retome .NET (si bien lo he seguido usando en proyectos internos, me he quedado demasiado descolgado como para poder «enseñar» nada), así que he decidido hacer borrón y cuenta nueva, dejando <a rel="noreferrer noopener" href="https://danielggarcia.wordpress.com" target="_blank">https://danielggarcia.wordpress.com</a> tal y como se concibió incialmente. Si te suscribiste o seguiste mi blog: mil gracias por tu atención. No obstante, entiendo que si seguiste a mi antiguo yo fue porque te interesaba .NET y el desarrollo. Y debido a que esta nueva etapa pretende ser más personal y enfocada en otras materias, no me parece justo «arrastrar» a mis suscriptores a temas que probablemente no les interesen.</p>



<p class="wp-block-paragraph">Gracias por todo.</p>



<p class="wp-block-paragraph">Nos vemos en <a href="https://danigarcia.org" target="_blank" rel="noreferrer noopener">danigarcia.org</a>.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Para llegar a ser grande necesitarás, al menos a tres tipos de personas: alguien mejor de quien poder aprender, alguien inferior a quien poder enseñar y alguien igual con quien poder medirse.</p><cite>Frank Shamrock</cite></blockquote>
]]></content:encoded>
					
					<wfw:commentRss>https://danielggarcia.wordpress.com/2022/07/13/nueva-etapa-2/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1127</post-id>
		<media:content url="https://1.gravatar.com/avatar/77787450a00d8f7372bceaa70593a9c6156f81bb51204ddc5bb88b1ad375de8a?s=96&#38;d=https%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">danielggarcia</media:title>
		</media:content>
	</item>
		<item>
		<title>Una larga ausencia</title>
		<link>https://danielggarcia.wordpress.com/2014/11/17/una-larga-ausencia/</link>
					<comments>https://danielggarcia.wordpress.com/2014/11/17/una-larga-ausencia/#comments</comments>
		
		<dc:creator><![CDATA[Daniel García]]></dc:creator>
		<pubDate>Mon, 17 Nov 2014 17:29:25 +0000</pubDate>
				<category><![CDATA[Personal]]></category>
		<guid isPermaLink="false">http://danielggarcia.wordpress.com/?p=1115</guid>

					<description><![CDATA[Ya casi han pasado cuatro meses desde la última vez que actualicé el blog, y por ello quisiera pedir disculpas. Cambio de trabajo, cambio de ciudad, inicio de un Máster y responsabilidades sociales y familiares han mermado de forma importante mi tiempo libre, por lo que muy a mi pesar no he podido (al menos) finalizar la [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Ya casi han pasado cuatro meses desde la última vez que actualicé el blog, y por ello quisiera pedir disculpas. Cambio de trabajo, cambio de ciudad, inicio de un Máster y responsabilidades sociales y familiares han mermado de forma importante mi tiempo libre, por lo que muy a mi pesar no he podido (al menos) finalizar la serie dedicada a los patrones de diseño aplicados al entorno .NET.</p>
<p>Sin embargo, <em>I&#8217;ll be back</em>. No soy persona que guste de dejar las cosas a medias, y en cuanto saque un poco de tiempo, me pondré manos a la obra para finalizar los patrones que quedan pendientes y seguir dando guerra por estos lares.</p>
<p>Por lo tanto, ante la pregunta de que si publicaré más patrones, la respuesta es «sí». Lo que no puedo asegurar es cuándo. Pero intentaré que no sea muy tarde.</p>
<p>Y por supuesto, agradezco vuestras críticas y vuestros comentarios.</p>
<p>Nos vemos pronto.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://danielggarcia.wordpress.com/2014/11/17/una-larga-ausencia/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1115</post-id>
		<media:content url="https://1.gravatar.com/avatar/77787450a00d8f7372bceaa70593a9c6156f81bb51204ddc5bb88b1ad375de8a?s=96&#38;d=https%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">danielggarcia</media:title>
		</media:content>
	</item>
		<item>
		<title>Patrones de Comportamiento (VI): Patrón Observer</title>
		<link>https://danielggarcia.wordpress.com/2014/06/02/patrones-de-comportamiento-vi-patron-observer/</link>
					<comments>https://danielggarcia.wordpress.com/2014/06/02/patrones-de-comportamiento-vi-patron-observer/#comments</comments>
		
		<dc:creator><![CDATA[Daniel García]]></dc:creator>
		<pubDate>Mon, 02 Jun 2014 00:21:48 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Nivel avanzado]]></category>
		<category><![CDATA[Patrones de Diseño]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[ejemplo]]></category>
		<category><![CDATA[observer pattern]]></category>
		<category><![CDATA[patrón observer]]></category>
		<guid isPermaLink="false">http://danielggarcia.wordpress.com/?p=1111</guid>

					<description><![CDATA[Objetivo: «Definir una dependencia uno-a-muchos entre objetos de forma de que, cuando el estado de uno de ellos cambia, todos los objetos dependientes son notificados y actualizados de forma automática». Design Patterns: Elements of Reusable Object-Oriented Software Podemos afirmar sin rubor alguno que el patrón Observer es uno de los más importantes (y utilizados) de [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong>Objetivo:<br />
</strong></p>
<blockquote><p><em>«Definir una dependencia uno-a-muchos entre objetos de forma de que, cuando el estado de uno de ellos cambia, todos los objetos dependientes son notificados y actualizados de forma automática».<br />
</em></p>
<p>Design Patterns: Elements of Reusable Object-Oriented Software</p></blockquote>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/06/060214_0019_patronesdec1.png" alt="" /></p>
<p>Podemos afirmar sin rubor alguno que el patrón <em>Observer</em> es uno de los más importantes (y utilizados) de todos los patrones de diseño vistos hasta el momento. Su filosofía es simple: un objeto, denominado <em>sujeto</em> (<em>Subject</em>) posee un estado. Cuando su estado cambia, es capaz de «avisar» a sus <em>subcriptores</em> (<em>Observers</em>) de este cambio de estado. De este modo, los objetos suscritos al objeto no tienen que preocuparse de cuándo se produce un cambio de estado: éste se encargará de informar de forma activa a todos aquellos objetos que hayan decidido suscribirse.</p>
<p>Este tipo de suscripción puede ser de dos tipos:</p>
<ul>
<li>Suscripción <em>push</em>: el objeto informa a sus suscriptores con sus valores tan pronto como su estado cambie.</li>
<li>Suscripción <em>pull</em>: el objeto es interrogado por sus suscriptores si su estado ha cambiado desde la última vez que se tanteó.</li>
</ul>
<p>Este esquema respeta al máximo el principio de <strong>bajo acoplamiento</strong>. El <em>Subject</em> y el <em>Observer</em> pueden interactuar entre ellos, pero apenas tienen conocimiento del uno sobre el otro. Dado que <strong>hemos basado el diseño en abstracciones, no en concreciones</strong>, no será necesario modificar el <em>Subject</em> para añadir nuevos <em>Observers</em> (bastará con que implemente la interfaz <em>IObserver</em>). Del mismo modo, un <em>Observer</em> podrá suscribirse a más de un <em>Subject</em> si éste implementa la interfaz <em>ISubject</em>.</p>
<p><span id="more-1111"></span></p>
<p>Vale, hemos entendido el concepto pero ¿cómo funciona realmente el patrón? Explicado de forma simple, podemos resumirlo de la siguiente manera:</p>
<ul>
<li>
<div><em>SubjectConcreto</em> implementa la interfaz <em>ISubject</em>. Esta clase tendrá una funcionalidad propia, un estado (por ejemplo, una serie de variables) y una lista interna de objetos que implementan la interfaz <em>IObserver. </em>Esta lista se utilizará para realizar la «suscripción» a los cambios de estado, invocando el método <em>IObserver.update()</em> de cada objeto dentro de esta lista cada vez que se produzca un cambio de estado. Además, esta clase implementará los métodos de <em>ISubject:</em></div>
<ul>
<li><em>registrarObserver(IObserver o)</em>: añade el <em>observer</em> «o» pasado como parámetro a la lista de objetos que serán notificados.</li>
<li><em>eliminarObserver(Observer o)</em>: elimina el <em>observer</em> «o» pasado como parámetro de la lista de objetos que serán notificados.</li>
<li><em>notificarObservers()</em>: recorre la lista de <em>observers</em>, invocando el método <em>update()</em> de cada uno de ellos, provocando que se realice una acción determinada cuando el estado del <em>Subject </em>cambie. Normalmente este método será invocado en el momento en el que el estado del <em>Subject</em> cambie (por ejemplo, al final del método <em>setState()</em>).</li>
</ul>
</li>
</ul>
<p>El método <em>update()</em> será implementado por cada <em>Observer</em> concreto, y se encargará de realizar las operaciones que el objeto suscrito quiera realizar cuando se entere de que algo ha cambiado dentro del <em>Subject</em>.</p>
<h2>Implementando el patrón Observer</h2>
<p>Realizaremos una implementación de este patrón basándonos en un sistema de sensores que realice una medición de los niveles de agua y aceite, así como de la presión de los neumáticos. Este sistema permitirá que los <em>observers</em> puedan suscribirse a los cambios en los valores de estos niveles, realizando las operaciones que estimen oportunas. Comenzaremos creando la interfaz <em>IObserver</em> que incluirá el método <em>update</em> que tendrán que implementar todos aquellas clases que deseen recibir notificaciones. Este método recibirá un parámetro que contendrá información sobre la actualización. Para hacerla lo más genérica posible, haremos que sea de tipo <em>Object</em>, realizando el <em>casting</em> correspondiente a la hora de implementar la clase concreta.</p>
<p><span style="text-decoration:underline;"><strong>IObserver.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public interface IObserver
    {
        // Metodo que sera invocado por el Subject
        // El objeto &quot;o&quot; seran los valores que el Subject le pasara al Observer
        void update(Object o);
    }

</pre>
<p>Lo siguiente que haremos sera codificar una interfaz que exponga los métodos propios de un notificador:</p>
<ul>
<li>Un método para registrar un <em>observer</em>, que aceptará un <em>IObserver </em>como argumento.</li>
<li>Un método para eliminar la suscripción de un <em>observer</em>, que también aceptará un <em>IObserver</em> como argumento.</li>
<li>Un método para realizar la notificación a todos los <em>observers</em> que se encuentren suscritos al <em>Subject</em>.</li>
</ul>
<p><span style="text-decoration:underline;"><strong>ISubject.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    // Interfaz que expone los metodos de registro y eliminacion de observers, asi como para
    // la notificacion de los cambios de estado.
    public interface ISubject
    {
        void RegistrarObserver(IObserver o);
        void EliminarObserver(IObserver o);
        void NotificarObservers();
    }
</pre>
<p>A continuación codificaremos el <em>Subject</em> en sí: una clase que implementará la interfaz <em>ISubject</em> y que incluirá los métodos declarados en ésta. Además incluirá una serie de variables que almacenarán los distintos niveles (aceite, agua y presión de los neumáticos) junto a sus respectivas <em>Properties</em>, que permitirán modificar sus valores. En el método <em>set</em> de estas <em>Properties</em> será donde se realice la invocación del método <em>NotificarObservers()</em>, siempre y cuando el valor cambie, es decir, <strong>se comprueba si el nuevo valor es igual al anterior</strong>, y en caso contrario, se actualiza el estado y se notifica a todos aquellos <em>Observers</em> que se encuentren suscritos. Este método puede afinarse dependiendo del caso concreto (por ejemplo, notificando únicamente cuando el cambio suponga la superación de cierto umbral).</p>
<p>El constructor de la clase recibirá como parámetros los valores iniciales de los niveles de aceite, agua y presión de los neumáticos, además de instanciar el IList que almacenará los <em>Observers</em> suscritos a las notificaciones. Los métodos <em>RegistrarObserver</em> y <em>EliminarObserver</em> serán los encargados de añadir y eliminar suscriptores a la lista (previa comprobación de si éstos están ya en la lista o no). El método <em>NotificarObservers()</em> será tan sencillo como un bucle <em>foreach</em> que recorra todos los <em>IObserver</em> suscritos a las notificaciones, invocando su método <em>update()</em> pasándole el estado del objeto como parámetro.</p>
<p>Previamente hemos dicho que existen dos versiones del patrón:</p>
<ul>
<li>Una versión <em>push</em>, que es precisamente la que definimos aquí: el propio <em>Subject</em> inyecta el estado en los <em>Observers</em>, pasándolo como parámetro al método <em>Update()</em>.</li>
<li>Una versión <em>pop</em>, que como alternativa ofrece simplemente informar al <em>Observer</em> que se ha producido un cambio de estado, siendo responsabilidad de éste solicitar al <em>Subject</em> los nuevos valores.</li>
</ul>
<p><span style="text-decoration:underline;"><strong>MedidorSensores.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class MedidorSensores : ISubject
    {
        #region Estado

        // Atributos que modelan el estado
        private int nivelAceite;
        private int nivelAgua;
        private int nivelPresionNeumaticos;

        #endregion

        // Listado de observers
        IList suscriptores;

        #region Properties

        public int NivelAceite
        {
            get { return this.nivelAceite; }

            // Cada vez que se modifique el estado, se invocara el metodo NotificarObservers()
            set
            {
                if (this.nivelAceite != value)
                {
                    this.nivelAceite = value;
                    NotificarObservers();
                }
            }
        }

        public int NivelAgua
        {
            get { return this.nivelAgua; }

            // Cada vez que se modifique el estado, se invocara el metodo NotificarObservers()
            set
            {
                if (this.nivelAgua != value)
                {
                    this.nivelAgua = value;
                    NotificarObservers();
                }
            }
        }

        public int NivelPresionNeumaticos
        {
            get { return this.nivelPresionNeumaticos; }

            // Cada vez que se modifique el estado, se invocara el metodo NotificarObservers()
            set
            {
                if (this.nivelPresionNeumaticos != value)
                {
                    this.nivelPresionNeumaticos = value;
                    NotificarObservers();
                }
            }
        }

        #endregion

        #region Metodos de la interfaz ISubject

        // Constructor que creara un medidor con los valores iniciales de las presiones
        public MedidorSensores(int nivelAceite, int nivelAgua, int nivelPresionNeumaticos)
        {
            this.suscriptores = new ArrayList();
            this.nivelAceite = nivelAceite;
            this.nivelAgua = nivelAgua;
            this.nivelPresionNeumaticos = nivelPresionNeumaticos;
        }

        // Comprobamos si el observer se encuentra en la lista. En caso contrario,
        // lo incluye en la lista
        public void RegistrarObserver(IObserver o)
        {
            if (!suscriptores.Contains(o))
                suscriptores.Add(o);
        }

        // Comprobamos si el observer se encuentra en la lista. En caso afirmativo,
        // lo elimina de la lista
        public void EliminarObserver(IObserver o)
        {
            if (suscriptores.Contains(o))
                suscriptores.Remove(o);
        }

        // Recorre la lista de observers e invoca su metodo Update()
        public void NotificarObservers()
        {
            // Creamos un array con el estado del Subject
            int[] valores = { this.nivelAceite, this.nivelAgua, this.nivelPresionNeumaticos };

            // Recorremos todos los objetos suscritos (observers)
            IObserver observer;
            foreach(Object o in suscriptores)
            {
                // Invocamos el metodo Update de cada observer, pasandole el array con el estado
                // del subject como parametro.
                // Cada observer ya hara lo que estime necesario con esa informacion.
                observer = (IObserver)o;
                observer.update(valores);
            }
        }

        #endregion
    }
</pre>
<p>El último paso será la creación de las clases que implementen la interfaz <em>IObserver</em>. Crearemos dos clases: una de ellas simbolizará el <em>display</em> del vehículo, es decir, la pantalla de cristal líquido que muestra la información al conductor, además de la velocidad, revoluciones, llenado del depósito del combustible… Este <em>Observer</em> mostrará <strong>siempre</strong> los cambios producidos en los niveles, ya que su misión será la de informar al usuario en todo momento de los niveles actuales. Es el tipo más simple de <em>Observer</em>, ya que se limita a presentar la información recibida del <em>Subject</em>.</p>
<p><span style="text-decoration:underline;"><strong>ObserverDisplay.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class ObserverDisplay : IObserver
    {
        #region Atributos

        // Atributos que modelan el estado
        private int nivelAceite;
        private int nivelAgua;
        private int nivelPresionNeumaticos;

        // Subject al que se encuentra suscrito el observer
        private ISubject subject;

        #endregion

        #region Constructores

        // El constructor suscribira el observer al subject
        public ObserverDisplay(ISubject subject)
        {
            this.subject = subject;
            subject.RegistrarObserver(this);
        }

        #endregion

        #region Metodos de IObserver

        public void update(object o)
        {
            // Comprobamos el tipo del objeto recibido como parametro
            int[] arrayInt = null;
            if (o.GetType().Equals(typeof(int[])))
                arrayInt = (int[])o;

            // Si es del tipo esperado (int[]) y del tamano esperado (3), actualizamos los
            // atributos
            if ((arrayInt != null) &amp;&amp; (arrayInt.Length == 3))
            {
                nivelAceite = arrayInt[0];
                nivelAgua = arrayInt[1];
                nivelPresionNeumaticos = arrayInt[2];

                // Mostramos por pantalla los valores actuales
                MostrarValores();
            }
        }

        #endregion

        // Metodo que muestra los valores en el display
        private void MostrarValores()
        {
            Console.WriteLine(&quot;Nivel de Aceite: &quot; + nivelAceite);
            Console.WriteLine(&quot;Nivel de Agua: &quot; + nivelAgua);
            Console.WriteLine(&quot;Presion de Neumaticos: &quot; + nivelPresionNeumaticos + &quot;\n&quot;);
        }
    }
</pre>
<p>Como segundo <em>Observer</em> codificaremos una clase <em>ObserverAlerta</em> que, en lugar de informar siempre de los niveles actuales, sea capaz de enviar una alerta (sonora, remota, visual o de cualquier otro tipo) en caso de que los niveles superen ciertos umbrales superiores o inferiores. En caso contrario, no realizarán ninguna acción. Esto servirá para mostrar que un <em>Observer</em> realizará cualquier tipo de operación con estos datos, y también la suscripción de más de uno de estos elementos.</p>
<p><span style="text-decoration:underline;"><strong>ObserverAlerta.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class ObserverAlerta : IObserver
    {
        #region Constantes

        // Niveles minimos y maximos
        private static readonly int MIN_ACEITE = 12;
        private static readonly int MAX_ACEITE = 45;

        private static readonly int MIN_AGUA = 300;
        private static readonly int MAX_AGUA = 550;

        private static readonly int MIN_PRESION = 120;
        private static readonly int MAX_PRESION = 350;

        #endregion

        #region Atributos

        // Atributos que modelan el estado
        private int nivelAceite;
        private int nivelAgua;
        private int nivelPresionNeumaticos;

        // Subject al que se encuentra suscrito el observer
        private ISubject subject;

        #endregion

        #region Constructores

        // El constructor suscribira el observer al subject
        public ObserverAlerta(ISubject subject)
        {
            this.subject = subject;
            subject.RegistrarObserver(this);
        }

        #endregion

        #region Metodos de IObserver

        public void update(object o)
        {
            // Comprobamos el tipo del objeto recibido como parametro
            int[] arrayInt = null;
            if (o.GetType().Equals(typeof(int[])))
                arrayInt = (int[])o;

            // Si es del tipo esperado (int[]) y del tamano esperado (3), actualizamos los
            // atributos
            if ((arrayInt != null) &amp;&amp; (arrayInt.Length == 3))
            {
                nivelAceite = arrayInt[0];
                nivelAgua = arrayInt[1];
                nivelPresionNeumaticos = arrayInt[2];

                // Comprobamos que los valores no exceden los limites
                ComprobarAceite();
                ComprobarAgua();
                ComprobarNeumaticos();
            }

        }

        #endregion

        // Metodo que comprueba los niveles de aceite
        private void ComprobarAceite()
        {
            if (nivelAceite &lt; MIN_ACEITE)
            {
                EnviarAlerta();
                Console.WriteLine(String.Format(&quot;NIVEL DE ACEITE DEMASIADO BAJO: {0}/{1}&quot;, nivelAceite, MIN_ACEITE));
            }
            if (nivelAceite &gt; MAX_ACEITE)
            {
                EnviarAlerta();
                Console.WriteLine(String.Format(&quot;NIVEL DE ACEITE DEMASIADO ALTO: {0}/{1}&quot;, nivelAceite, MAX_ACEITE));
            }
        }

        // Metodo que comprueba los niveles de agua
        private void ComprobarAgua()
        {
            if (nivelAgua &lt; MIN_AGUA)
            {
                EnviarAlerta();
                Console.WriteLine(String.Format(&quot;NIVEL DE AGUA DEMASIADO BAJO: {0}/{1}&quot;, nivelAgua, MIN_AGUA));
            }
            if (nivelAgua &gt; MAX_AGUA)
            {
                EnviarAlerta();
                Console.WriteLine(String.Format(&quot;NIVEL DE AGUA DEMASIADO ALTO: {0}/{1}&quot;, nivelAgua, MAX_AGUA));
            }
        }

        // Metodo que comprueba la presion de los neumaticos
        private void ComprobarNeumaticos()
        {
            if (nivelPresionNeumaticos &lt; MIN_PRESION)
            {
                EnviarAlerta();
                Console.WriteLine(String.Format(&quot;NIVEL DE PRESION DE NEUMATICOS DEMASIADO BAJO: {0}/{1}&quot;, nivelPresionNeumaticos, MIN_PRESION));
            }
            if (nivelPresionNeumaticos &gt; MAX_PRESION)
            {
                EnviarAlerta();
                Console.WriteLine(String.Format(&quot;NIVEL DE PRESION DE NEUMATICOS DEMASIADO ALTO: {0}/{1}&quot;, nivelPresionNeumaticos, MAX_PRESION));
            }
        }

        // Metodo que envie la alerta
        private void EnviarAlerta()
        {
            // Este metodo podria enviar una alerta a la centralita del vehiculo que, por ejemplo,
            // forzaria a su detencion
            Console.WriteLine(&quot;ALERTA!!&quot;);
        }
    }
</pre>
<p>Finalmente, escribiremos el código necesario para mostrar el funcionamiento del patrón. Comenzaremos instanciando un <em>Subject</em> con unos niveles iniciales, para a continuación instanciar dos <em>Observers</em> (uno de display y otro de alerta) que recibirán como parámetro el <em>Subject</em> al cual se suscribirán de forma automática. A continuación alteraremos los valores del medidor de sensores y comprobaremos cómo los <em>Observers</em> son informados y actúan en consecuencia, mostrando <strong>siempre</strong> los cambios en los valores en el caso del display y mostrando únicamente las alertas cuando los valores se encuentran fuera de los límites para el caso del observer <em>ObserverAlerta</em>.</p>
<pre class="brush: csharp; title: ; notranslate">
            // Creamos un medidor de sensores
            ISubject sensores = new MedidorSensores(20, 380, 200);

            // Creamos dos observers: un display y un emisor de alertas.
            // Se realiza la suscripcion a traves del constructor
            IObserver display = new ObserverDisplay(sensores);
            IObserver alerta = new ObserverAlerta(sensores);

            // Modificamos valores del subject. Los observers son automaticamente informados
            // y actuaran automaticamente
            ((MedidorSensores)sensores).NivelAceite += 10;
            ((MedidorSensores)sensores).NivelAceite += 10;
            ((MedidorSensores)sensores).NivelAgua += 100;
            ((MedidorSensores)sensores).NivelPresionNeumaticos -= 50;
            ((MedidorSensores)sensores).NivelAceite += 10;
            ((MedidorSensores)sensores).NivelAgua += 100;
            ((MedidorSensores)sensores).NivelAgua += 100;
</pre>
<p>Como vemos, siempre que se produce un cambio de estado, el display recibe la notificación y actúa en consecuencia. Cuando esta notificación llega a la alerta y los valores se encuentran fuera de los límites aceptables, además se emitirá una alerta.</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/06/060214_0019_patronesdec2.png" alt="" /></p>
<p>Como alternativa, podemos probar a eliminar la suscripción a las alertas antes de que éstas rebasen los límites:</p>
<pre class="brush: csharp; title: ; notranslate">
            // Modificamos valores del subject. Los observers son automaticamente informados
            // y actuaran automaticamente
            ((MedidorSensores)sensores).NivelAceite += 10;
            ((MedidorSensores)sensores).NivelAceite += 10;
            ((MedidorSensores)sensores).NivelAgua += 100;
            ((MedidorSensores)sensores).NivelPresionNeumaticos -= 50;

            // Eliminamos el registro de las alertas y aumentamos los niveles para comprobar que no
            // son informados
            sensores.EliminarObserver(alerta);
            ((MedidorSensores)sensores).NivelAceite += 10;
            ((MedidorSensores)sensores).NivelAgua += 100;
            ((MedidorSensores)sensores).NivelAgua += 100;
</pre>
<p>En este caso, únicamente el display realizará su trabajo, ya que hemos decidido eliminar la suscripción de <em>ObserverAlerta</em> a lo largo del programa, lo que implicará que este objeto no reciba a partir de ese momento las notificaciones del <em>Subject</em>.</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/06/060214_0019_patronesdec3.png" alt="" /></p>
<h2>IObservable e IObserver</h2>
<p>En la práctica no será necesario definir la interfaz <em>IObservable</em>, ya que .NET ofrece por defecto las interfaces <em>IObserver&lt;T&gt;</em> e <em>IObservable&lt;T&gt;</em> (tal y como hacía con <em>IEnumerable&lt;T&gt;</em> con el patrón iterator) para facilitarnos un poco la vida. El parámetro <em>&lt;T&gt;</em> será la clase cuyo estado quiera observarse, y en este caso no tiene por qué implementar la interfaz <em>ISubject</em>, sino que será parametrizada en <em>IObservable&lt;T&gt;</em> y en <em>IObserver&lt;T&gt;</em>, es decir:</p>
<ul>
<li>Se deberá crear una clase, por ejemplo <em>MedidorSensores</em>, que exponga una serie de <em>Properties</em> que se pretende monitorizar.</li>
<li>Se codificará una clase <em>Suscriber&lt;MedidorSensores&gt; </em>que implemente la interfaz <em>IObservable&lt;T&gt;</em> (siendo <em>T </em>en este caso <em>MedidorSensores</em>) que será la encargada de gestionar las suscripciones y enviar la información a los <em>Observers</em>. Su formato será el siguiente:</li>
</ul>
<pre class="brush: csharp; title: ; notranslate">
    public class Suscriber : IObservable&lt;MedidorSensores&gt;
    {
        public IDisposable Subscribe(IObserver&lt;MedidorSensores&gt; observer)
        {
            throw new NotImplementedException();
        }
    }
</pre>
<ul>
<li>Se codificará una clase <em>Provider&lt;MedidorSensores&gt;</em> que implemente la interfaz <em>IObserver&lt;T&gt;</em> (siendo <em>T </em>en este caso <em>MedidorSensores</em>) que será la clase <em>Observer</em> e implementará los métodos <em>OnCompleted, OnError </em>y <em>OnNext</em> (siendo este último método el encargado de realizar las notificaciones).</li>
</ul>
<pre class="brush: csharp; title: ; notranslate">
    public class Provider : IObserver&lt;MedidorSensores&gt;
    {

        public void OnCompleted()
        {
            throw new NotImplementedException();
        }

        public void OnError(Exception error)
        {
            throw new NotImplementedException();
        }

        public void OnNext(MedidorSensores value)
        {
            throw new NotImplementedException();
        }
    }
</pre>
<p>Al final del artículo se indica un enlace en el que se podrá comprobar cómo utilizar estas interfaces aplicándolas a los datos de una estación meteorológica.</p>
<h2>¿Cuándo utilizar este patrón? Ejemplos reales</h2>
<p>Este patrón es útil en multitud de supuestos, pero el principal será cuando la modificación del estado de un objeto deba provocar cambio en otros objetos sin que sea necesario conocer nada acerca de la cantidad ni el tipo de dichos objetos.</p>
<p>Este patrón es la base de los <strong>eventos</strong> de la mayor parte de las interfaces de usuario: los <em>Event Handlers</em> se corresponderían con los <em>Observers</em> que esperan la notificación de un cambio de estado. Así, en un botón, definir un método para el evento OnClick hará que el control <em>Button</em> cambie su estado (por ejemplo, de <em>no pulsado</em> a <em>pulsado</em>), notificando a todos aquellos objetos que estén suscritos a él. De este modo, el <em>Event Handler</em> será notificado de este cambio de estado y ejecutará el código que haya sido programado para responder a dicho cambio de estado (por ejemplo, mostrar un mensaje cuando se pulsa un botón, o lo que es lo mismo, cuando el botón pasa de <em>no pulsado</em> a <em>pulsado</em>.</p>
<p>El patrón <em>Observer</em> también es la base del <strong>enlace de datos</strong> (<em>data binding</em>), por ejemplo en un control <em>Gridview</em>, que al obtener los datos de una fila de datos se encargará de dibujar la plantilla previamente configurada para mostrarle los datos al usuario.</p>
<p>Más adelante volveremos a este patrón, ya que es la base de uno de los patrones compuestos más utilizados hoy en día: <strong>el patrón MVC o Modelo Vista Controlador</strong>. El papel del patrón <em>Observer</em> en este patrón compuesto (el patrón MVC no es un patrón en sí, sino que es un patrón compuesto de varios patrones, al igual que una clase es una estructura de datos formada por otras estructuras de datos) será actuar de núcleo del mismo implementándose en el modelo. De este modo, los objetos interesados se mantienen actualizados cuando se produce un cambio de estado, haciendo que tanto la vista como el controlador estén débilmente acoplados con el modelo. Como adelanto, MVC hace uso de otros dos patrones ya vistos anteriormente: <em><a href="https://danielggarcia.wordpress.com/2014/03/31/patrones-estructurales-vi-patron-composite/" target="_blank">Composite</a></em> (vista) y <em><a href="https://danielggarcia.wordpress.com/2014/05/12/patrones-de-comportamiento-iv-patron-strategy/" target="_blank">Strategy</a></em> (controlador).</p>
<h3>Fuentes:</h3>
<ul>
<li><a href="http://shop.oreilly.com/product/9780596007126.do" target="_blank">Head First Design Patterns</a> (Freeman et al.)</li>
<li><a href="http://www.c-sharpcorner.com/UploadFile/rafeeqkp/observer-pattern-with-C-Sharp-4-0/" target="_blank">Observer Pattern with C# 4.0</a> (Rafeeq Mohamed)</li>
<li><a href="http://visualstudiomagazine.com/articles/2013/08/14/the-observer-pattern-in-net.aspx" target="_blank">The Observer Pattern in .NET</a> (Eric Vogel)</li>
<li><a href="http://dotnetcodr.com/2013/08/01/design-patterns-and-practices-in-net-the-observer-pattern/" target="_blank">Design patterns and practices in .NET: the Observer pattern</a> (Andras Nemes)</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://danielggarcia.wordpress.com/2014/06/02/patrones-de-comportamiento-vi-patron-observer/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1111</post-id>
		<media:content url="https://1.gravatar.com/avatar/77787450a00d8f7372bceaa70593a9c6156f81bb51204ddc5bb88b1ad375de8a?s=96&#38;d=https%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">danielggarcia</media:title>
		</media:content>

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/06/060214_0019_patronesdec1.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/06/060214_0019_patronesdec2.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/06/060214_0019_patronesdec3.png" medium="image" />
	</item>
		<item>
		<title>Patrones de Comportamiento (V): Patrón State</title>
		<link>https://danielggarcia.wordpress.com/2014/05/20/patrones-de-comportamiento-v-patron-state/</link>
					<comments>https://danielggarcia.wordpress.com/2014/05/20/patrones-de-comportamiento-v-patron-state/#comments</comments>
		
		<dc:creator><![CDATA[Daniel García]]></dc:creator>
		<pubDate>Tue, 20 May 2014 05:42:04 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Nivel avanzado]]></category>
		<category><![CDATA[Patrones de Diseño]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[ejemplo]]></category>
		<category><![CDATA[state pattern]]></category>
		<guid isPermaLink="false">http://danielggarcia.wordpress.com/?p=1102</guid>

					<description><![CDATA[Objetivo: «Permitir que un objeto modifique su comportamiento cuando su estado interno cambie. Parecerá que el objeto cambia de clase». DesignPatterns: Elements of Reusable Object-Oriented Software El patrón State tiene la misión fundamental de encapsular el comportamiento de un objeto dependiendo del estado en el que éste se encuentre. ¿A qué nos referimos con estado? [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong>Objetivo:<br />
</strong></p>
<blockquote><p><em>«Permitir que un objeto modifique su comportamiento cuando su estado interno cambie. Parecerá que el objeto cambia de clase».<br />
</em></p>
<p>DesignPatterns: Elements of Reusable Object-Oriented Software</p></blockquote>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/052014_0541_patronesdec1.png" alt="" /></p>
<p>El patrón <em>State </em>tiene la misión fundamental de encapsular el comportamiento de un objeto dependiendo del estado en el que éste se encuentre. ¿A qué nos referimos con estado? Estrictamente hablando, podemos definir el estado de un objeto como el conjunto actual de los valores de los atributos de un objeto. Desde un punto de vista más coloquial, y refiriéndonos al patrón que estamos presentando, podríamos definir un estado como un conjunto de características que harán que el objeto tenga unas características concretas. O hablando en plata: desde el punto de vista de la orientación a objetos, podemos decir que el estado de un vehículo es de velocidad instantánea igual a cero, sin consumo de combustible, a una distancia de entre cero y veinte centímetros de la acera y con el habitáculo vacío. Desde un punto de vista coloquial (que ahora mismo es el que nos interesa), podemos decir que la suma de esos atributos nos informa de que el vehículo se encuentra en estado <strong>aparcado</strong>.</p>
<p><span id="more-1102"></span></p>
<p>Supongo que todos conocemos el concepto de «<a href="http://es.wikipedia.org/wiki/M%C3%A1quina_de_estados">máquina de estados</a>«. Si no es así, lo podemos resumir con aquella máxima de «una imagen vale más que mil palabras»:</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/052014_0541_patronesdec2.png" alt="" /></p>
<p>Como podemos observar, contamos con una serie de círculos que representan los <strong>estados</strong> (Apagado, Parado, En Marcha). Cada uno de esos estados se caracteriza por los valores de una serie de atributos (por ejemplo, para que el vehículo se encuentre <em>En Marcha</em>, se debe dar el caso de que el vehículo esté arrancado y con una velocidad distinta de cero). ¿Cómo se producen los cambios de estado? A través de las llamadas <strong>transiciones</strong>. Estas transiciones podrían compararse con nuestros <strong>métodos y funciones</strong>, que actúan sobre los valores del objeto haciendo que éste cambie de estado. O no.</p>
<p>Por tanto, tenemos un conjunto limitado de estados (Apagado, Parado, En Marcha) y otro de transiciones (Contacto, Acelerar, Frenar). El factor determinante se encuentra en que <strong>dependiendo en qué estado nos encontremos, las transiciones actuarán de forma distinta</strong>, realizando ciertas operaciones, transiciones a otros estados… o no realizando absolutamente nada. Como ejemplo, pisar el acelerador con el vehículo apagado no realizará ningún cambio, mientras que si pisamos el acelerador con el vehículo arrancado, el coche se pondrá en movimiento, ganando velocidad (y realizando una transición del estado PARADO al estado EN_MARCHA).</p>
<p>Pongámosle código a nuestro ejemplo:</p>
<h2>Un pequeño conjunto de estados</h2>
<p>Modelaremos este ejemplo con una clase a la que llamaremos «VehiculoBasico». Su funcionamiento será sencillo: contará con una variable entera que almacenará el estado actual, otra que almacenará la velocidad, y un conjunto de métodos que serán los encargados de realizar las transiciones. ¿Cómo lo controlamos? Pues a priori, no tenemos mucho donde elegir: a través de una serie de sentencias <em>switch</em> o <em>if…else</em>, que comprueben el estado actual y actúen de forma distinta dependiendo del estado en el que nos encontremos. Comencemos con la declaración de la clase, un conjunto de enteros que modelen los posibles estados y sus atributos:</p>
<pre class="brush: csharp; title: ; notranslate">
    public class VehiculoBasico
    {
        // Estados
        private const int APAGADO = 0;
        private const int PARADO = 1;
        private const int EN_MARCHA = 2;

        // Atributos
        private const int VELOCIDAD_MAXIMA = 200;
        private int estado = APAGADO;
        private int velocidadActual = 0;

    }

</pre>
<p>A continuación modelaremos cada uno de los métodos que pueden realizar transiciones. Comenzaremos con el método <em>Contacto</em>:</p>
<pre class="brush: csharp; title: ; notranslate">
        public void Contacto()
        {
            switch (estado)
            {
                case APAGADO:
                    {
                        // El vehiculo arranca
                        estado = PARADO;
                        velocidadActual = 0;
                        Console.WriteLine(&quot;El vehiculo se encuentra ahora PARADO&quot;);
                        break;
                    }
                case PARADO:
                    {
                        // El vehiculo se apaga
                        estado = APAGADO;
                        Console.WriteLine(&quot;El vehiculo se encuentra ahora APAGADO&quot;);
                        break;
                    }
                case EN_MARCHA:
                    {
                        // No se puede detener el vehiculo en marcha!
                        Console.WriteLine(&quot;ERROR: No se puede cortar el contacto en marcha!&quot;);
                        break;
                    }
                default:
                    break;
            }
        } 
</pre>
<p>Como vemos, lo primero que haremos en el método será comprobar el estado actual y/o otros atributos. Acorde a esta información, realizaremos las operaciones oportunas. Seguiremos con el método <em>Acelerar</em></p>
<pre class="brush: csharp; title: ; notranslate">
        public void Acelerar()
        {
            switch (estado)
            {
                case APAGADO:
                    {
                        // Acelerar con el vehiculo apagado no sirve de mucho <img src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" />
                        Console.WriteLine(&quot;ERROR: El vehiculo esta apagado. Efectue el contacto para iniciar&quot;);
                        break;
                    }
                case PARADO:
                    {
                        // El vehiculo se pone en marcha. Aumenta la velocidad y cambiamos de estado
                        velocidadActual += 10;
                        estado = EN_MARCHA;
                        Console.WriteLine(&quot;El vehiculo se encuentra ahora EN_MARCHA&quot;);
                        Console.WriteLine(&quot;Velocidad actual: &quot; + velocidadActual);
                        break;
                    }
                case EN_MARCHA:
                    {
                        // Aumentamos la velocidad, permaneciendo en el mismo estado
                        if (velocidadActual &gt;= VELOCIDAD_MAXIMA)
                            Console.WriteLine(&quot;ERROR: El coche ha alcanzado su velocidad maxima&quot;);
                        else
                            velocidadActual += 10;
                        break;
                    }
                default:
                    break;
            }
        }
</pre>
<p>Finalmente, codificaremos el último de los métodos: <em>Frenar</em>.</p>
<pre class="brush: csharp; title: ; notranslate">
        public void Frenar()
        {
            switch (estado)
            {
                case APAGADO:
                    {
                        // Frenar con el vehiculo parado tampoco sirve de mucho...
                        Console.WriteLine(&quot;ERROR: El vehiculo esta apagado. Efectue el contacto para iniciar&quot;);
                        break;
                    }
                case PARADO:
                    {
                        // No ocurre nada. Si el vehiculo ya se encuentra detenido, no habra efecto alguno
                        Console.WriteLine(&quot;ERROR: El vehiculo ya se encuentra detenido&quot;);
                        break;
                    }
                case EN_MARCHA:
                    {
                        // Reducimos la velocidad. Si esta llega a 0, cambiaremos a estado &quot;PARADO&quot;
                        velocidadActual -= 10;
                        if (velocidadActual &lt;= 0)
                        {
                            estado = PARADO;
                            Console.WriteLine(&quot;El vehiculo se encuentra ahora PARADO&quot;);
                        }
                        Console.WriteLine(&quot;Velocidad actual: &quot; + velocidadActual);
                        break;
                    }
                default:
                    break;
            }
        }
</pre>
<p>Ahora codificaremos un pequeño programita que haga uso de nuestra clase:</p>
<pre class="brush: csharp; title: ; notranslate">
            VehiculoBasico vb = new VehiculoBasico();

            vb.Acelerar();
            vb.Contacto();
            vb.Acelerar();
            vb.Acelerar();
            vb.Acelerar();
            vb.Frenar();
            vb.Frenar();
            vb.Frenar();
            vb.Frenar();
</pre>
<p>El resultado es bastante previsible: al acelerar sin arrancar obtenemos un error. Damos contacto, aceleramos un poco y vamos frenando hasta que el vehículo se detiene. E incluso pisamos el freno estando ya parados, por lo que el vehículo nos informa de ello.</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/052014_0541_patronesdec3.png" alt="" /></p>
<h2>Encapsulando el estado</h2>
<p>Todo esto resulta muy sencillo, pero ¿qué ocurriría si, por ejemplo, los requisitos de nuestro programa nos exigieran añadir un nuevo estado? Como podemos imaginar, cada uno de los métodos tendrá que añadir una nueva línea a su <em>switch</em> para contemplar esta posibilidad, amén de que seguramente tengamos que modificar el código ya existente para «encajar» nuestro nuevo estado dentro de la funcionalidad del programa. Por ejemplo, si imaginamos un estado «Sin Gasolina» que indique que nos hemos quedado sin combustible, implicaría:</p>
<ul>
<li>Añadir una nueva constante SIN_COMBUSTIBLE para modelar el estado.</li>
<li>Añadir un nuevo <em>case </em>que contemple este estado en cada uno de los métodos existentes (Acelerar, Frenar y Contacto)</li>
<li>Modificar los métodos para contemplar que el vehículo no arrancará sin combustible, y que no podrá aumentar su velocidad si nos encontramos en marcha.</li>
</ul>
<p>¿Cómo evitar este quebradero de cabeza? Siguiendo el principio de <em>encapsular lo que cambia</em> que tan buenos resultados nos ha dado hasta el momento. Y como lo que cambia parecen ser los estados, ¡vamos a encapsularlos!</p>
<p>Lo primero que deberemos hacer será crear una interfaz común que todos los estados deberán implementar. Esta interfaz, por lo tanto, deberá exponer los métodos <em>Acelerar</em>, <em>Frenar</em> y <em>Contacto</em>.</p>
<pre class="brush: csharp; title: ; notranslate">
    public interface State
    {
        void Acelerar();
        void Frenar();
        void Contacto();
    }
</pre>
<p>Lo siguiente que haremos será crear una clase que se denominará <strong>clase de contexto</strong>, encargada de albergar el estado actual junto al resto de los atributos que se consideren oportunos. En nuestro caso concreto, será el vehículo:</p>
<p><span style="text-decoration:underline;"><strong>Vehiculo.cs</strong></span>:</p>
<pre class="brush: csharp; title: ; notranslate">
    public class Vehiculo
    {
        #region Atributos

        private State estado;                 // Estado actual del vehiculo (apagado, parado, en marcha, sin combustible)
        private int velocidadActual = 0;      // Velocidad actual del vehiculo
        private int combustibleActual = 0;    // Cantidad de combustible restante

        #endregion

        #region Properties

        // Asigna o recupera el estado del vehiculo
        public State Estado
        {
            get { return estado; }
            set { estado = value; }
        }

        // Asigna o recupera la velocidad actual del vehiculo
        public int VelocidadActual
        {
            get { return velocidadActual; }
            set { velocidadActual = value; }
        }

        // Obtiene la cantidad de combustible actual
        public int CombustibleActual
        {
            get { return combustibleActual; }
        }

        #endregion

        #region Constructores

        // El constructor inserta el combustible del que dispondra el vehiculo
        public Vehiculo(int combustible)
        {
            this.combustibleActual = combustible;
            //TODO:
            //Indicar un estado inicial (Apagado)
        }

        #endregion

        #region Metodos relacionados con los estados

        // Los metodos del contexto invocaran el metodo de la interfaz State, delegando las operaciones
        // dependientes del estado en las clases que los implementen.
        public void Acelerar()
        {
            estado.Acelerar();
            Console.WriteLine(&quot;Velocidad actual: &quot; + velocidadActual + &quot;. Combustible restante: &quot; + combustibleActual);
        }

        public void Frenar()
        {
            estado.Frenar();
        }

        public void Contacto()
        {
            estado.Contacto();
        }

        #endregion

        #region Otros metodos

        public void ModificarVelocidad(int kmh)
        {
            velocidadActual += kmh;
        }

        public void ModificarCombustible(int decilitros)
        {
            combustibleActual += decilitros;
        }

        #endregion
    }
</pre>
<p>Volveremos a esta clase dentro de un momento. Antes deberemos implementar la interfaz con <strong>una clase por cada estado existente en el sistema</strong>. Nuestra idea será crear una clase por cada uno de los estados, que implemente los métodos de la interfaz <em>State</em>. Además, añadiremos un nuevo estado <em>Sin Combustible</em>, que será un estado final (una vez alcanzado, no podrá cambiarse de estado).</p>
<p><a href="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/statepatternclassdiagram.png"><img data-attachment-id="1104" data-permalink="https://danielggarcia.wordpress.com/2014/05/20/patrones-de-comportamiento-v-patron-state/statepatternclassdiagram/" data-orig-file="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/statepatternclassdiagram.png" data-orig-size="688,426" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}" data-image-title="State Pattern Class Diagram" data-image-description="" data-image-caption="" data-medium-file="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/statepatternclassdiagram.png?w=300" data-large-file="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/statepatternclassdiagram.png?w=620" src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/statepatternclassdiagram.png?w=620" alt="State Pattern Class Diagram" width="620" height="383" class="aligncenter size-large wp-image-1104" srcset="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/statepatternclassdiagram.png?w=620 620w, https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/statepatternclassdiagram.png?w=150 150w, https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/statepatternclassdiagram.png?w=300 300w, https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/statepatternclassdiagram.png 688w" sizes="(max-width: 620px) 100vw, 620px" /></a></p>
<p>La idea de este nuevo modelo es modificar el diagrama anterior para contemplar el estado <em>SinCombustible</em>, de forma similar a la siguiente:</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/052014_0541_patronesdec4.png" alt="" /></p>
<p>Comencemos por el primero de ellos: <em>ApagadoState</em>.</p>
<pre class="brush: csharp; title: ; notranslate">
    public class ApagadoState : State
    {
        // Referencia a la clase de contexto
        private Vehiculo v;

        // Constructor que inyecta la dependencia en la clase actual
        public ApagadoState(Vehiculo v)
        {
            this.v = v;
        }

        public void Acelerar()
        { }

        public void Frenar()
        { }

        public void Contacto()
        { }
    }
</pre>
<p>Crearemos otras tres clases similares que implementen <em>State</em>: ParadoState, EnMarchaState y SinCombustibleState. Las cuatro clases que implementan los estados tienen como característica común (además de los métodos de la interfaz) que su constructor recibe como parámetro <strong>una referencia al contexto</strong>, de modo que puedan utilizar sus métodos públicos y, sobre todo, para que puedan <strong>realizar la transición de estados inyectando ese objeto en los nuevos objetos que se creen</strong>.</p>
<p>Por lo tanto, una vez comprendido esto, procederemos a codificar la funcionalidad de los estados, incluyendo las transiciones:</p>
<p><span style="text-decoration:underline;"><strong>ApagadoState.cs</strong></span>:</p>
<pre class="brush: csharp; title: ; notranslate">
    public class ApagadoState : State
    {
        // Referencia a la clase de contexto
        private Vehiculo v;

        // Constructor que inyecta la dependencia en la clase actual
        public ApagadoState(Vehiculo v)
        {
            this.v = v;
        }

        public void Acelerar()
        {
            // Acelerar con el vehiculo apagado no sirve de mucho <img src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" />
            Console.WriteLine(&quot;ERROR: El vehiculo esta apagado. Efectue el contacto para iniciar&quot;);
        }

        public void Frenar()
        {
            // Frenar con el vehiculo parado tampoco sirve de mucho...
            Console.WriteLine(&quot;ERROR: El vehiculo esta apagado. Efectue el contacto para iniciar&quot;);
        }

        public void Contacto()
        {
            // Comprobamos que el vehiculo disponga de combustible
            if (v.CombustibleActual &gt; 0)
            {
                // El vehiculo arranca -&gt; Cambio de estado
                //estado = PARADO;
                v.Estado = new ParadoState(v);
                Console.WriteLine(&quot;El vehiculo se encuentra ahora PARADO&quot;);
                v.VelocidadActual = 0;
            }
            else
            {
                // El vehiculo no arranca -&gt; Sin combustible
                //estado = SIN COMBUSTIBLE
                v.Estado = new SinCombustibleState(v);
                Console.WriteLine(&quot;El vehiculo se encuentra sin combustible&quot;);
            }
        }
    }
</pre>
<p>Como observamos, cada método es independiente e implementa su propia funcionalidad, incluyendo la transición de estados. Para ello realiza un <em>new</em> pasando como parámetro al constructor la referencia al contexto (el objeto de la clase Vehiculo). El resto de estados seguirán un patrón similar:</p>
<p><span style="text-decoration:underline;"><strong>ParadoState.cs</strong></span>:</p>
<pre class="brush: csharp; title: ; notranslate">
    public class ParadoState :State
    {
        // Referencia a la clase de contexto
        private Vehiculo v;

        // Constructor que inyecta la dependencia en la clase actual
        public ParadoState(Vehiculo v)
        {
            this.v = v;
        }

        public void Acelerar()
        {
            // Comprobamos que el vehiculo disponga de combustible
            if (v.CombustibleActual &gt; 0)
            {
                // El vehiculo se pone en marcha. Aumenta la velocidad y cambiamos de estado
                //estado = EN_MARCHA;
                v.Estado = new EnMarchaState(v);
                Console.WriteLine(&quot;El vehiculo se encuentra ahora EN MARCHA&quot;);
                v.ModificarVelocidad(10);
                v.ModificarCombustible(-10);
            }
            else
            {
                //estado = SIN COMBUSTIBLE
                v.Estado = new SinCombustibleState(v);
                Console.WriteLine(&quot;El vehiculo se encuentra ahora SIN COMBUSTIBLE&quot;);
            }
        }

        public void Frenar()
        {
            // No ocurre nada. Si el vehiculo ya se encuentra detenido, no habra efecto alguno
            Console.WriteLine(&quot;ERROR: El vehiculo ya se encuentra detenido&quot;);
        }

        public void Contacto()
        {
            // El vehiculo se apaga
            // estado = APAGADO;
            v.Estado = new ApagadoState(v);
            Console.WriteLine(&quot;El vehiculo se encuentra ahora APAGADO&quot;);
        }
    }
</pre>
<p><span style="text-decoration:underline;"><strong>EnMarchaState.cs</strong></span>:</p>
<pre class="brush: csharp; title: ; notranslate">
    public class EnMarchaState : State
    {
        private const int VELOCIDAD_MAXIMA = 200;

        // Referencia a la clase de contexto
        private Vehiculo v;

        // Constructor que inyecta la dependencia en la clase actual
        public EnMarchaState(Vehiculo v)
        {
            this.v = v;
        }

        public void Acelerar()
        {
            if (v.CombustibleActual &gt; 0)
            {
                // Aumentamos la velocidad, permaneciendo en el mismo estado
                if (v.VelocidadActual &gt;= VELOCIDAD_MAXIMA)
                {
                    Console.WriteLine(&quot;ERROR: El coche ha alcanzado su velocidad maxima&quot;);
                    v.ModificarCombustible(-10);
                }
                else
                {
                    v.ModificarVelocidad(10);
                    v.ModificarCombustible(-10);
                }
            }
            else
            {
                //estado = SIN COMBUSTIBLE
                v.Estado = new SinCombustibleState(v);
                Console.WriteLine(&quot;El vehiculo se ha quedado sin combustible&quot;);
            }
        }

        public void Frenar()
        {
            // Reducimos la velocidad. Si esta llega a 0, cambiaremos a estado &quot;PARADO&quot;
            v.ModificarVelocidad(-10);
            if (v.VelocidadActual &lt;= 0)
            {
                //estado = PARADO;
                v.Estado = new ParadoState(v);
                Console.WriteLine(&quot;El vehiculo se encuentra ahora PARADO&quot;);
            }
        }

        public void Contacto()
        {
            // No se puede detener el vehiculo en marcha!
            Console.WriteLine(&quot;ERROR: No se puede cortar el contacto en marcha!&quot;);
        }
    }
&lt;</pre>
<p><span style="text-decoration:underline;"><strong>SinCombustibleState.cs</strong></span>:</p>
<pre class="brush: csharp; title: ; notranslate">
    public class SinCombustibleState : State
    {
        // Referencia a la clase de contexto
        private Vehiculo v;

        // Constructor que inyecta la dependencia en la clase actual
        public SinCombustibleState(Vehiculo v)
        {
            this.v = v;
        }

        public void Acelerar()
        {
            Console.WriteLine(&quot;ERROR: El vehiculo se encuentra sin combustible&quot;);
        }

        public void Frenar()
        {
            Console.WriteLine(&quot;ERROR: El vehiculo se encuentra sin combustible&quot;);
        }

        public void Contacto()
        {
            Console.WriteLine(&quot;ERROR: El vehiculo se encuentra sin combustible&quot;);
        }
    }
</pre>
<p>Ahora modificaremos el constructor del contexto para que disponga de un estado inicial (por ejemplo, ApagadoState)</p>
<pre class="brush: csharp; title: ; notranslate">
        // El constructor inserta el combustible del que dispondra el vehiculo e instancia el
        // estado inicial (apagado)
        public Vehiculo(int combustible)
        {
            this.combustibleActual = combustible;

            //Indicar un estado inicial (Apagado)
            estado = new ApagadoState(this);
        }
</pre>
<p>Finalmente, disponemos de un pequeño fragmento de código que haga uso de nuestro patrón:</p>
<pre class="brush: csharp; title: ; notranslate">
            Vehiculo v = new Vehiculo(20);

            v.Acelerar();
            v.Contacto();
            v.Acelerar();
            v.Acelerar();
            v.Acelerar();
            v.Frenar();
            v.Frenar();
            v.Frenar();
            v.Frenar();
</pre>
<p>El resultado de nuestra ejecución será el siguiente:</p>
<p><a href="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/stateresult.png"><img data-attachment-id="1105" data-permalink="https://danielggarcia.wordpress.com/2014/05/20/patrones-de-comportamiento-v-patron-state/stateresult/" data-orig-file="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/stateresult.png" data-orig-size="677,322" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}" data-image-title="Resultado" data-image-description="" data-image-caption="" data-medium-file="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/stateresult.png?w=300" data-large-file="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/stateresult.png?w=620" src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/stateresult.png?w=620" alt="Resultado" width="620" height="294" class="aligncenter size-large wp-image-1105" srcset="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/stateresult.png?w=620 620w, https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/stateresult.png?w=150 150w, https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/stateresult.png?w=300 300w, https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/stateresult.png 677w" sizes="(max-width: 620px) 100vw, 620px" /></a></p>
<h2>¿Cuándo utilizar este patrón? Ejemplos reales</h2>
<p>Se suele decir que los patrones <em>Strategy </em>y <em>State</em> son hermanos que fueron separados al nacer. Esto se debe a que sus razones de ser son muy parecidas: modificar el funcionamiento de un objeto en tiempo de ejecución de forma transparente a través de un proceso de composición. La diferencia fundamental, sin embargo, se encuentra en que el patrón <em>Strategy</em> tiene como objetivo <strong>proporcionar alternativas para realizar una misma tarea</strong>, aunque ésta sea de alto nivel, es decir: el patrón <em>Strategy</em> es adecuado cuando queremos, por ejemplo, serializar un objeto. Cada una de las implementaciones encapsulará una forma distinta de serialización: binaria, Base64, como un fichero XML, JSON, etc. <em>State</em>, por su parte, tiene su razón de ser en <strong>proporcionar comportamientos distintos </strong>cuando la aplicación se encuentra en <strong>estados distintos</strong>. Con este patrón, la clase que implemente nuestro <em>State</em> realizará operaciones distintas dependiendo de su estado, no proporcionará «varias formas de hacer lo mismo». Por ello, <em>Strategy </em>y <em>State</em> son patrones distintos, aunque muy similares: <em>Strategy </em>encapsula el algoritmo, mientras que <em>State</em> encapsulará un comportamiento que variará dependiendo del estado en el que se encuentre el programa.</p>
<p>Por lo tanto, la aplicación de este patrón será adecuada en entornos en los que se identifiquen «estados» con operaciones comunes que varíen su comportamiento dependiendo de en cuál de ellos se encuentren activos. Un buen ejemplo de este comportamiento sería la implementación de un <em>Workflow</em> de un gestor de defectos en el que un elemento de trabajo pueda encontrarse en distintos estados (nuevo, en curso, corregido&#8230;) y en el que cada uno de los estados implica un conjunto de posibles operaciones y transiciones que difieren entre sí.</p>
<p>Una posible mejora de este patrón consiste en extraer cualquier tipo de información variable (en este ejemplo, la velocidad y el combustible) y situarla en el contexto o en otra clase externa, permitiendo de este modo modelar cada estado de forma estática o a través de un patrón Singleton. Así, en lugar de instanciar un estado cada vez que se necesite realizar un cambio, bastará con referenciar la instancia ya existente, que únicamente incluirá el comportamiento (el código mostrado en este artículo sería un buen ejemplo en el que podría aplicarse esta alternativa).</p>
<h3>Fuentes:</h3>
<ul>
<li><a href="http://shop.oreilly.com/product/9780596007126.do">Head First Design Patterns</a> (Freeman et al.)</li>
<li><a href="http://java.dzone.com/articles/design-patterns-state">Design Pattern Uncovered: State Pattern</a> (James Sugrue)</li>
<li><a href="http://www.dofactory.com/Patterns/PatternState.aspx">.NET State Pattern</a> (doFactory)</li>
<li><a href="http://userpages.umbc.edu/~tarr/dp/lectures/StateStrategy.pdf">The State and Strategy Patterns</a> (Bob Tarr, pdf)</li>
</ul>
<p style="text-align:center;">
]]></content:encoded>
					
					<wfw:commentRss>https://danielggarcia.wordpress.com/2014/05/20/patrones-de-comportamiento-v-patron-state/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1102</post-id>
		<media:content url="https://1.gravatar.com/avatar/77787450a00d8f7372bceaa70593a9c6156f81bb51204ddc5bb88b1ad375de8a?s=96&#38;d=https%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">danielggarcia</media:title>
		</media:content>

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/052014_0541_patronesdec1.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/052014_0541_patronesdec2.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/052014_0541_patronesdec3.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/statepatternclassdiagram.png?w=620" medium="image">
			<media:title type="html">State Pattern Class Diagram</media:title>
		</media:content>

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/052014_0541_patronesdec4.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/stateresult.png?w=620" medium="image">
			<media:title type="html">Resultado</media:title>
		</media:content>
	</item>
		<item>
		<title>Patrones de Comportamiento (IV): Patrón Strategy</title>
		<link>https://danielggarcia.wordpress.com/2014/05/12/patrones-de-comportamiento-iv-patron-strategy/</link>
					<comments>https://danielggarcia.wordpress.com/2014/05/12/patrones-de-comportamiento-iv-patron-strategy/#comments</comments>
		
		<dc:creator><![CDATA[Daniel García]]></dc:creator>
		<pubDate>Mon, 12 May 2014 21:26:53 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Nivel intermedio]]></category>
		<category><![CDATA[Patrones de Diseño]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[ejemplo]]></category>
		<category><![CDATA[patrón strategy]]></category>
		<category><![CDATA[strategy pattern]]></category>
		<guid isPermaLink="false">http://danielggarcia.wordpress.com/?p=1091</guid>

					<description><![CDATA[Objetivo: «Definir una familia de algoritmos, encapsular cada uno de ellos y hacerlos intercambiables. Strategy permite cambiar el algoritmo independientemente de los clientes que lo utilicen». Design Patterns: Elements of Reusable Object-Oriented Software En el artículo anterior veíamos cómo un patrón de diseño puede ayudarnos a encapsular distintos algoritmos a partir de una «plantilla» cuyos [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong>Objetivo:<br />
</strong></p>
<blockquote><p><em>«Definir una familia de algoritmos, encapsular cada uno de ellos y hacerlos intercambiables. Strategy permite cambiar el algoritmo independientemente de los clientes que lo utilicen».<br />
</em></p>
<p>Design Patterns: Elements of Reusable Object-Oriented Software</p></blockquote>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/051214_2126_patronesdec1.png" alt="" /></p>
<p>En el artículo anterior veíamos cómo un patrón de diseño puede ayudarnos a encapsular distintos algoritmos a partir de una «plantilla» cuyos hijos se encargaban de especializar. El patrón <em>Strategy</em>, por su parte, no bucea en los detalles, sino que va un paso más allá: encapsulará un algoritmo completo ignorando los detalles de su implementación, permitiendo intercambiarlo en tiempo de ejecución para permitir actuar a la clase cliente con un comportamiento distinto.</p>
<p>El nombre de este patrón evoca la posibilidad de realizar un cambio de estrategia en tiempo de ejecución sustituyendo un objeto que se encargará de implementarla. No nos preocupará el «cómo». De hecho, ni siquiera nos importará «el qué»: la clase que actúa como interfaz del patrón únicamente tendrá que exponer el método o métodos que deberá invocar el cliente.</p>
<p><span id="more-1091"></span></p>
<h2>Strategy pattern y videojuegos</h2>
<p>Un ejemplo clásico para entender este patrón es el de un protagonista de un videojuego en el cual manejamos a un soldado que puede portar y utilizar varias armas distintas. La clase (o clases) que representan a nuestro soldado no deberían de preocuparse de los detalles de las armas que porta: debería bastar, por ejemplo, con un método de interfaz «atacar» que dispare el arma actual y otro método «recargar» que inserte munición en ésta (si se diera el caso). En un momento dado, otro método «<em>cambiarArma</em>» podrá sustituir el objeto equipado por otro, manteniendo la interfaz intacta. Da igual que nuestro soldado porte un rifle, una pistola o un fusil: los detalles de cada estrategia estarán encapsulados dentro de cada una de las clases intercambiables que representan las armas. Nuestra clase cliente (el soldado) únicamente debe preocuparse de las acciones comunes a todas ellas: atacar, recargar y cambiar de arma. Éste último método, de hecho, será el encargado de realizar la operación de «cambio de estrategia» que forma parte del patrón.</p>
<p>Por lo tanto, el patrón <em>Strategy</em> es, como podemos imaginar, uno de los patrones más utilizados a la hora de diseñar software. Siempre que exista una posibilidad de realizar una tarea de distintas formas posibles, el patrón <em>Strategy</em> tendrá algo que decir al respecto.</p>
<p>Nuestro diagrama de clases muestra una interfaz denominada <em>IStrategy</em> que expone un método <em>operacion()</em>. Las clases que implementen esta interfaz serán aquellas que implementen las distintas estrategias a realizar por el cliente, y como podemos observar, no tienen mayor dificultad: una interfaz, varias clases que la implementan. Programación Orientada a Objetos básica.</p>
<p>La filosofía del patrón, por lo tanto, radica en el enlace entre la llamada<strong> clase de contexto y la propia interfaz</strong>. Esta clase de contexto será el «<em>broker</em>» o intermediario entre el cliente y las clases que implementan la estrategia, y por lo tanto, sus funciones serán simples: cambiar la estrategia actual y ejecutarla. Si hablásemos de un videojuego, el contexto sería el objeto encargado de equipar la pistola al pulsar la tecla «1» y de invocar la funcionalidad de disparo cuando hacemos click con el ratón. Esto se traduciría por instanciar un objeto <em>StrategyPistola</em> en la referencia <em>IStrategy</em> e invocar el método «<em>atacar()</em>» de ésta para que la clase que implementa la interfaz se encargue del trabajo sucio (¡nunca mejor dicho!).</p>
<h2>Implementando el patrón</h2>
<p>Pese a que el ejemplo de nuestro videojuego es bastante ilustrativo, dado que en esta serie de artículos tenemos fijación por los coches, implementaremos el patrón a través de un hipotético módulo de la centralita del vehículo que nos permitirá alternar entre una conducción normal y deportiva. La diferencia entre ambas será simple: mayor consumo, mayor potencia y mayor velocidad. Podríamos añadir más comportamientos «personalizados», como el endurecimiento de la suspensión, pero con estos dos elementos será suficiente para captar la idea.</p>
<p>Comencemos añadiendo la interfaz <em>ITipoConduccion</em>, que simbolizará la interfaz de la estrategia (<em>IStrategy</em>). Le añadiremos tres métodos: uno para obtener la descripción del tipo de conducción actual, otro que proporcione el incremento de velocidad en relación al combustible inyectado y un tercer método que indique la cantidad de potencia suministrada por el motor, también en proporción al combustible que recibe.<br />
<strong><span style="text-decoration:underline;">ITipoConduccion.cs</span></strong></p>
<p><span style="text-decoration:underline;"><strong>ITipoConduccion.cs</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public interface ITipoConduccion
    {
        string ObtenerDescripcion();
        int ObtenerPotencia(float decilitrosCombustible);
        int ObtenerIncrementoVelocidad(float decilitrosCombustible);
    }
</pre>
<p>A continuación añadiremos las estrategias en sí, es decir, las clases que implementan la interfaz y dotan de distintos comportamientos que serán seleccionados por el contexto. Habíamos dicho que utilizaríamos dos: conducción normal y conducción deportiva. Por lo tanto, crearemos dos clases que proporcionen distintos comportamientos para los mismos métodos:</p>
<p><span style="text-decoration:underline;"><strong>ConduccionNormal.cs</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class ConduccionNormal : ITipoConduccion
    {
        public string ObtenerDescripcion()
        {
            return &quot;Conduccion Normal&quot;;
        }

        public int ObtenerPotencia(float decilitrosCombustible)
        {
            return (int)(decilitrosCombustible * 0.842) + 3;
        }

        public int ObtenerIncrementoVelocidad(float decilitrosCombustible)
        {
            return (int)(decilitrosCombustible * 0.422) + 2;
        }
    }
</pre>
<p><span style="text-decoration:underline;"><strong>ConduccionDeportiva.cs</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class ConduccionDeportiva : ITipoConduccion
    {
        public string ObtenerDescripcion()
        {
            return &quot;Conduccion Deportiva&quot;;
        }

        public int ObtenerPotencia(float decilitrosCombustible)
        {
            return (int)(decilitrosCombustible * 0.987) + 5;
        }

        public int ObtenerIncrementoVelocidad(float decilitrosCombustible)
        {
            return (int)(decilitrosCombustible * 0.618) + 3;
        }
    }
</pre>
<p>Lo siguiente será crear el contexto. Esta clase será la encargada de establecer la conexión entre el cliente y las clases que implementan la estrategia, sustituyendo la clase que la implementa dependiendo del comportamiento esperado. Por lo tanto, se compondrá de una referencia a la interfaz que implementarán las estrategias más un método que permita cambiar de instancia (es decir, una <em>property</em> o un <em>setter</em> de toda la vida). A partir de esta funcionalidad básica, el contexto podrá realizar otras operaciones relacionadas con la estrategia que pretende modelar, como por ejemplo la invocación de sus métodos o la encapsulación del cambio de estrategia.</p>
<p><span style="text-decoration:underline;"><strong>Contexto.cs</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class Contexto
    {
        // Referencia a la interfaz
        private ITipoConduccion tipoConduccion;

        // Propiedad que establecerá un nuevo tipo de conducción (cambio de estrategia)
        public ITipoConduccion TipoConduccion
        {
            get { return tipoConduccion; }
            set { this.tipoConduccion = value; }
        }

		// Métodos de servicio (invocan los métodos implementados por las estrategias)
        public string ObtenerDescripcion()
        {
            return tipoConduccion.ObtenerDescripcion();
        }

        public int IncrementarVelocidad(float combustible)
        {
            return tipoConduccion.ObtenerIncrementoVelocidad(combustible);
        }

        public int IncrementarPotencia(float combustible)
        {
            return tipoConduccion.ObtenerPotencia(combustible);
        }
    }
</pre>
<p>En realidad, la propia clase cliente puede actuar como clase de contexto, pero siempre será mejor minimizar el acoplamiento entre las estrategias y las reglas de negocio. De este modo, respetaremos otro de los principios de la orientación a objetos: <em>una clase, una responsabilidad</em>. Para comprobar el funcionamiento de nuestro cliente, bastará con utilizar el siguiente código que hará uso del contexto para cambiar de estrategia en tiempo de ejecución:</p>
<p><span style="text-decoration:underline;"><strong>Vehiculo.cs</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class Vehiculo
    {
        private Contexto contexto;

        public Vehiculo()
        {
            contexto = new Contexto();
        }

        public void ConduccionDeportiva()
        {
            ITipoConduccion conduccionDeportiva = new ConduccionDeportiva();
            contexto.TipoConduccion = conduccionDeportiva;
        }

        public void ConduccionNormal()
        {
            ITipoConduccion conduccionNormal = new ConduccionNormal();
            contexto.TipoConduccion = conduccionNormal;
        }

        // Métodos que invocan la funcionalidad implementada por la interfaz
        public void Acelerar(float combustible)
        {
            string descripcion = contexto.ObtenerDescripcion();
            int incrementoVelocidad = contexto.IncrementarVelocidad(combustible);
            int potencia = contexto.IncrementarPotencia(combustible);

            Console.WriteLine(&quot;Tipo de conducción &quot; + descripcion);
            Console.WriteLine(&quot;Combustible inyectado: &quot; + combustible);
            Console.WriteLine(&quot;Potencia proporcionada: &quot; + potencia);
            Console.WriteLine(&quot;Incremento de velocidad: &quot; + incrementoVelocidad);
        }
    }
</pre>
<p>Finalmente, el código que invoca a nuestro cliente, que será el siguiente:</p>
<pre class="brush: csharp; title: ; notranslate">
        static void Main(string[] args)
        {
            Vehiculo v = new Vehiculo();
            v.ConduccionDeportiva();
            v.Acelerar(2.4f);

            Console.WriteLine(&quot;&quot;);

            v.ConduccionNormal();
            v.Acelerar(2.4f);

            Console.ReadLine();
        }
</pre>
<p>El resultado final será el siguiente:</p>
<p><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/051214_2126_patronesdec2.png" alt="" /></p>
<h2>¿Cuándo utilizar este patrón? Ejemplos reales</h2>
<p>Este patrón es aconsejable, como ya hemos comentado, en situaciones en los que una misma operación (o conjunto de operaciones) puedan realizarse de formas distintas. A <em>grosso modo</em>, el patrón <em>Strategy</em> realiza una tarea bastante similar al patrón <em>Template Method</em>, salvo porque en este caso el algoritmo no tiene por qué contar con pasos en común y porque <em>Strategy</em> confía en la composición mientras que <em>Template Method</em> se basa en la herencia.</p>
<p>Ejemplos reales de este patrón se aplican, por ejemplo, la serialización de objetos. Una interfaz que exponga un método <em>serialize()</em> podrá codificar un objeto en distintos formatos (String64, XML, JSON). El cliente no necesita saber cómo se realizará esta operación: bastará con que el contexto seleccione la estrategia adecuada y el resultado de la operación dependerá de la opción concreta que se haya seleccionado. Del mismo modo podemos pensar en una conexión a un servicio web: podremos realizarla mediante TCP/IP, HTTP, HTTPS, Named Pipes&#8230; todo esto deberá ser transparente para el cliente: El contexto será el encargado de adoptar una forma concreta de conexión.</p>
<p>¿Más ejemplos? Los compresores funcionan a través de estrategias (se utiliza un algoritmo distinto para comprimir en <em>zip</em> o en <em>rar</em>), y en general, cualquier programa capaz de almacenar y transmitir datos en distintos formatos implementarán este patrón. Por lo tanto, como podemos imaginar, nos encontramos, tanto por su utilidad como por su sencillez, con uno de los patrones más utilizados de todos los expuestos por el GoF.</p>
<h3>Fuentes:</h3>
<ul>
<li><a href="http://shop.oreilly.com/product/9780596007126.do" target="_blank">Head First Design Patterns</a> (Freeman et al.)</li>
</ul>
<ul>
<li><a href="http://www.oodesign.com/strategy-pattern.html" target="_blank">Object Oriented Design: Strategy</a></li>
</ul>
<ul>
<li><a href="http://design-patterns-with-uml.blogspot.com.ar/2013/02/strategy-pattern.html" target="_blank">Design Patterns with UML: Strategy</a></li>
</ul>
<ul>
<li><a href="http://www.dofactory.com/Patterns/PatternStrategy.aspx" target="_blank">DOFactory: Strategy Pattern</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://danielggarcia.wordpress.com/2014/05/12/patrones-de-comportamiento-iv-patron-strategy/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1091</post-id>
		<media:content url="https://1.gravatar.com/avatar/77787450a00d8f7372bceaa70593a9c6156f81bb51204ddc5bb88b1ad375de8a?s=96&#38;d=https%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">danielggarcia</media:title>
		</media:content>

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/051214_2126_patronesdec1.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/051214_2126_patronesdec2.png" medium="image" />
	</item>
		<item>
		<title>Patrones de Comportamiento (III): Template Method</title>
		<link>https://danielggarcia.wordpress.com/2014/05/05/patrones-de-comportamiento-iii-template-method/</link>
					<comments>https://danielggarcia.wordpress.com/2014/05/05/patrones-de-comportamiento-iii-template-method/#comments</comments>
		
		<dc:creator><![CDATA[Daniel García]]></dc:creator>
		<pubDate>Mon, 05 May 2014 05:11:08 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Nivel avanzado]]></category>
		<category><![CDATA[Patrones de Diseño]]></category>
		<category><![CDATA[behavioral patterns]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[ejemplo]]></category>
		<category><![CDATA[patrón modelo]]></category>
		<category><![CDATA[patrón plantilla]]></category>
		<category><![CDATA[patrones de comportamiento]]></category>
		<category><![CDATA[template method]]></category>
		<guid isPermaLink="false">http://danielggarcia.wordpress.com/?p=1083</guid>

					<description><![CDATA[Objetivo: «Permitir que ciertos pasos de un algoritmo definidos en un método de una clase sean redefinidos en sus clases derivadas sin necesidad de sobrecargar la operación entera». Design Patterns: Elements of Reusable Object-Oriented Software Si el patrón Command nos permite encapsular una invocación a un método, el patrón Template Method o Método Modelo establece [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong>Objetivo:<br />
</strong></p>
<blockquote><p><em>«Permitir que ciertos pasos de un algoritmo definidos en un método de una clase sean redefinidos en sus clases derivadas sin necesidad de sobrecargar la operación entera».<br />
</em></p>
<p>Design Patterns: Elements of Reusable Object-Oriented Software</p></blockquote>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/050414_1810_patronesdec1.png" alt="" /></p>
<p>Si el patrón <em>Command</em> nos permite encapsular una invocación a un método, el patrón <em>Template Method</em> o <em>Método Modelo</em> establece una forma de encapsular <strong>algoritmos</strong>. Este patrón se basa en un principio muy sencillo: si un algoritmo puede aplicarse a varios supuestos en los que únicamente cambie un pequeño número de operaciones, la idea será utilizar una clase para modelarlo a través de sus operaciones. Esta clase base se encargará de definir los pasos comunes del algoritmo, mientras que las clases que hereden de ella implementarán los detalles propios de cada caso concreto, es decir, el código específico para cada caso.</p>
<p>El procedimiento es sencillo:</p>
<ul>
<li>Se declara una clase abstracta, que será la plantilla o modelo. Esta clase definirá una serie de funciones y métodos. Aquellas que sean comunes estarán implementadas. Aquellas que dependan de cada caso concreto, se declararán como abstractas, obligando a las clases hijas a implementarlas.</li>
<li>Cada clase derivada implementará los métodos específicos, acudiendo a la clase base para ejecutar el código común.</li>
<li>La clase base también se encargará de la lógica del algoritmo, ejecutando los pasos en un orden preestablecido (las clases hijas no deberían poder modificar el algoritmo, únicamente definir la funcionalidad específica que tienen que implementar).</li>
</ul>
<p>Dado que la clase padre es la que se encarga de llamar los métodos de las clases derivadas (los pasos del algoritmo estarán implementado en la clase base), se trata de una aplicación manifiesta del <strong>principio de inversión de dependencias</strong>: la clase base no tiene por qué saber nada acerca de sus hijas, pero aún así, se encargará de invocar su funcionalidad cuando sea necesario. El <em>principio de Hollywood</em> («no nos llames, nosotros te llamaremos») vuelve a entrar en escena.</p>
<p><span id="more-1083"></span></p>
<h2>Implementando el patrón</h2>
<p>En anteriores artículos hemos hecho uso de este patrón sin ser conscientes de ello al definir el funcionamiento de un motor de cuatro tiempos. Veíamos que el funcionamiento de un motor de gasolina se basaba en el siguiente algoritmo:</p>
<ul>
<li><strong>Admisión</strong>: el descenso del pistón crea un vacío que aspira la mezcla de aire y combustible de la válvula de admisión. La válvula de escape permanece cerrada.</li>
<li><strong>Compresión</strong>: una vez que el pistón ha bajado hasta el final, se cierra la válvula de admisión. El pistón asciende, comprimiendo la mezcla y aumentando la presión.</li>
<li><strong>Explosión</strong>: el pistón alcanza la parte superior y la bujía produce una chispa que hace explotar la mezcla de aire y combustible, haciendo que el pistón vuelva a descender.</li>
<li><strong>Escape</strong>: la válvula de escape se abre. El pistón asciende nuevamente, empujando los gases resultantes de la explosión y comenzando un nuevo ciclo.</li>
</ul>
<p>Ahora veamos cómo funciona, a grandes rasgos, un motor diesel de cuatro tiempos:</p>
<ul>
<li><strong>Admisión</strong>: el descenso del pistón crea un vacío que aspira aire desde la válvula de admisión. La válvula de escape permanece cerrada.</li>
<li><strong>Compresión</strong>: una vez que el pistón ha bajado hasta el final, se cierra la válvula de admisión. El pistón asciende, comprimiendo el aire y aumentando la presión.</li>
<li><strong>Combustión</strong>: los inyectores pulverizan el combustible, haciendo que la presión se encargue de aumentar la temperatura, haciendo que se produzca la combustión y la expansión de los gases que fuerzan el descenso del pistón.</li>
<li><strong>Escape</strong>: la válvula de escape se abre. El pistón asciende nuevamente, empujando los gases resultantes de la explosión y comenzando un nuevo ciclo.</li>
</ul>
<p>Tal y como observamos, ambos motores tienen un funcionamiento muy similar. Las fases 2 y 4 (compresión y escape) son idénticas, la fase 1 (admisión) varía ligeramente, mientras que la fase 3 (explosión en el motor de gasolina, combustión en el motor diesel) tiene un comportamiento diferente. ¿Cómo encaja aquí el patrón <em>Template Method</em>?</p>
<p>Dado que el algoritmo para realizar el ciclo del motor tiene los mismos pasos efectuados en el mismo orden, es el contexto adecuado para utilizar este patrón. Podemos crear una superclase <em>Motor</em> que implemente las fases comunes a ambos motores (<em>Compresión, Escape</em>) más el algoritmo <em>RealizarFaseMotor,</em> que será el encargado de invocar los métodos en un orden fijo. Esta ejecución será <strong>invariable</strong>, por lo que las clases derivadas únicamente podrán (y deberán) implementar las partes específicas de cada motor.</p>
<p>Dado que la fase <em>Admisión</em> varía ligeramente (inyección de mezcla de combustible y gas en el motor de gasolina frente a inyección de gas en el motor diesel), es posible implementar la parte común en el propio método de la superclase y <strong>encapsular únicamente la parte que varía</strong> en otro método que será invocado desde <em>Compresión</em>. Así respetaremos otro de los principios de la orientación a objetos: <strong>encapsular aquello que es susceptible de cambiar</strong>.</p>
<p>Comencemos creando la clase abstracta <em>Motor</em>. Si bien en otros casos hemos hablado de utilizar una interfaz o una clase abstracta para implementar una abstracción, en este caso <strong>será necesario utilizar una clase abstracta, no una interfaz</strong>. ¿Por qué? Porque si utilizamos una interfaz únicamente podremos definir la firma de los métodos a utilizar, pero no podremos codificar una funcionalidad común, que es lo que pretende este patrón. Por lo tanto, <em>Motor</em> será una clase abstracta que implementará de forma explícita la parte común y declarará como <em>abstractos</em> los métodos que las clases derivadas estarán obligadas a implementar. Comenzaremos declarando unas cuantas variables: dos para modelar el estado de las válvulas y otras dos para modelar el ángulo actual del cigüeñal y del árbol de levas. También crearemos un método que «reinicie» el ángulo de estos dos elementos, manteniéndolos siempre entre 0 y 359 grados:</p>
<pre class="brush: csharp; title: ; notranslate">
    public abstract class Motor
    {
        // Estado de las válvulas
        private bool valvulaAdmisionAbierta = false;
        private bool valvulaEscapeAbierta = false;

        // Ángulos del cigueñal y del árbol de levas
        protected int anguloCiguenal = 0;
        protected int anguloArbolLevas = 0;


        // Método que mantendrá el ángulo entre 0 y 359 grados
        protected int SumarAngulo(int anguloActual, int cantidad)
        {
            if (anguloActual + cantidad &gt;= 360)
                return anguloActual + cantidad - 360;
            else
                return anguloActual + cantidad;
        }

    }
</pre>
<p>A continuación modelaremos los dos métodos que implementará de forma explícita la clase base: compresión y escape:</p>
<pre class="brush: csharp; title: ; notranslate">
        // Segunda Fase: Compresión
        protected void Compresion()
        {
            Console.WriteLine(&quot;COMENZANDO FASE DE COMPRESION&quot;);

            // Se cierra la válvula de admisión
            valvulaAdmisionAbierta = false;

            // Giros del cigueñal y del árbol de levas
            anguloCiguenal = SumarAngulo(anguloCiguenal, 360);
            anguloArbolLevas = SumarAngulo(anguloArbolLevas, 180);

            Console.WriteLine(&quot;Angulo del ciguenal: &quot; + anguloCiguenal);
            Console.WriteLine(&quot;Angulo del arbol de levas: &quot; + anguloArbolLevas);

            Console.WriteLine(&quot;Valvula de admision abierta: &quot; + valvulaAdmisionAbierta);
            Console.WriteLine(&quot;Valvula de escape abierta: &quot; + valvulaEscapeAbierta + &quot;\n&quot;);
        }
        // Cuarta Fase: Escape
        protected void Escape()
        {
            Console.WriteLine(&quot;COMENZANDO FASE DE ESCAPE&quot;);

            // Se abre la válvula de escape
            valvulaEscapeAbierta = true;

            // Giros del cigueñal y del árbol de levas
            anguloCiguenal = SumarAngulo(anguloCiguenal, 180);
            anguloArbolLevas = SumarAngulo(anguloArbolLevas, 90);

            Console.WriteLine(&quot;Angulo del ciguenal: &quot; + anguloCiguenal);
            Console.WriteLine(&quot;Angulo del arbol de levas: &quot; + anguloArbolLevas);

            Console.WriteLine(&quot;Gases expulsados. Fin de ciclo&quot;);
        }

    }
</pre>
<p>Hemos dicho que la tercera fase depende exclusivamente de las clases derivadas. Por lo tanto, nuestra clase motor se limitará a declarar el método como abstracto y obligar a las clases derivadas a implementar la funcionalidad específica de cada motor:</p>
<pre class="brush: csharp; title: ; notranslate">
        // Tercera Fase: Consumo del combustible. Dado que depende del motor concreto,
        // este método será abstracto y deberá ser implementado por la clase derivada.
        protected abstract void ConsumirCombustible();
</pre>
<p>Nos queda la primera fase: admisión. Hemos dicho que parte de la funcionalidad es común (bajada del pistón, apertura de la válvula de admisión), pero otra parte depende de si el motor es de gasolina (inyección de combustible y aire) o diesel (inyección de aire). Por tanto, creamos otro método abstracto que las clases hija tendrán que codificar (<em>BajarPiston()</em>) y se invoca desde el método <em>Admision()</em>, que codificará la parte común:</p>
<pre class="brush: csharp; title: ; notranslate">
        // La bajada del pistón depende del motor concreto, por lo que deberá ser implementada
        // por la clase hija.
        protected abstract void BajarPiston();

        // Primera Fase: Admisión
        protected void Admision()
        {
            Console.WriteLine(&quot;COMENZANDO FASE DE ADMISION&quot;);

            // Se abre la válvula de admisión y se cierra la válvula de escape
            valvulaAdmisionAbierta = true;
            valvulaEscapeAbierta = false;

            // Se baja el pistón. Esta operación será distinta en el motor diesel (que
            // inyectará aire) o gasolina (que inyectará una mezcla de aire y combustible)
            BajarPiston();

            anguloCiguenal = SumarAngulo(anguloCiguenal, 180);
            anguloArbolLevas = SumarAngulo(anguloArbolLevas, 90);

            Console.WriteLine(&quot;Angulo del ciguenal: &quot; + anguloCiguenal);
            Console.WriteLine(&quot;Angulo del arbol de levas: &quot; + anguloArbolLevas);

            Console.WriteLine(&quot;Valvula de admision abierta: &quot; + valvulaAdmisionAbierta);
            Console.WriteLine(&quot;Valvula de escape abierta: &quot; + valvulaEscapeAbierta + &quot;\n&quot;);
        } 
</pre>
<p>Finalmente, codificamos el propio algoritmo, de carácter público, que se encargará de invocar todos los pasos en un orden determinado:</p>
<pre class="brush: csharp; title: ; notranslate">
        // Método público que ejecutará el algoritmo completo
        public void RealizarFaseMotor()
        {
            Admision();             // Parcialmente implementado en la clase base
            Compresion();           // Implementado en la clase base
            ConsumirCombustible();  // Delegado en las clases hijas
            Escape();               // Implementado en la clase base
        }
</pre>
<p>La clase completa, por lo tanto, tendrá el siguiente aspecto:</p>
<p><span style="text-decoration:underline;"><strong>Motor.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public abstract class Motor
    {
        // Estado de las válvulas
        private bool valvulaAdmisionAbierta = false;
        private bool valvulaEscapeAbierta = false;

        // Ángulos del cigueñal y del árbol de levas
        protected int anguloCiguenal = 0;
        protected int anguloArbolLevas = 0;

        // Método público que ejecutará el algoritmo completo
        public void RealizarFaseMotor()
        {
            Admision();             // Parcialmente implementado en la clase base
            Compresion();           // Implementado en la clase base
            ConsumirCombustible();  // Delegado en las clases hijas
            Escape();               // Implementado en la clase base
        }

        // Primera Fase: Admisión
        protected void Admision()
        {
            Console.WriteLine(&quot;COMENZANDO FASE DE ADMISION&quot;);

            // Se abre la válvula de admisión y se cierra la válvula de escape
            valvulaAdmisionAbierta = true;
            valvulaEscapeAbierta = false;

            // Se baja el pistón. Esta operación será distinta en el motor diesel (que
            // inyectará aire) o gasolina (que inyectará una mezcla de aire y combustible)
            BajarPiston();

            anguloCiguenal = SumarAngulo(anguloCiguenal, 180);
            anguloArbolLevas = SumarAngulo(anguloArbolLevas, 90);

            Console.WriteLine(&quot;Angulo del ciguenal: &quot; + anguloCiguenal);
            Console.WriteLine(&quot;Angulo del arbol de levas: &quot; + anguloArbolLevas);

            Console.WriteLine(&quot;Valvula de admision abierta: &quot; + valvulaAdmisionAbierta);
            Console.WriteLine(&quot;Valvula de escape abierta: &quot; + valvulaEscapeAbierta + &quot;\n&quot;);
        }

        // La bajada del pistón depende del motor concreto, por lo que deberá ser implementada
        // por la clase hija.
        protected abstract void BajarPiston();

        // Segunda Fase: Compresión
        protected void Compresion()
        {
            Console.WriteLine(&quot;COMENZANDO FASE DE COMPRESION&quot;);

            // Se cierra la válvula de admisión
            valvulaAdmisionAbierta = false;

            // Giros del cigueñal y del árbol de levas
            anguloCiguenal = SumarAngulo(anguloCiguenal, 360);
            anguloArbolLevas = SumarAngulo(anguloArbolLevas, 180);

            Console.WriteLine(&quot;Angulo del ciguenal: &quot; + anguloCiguenal);
            Console.WriteLine(&quot;Angulo del arbol de levas: &quot; + anguloArbolLevas);

            Console.WriteLine(&quot;Valvula de admision abierta: &quot; + valvulaAdmisionAbierta);
            Console.WriteLine(&quot;Valvula de escape abierta: &quot; + valvulaEscapeAbierta + &quot;\n&quot;);
        }

        // Tercera Fase: Consumo del combustible. Dado que depende del motor concreto,
        // este método será abstracto y deberá ser implementado por la clase derivada.
        protected abstract void ConsumirCombustible();

        // Cuarta Fase: Escape
        protected void Escape()
        {
            Console.WriteLine(&quot;COMENZANDO FASE DE ESCAPE&quot;);

            // Se abre la válvula de escape
            valvulaEscapeAbierta = true;

            // Giros del cigueñal y del árbol de levas
            anguloCiguenal = SumarAngulo(anguloCiguenal, 180);
            anguloArbolLevas = SumarAngulo(anguloArbolLevas, 90);

            Console.WriteLine(&quot;Angulo del ciguenal: &quot; + anguloCiguenal);
            Console.WriteLine(&quot;Angulo del arbol de levas: &quot; + anguloArbolLevas);

            Console.WriteLine(&quot;Gases expulsados. Fin de ciclo&quot;);
        }

        // Método que mantendrá el ángulo entre 0 y 359 grados
        protected int SumarAngulo(int anguloActual, int cantidad)
        {
            if (anguloActual + cantidad &gt;= 360)
                return anguloActual + cantidad - 360;
            else
                return anguloActual + cantidad;
        }
    }
</pre>
<p>Una vez que tenemos la clase padre, implementaremos las clases derivadas: <em>MotorGasolina</em> y <em>MotorDiesel</em>. Únicamente tendrán que implementar las partes específicas, es decir, los métodos <em>BajarPiston() </em>y <em>ConsumirCombustible()</em>:</p>
<p><span style="text-decoration:underline;"><strong>MotorGasolina.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class MotorGasolina : Motor
    {
        protected override void BajarPiston()
        {
            Console.WriteLine(&quot;Inyectando aire y combustible en el motor&quot;);
        }

        public override void ConsumirCombustible()
        {
            Console.WriteLine(&quot;COMENZANDO FASE DE EXPLOSIÓN&quot;);

            Console.WriteLine(&quot;Iniciando chispa en la bujía&quot;);
            Console.WriteLine(&quot;La explosión provoca el movimiento del pistón&quot;);

            anguloCiguenal = SumarAngulo(anguloCiguenal, 180);
            anguloArbolLevas = SumarAngulo(anguloArbolLevas, 90);

            Console.WriteLine(&quot;Angulo del ciguenal: &quot; + anguloCiguenal);
            Console.WriteLine(&quot;Angulo del arbol de levas: &quot; + anguloArbolLevas + &quot;\n&quot;);  
        }
    }
</pre>
<p><span style="text-decoration:underline;"><strong>MotorDiesel.cs:<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class MotorDiesel : Motor
    {
        protected override void BajarPiston()
        {
            Console.WriteLine(&quot;Inyectando aire en el motor&quot;);
        }

        protected override void ConsumirCombustible()
        {
            Console.WriteLine(&quot;COMENZANDO FASE DE COMBUSTIÓN&quot;);

            Console.WriteLine(&quot;Inyectando combustible pulverizado en el motor&quot;);
            Console.WriteLine(&quot;La presión provoca el movimiento del pistón&quot;);

            anguloCiguenal = SumarAngulo(anguloCiguenal, 180);
            anguloArbolLevas = SumarAngulo(anguloArbolLevas, 90);

            Console.WriteLine(&quot;Angulo del ciguenal: &quot; + anguloCiguenal);
            Console.WriteLine(&quot;Angulo del arbol de levas: &quot; + anguloArbolLevas + &quot;\n&quot;);            
        }
    }
</pre>
<p>Tal y como hemos dicho, las dos diferencias entre ambos radican en la compresión (inyección de mezcla en el motor gasolina por inyección de aire en el motor diesel) y en el consumo de combustible (explosión en el motor gasolina por combustión en el motor diesel). Salvando los detalles concretos que hemos codificado, <strong>el algoritmo del motor es exactamente el mismo</strong>, y viene determinado por el método público codificado en la clase base <strong>RealizarFaseMotor()</strong>. De hecho, si usamos el método para comprobar el funcionamiento de ambos motores, veremos el resultado:</p>
<pre class="brush: csharp; title: ; notranslate">
            Motor mGasolina = new MotorGasolina();
            Motor mDiesel = new MotorDiesel();

            mGasolina.RealizarFaseMotor();
            Console.WriteLine(&quot;----------------------------------------------------&quot;);
            mDiesel.RealizarFaseMotor();
</pre>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/050414_1810_patronesdec2.png" alt="" /></p>
<h2>Algoritmos con gancho</h2>
<p>Lo que hemos visto hasta ahora es sencillo de entender y de implementar, pero probablemente nos hayamos dado cuenta de un pequeño detalle: es demasiado rígido. La idea de mantener encapsulado e inmutable el cuerpo del algoritmo evita efectos indeseados, pero limita muchísimo la posibilidad de añadir pasos intermedios. Por ejemplo, ¿qué ocurriría si nuestro motor fuera turbo? El turbo realiza una compresión del aire antes de introducirlo en la cámara de explosión, proporcionando una mayor potencia sin modificar la cilindrada del motor. Sin embargo, este paso estaría (que me disculpen los profesionales del motor por lo que voy a decir) justo antes de la admisión. Sin embargo… habrá motores que implementen turbo y que no lo implementen. ¿Creamos por tanto una clase MotorTurboGasolina y MotorTurboDiesel? ¿Hacemos también abstracto el método <em>Admisión</em>para que este funcionamiento pueda personalizarse en las clases hijas? No es necesario. Para este tipo de situaciones, el patrón proporciona lo que se conocen como <em>Hooks</em>, <em>métodos de enganche </em>o <em>ganchos</em>.</p>
<p>La filosofía de estos métodos es sencilla: se implementan en la clase base con un <strong>comportamiento por defecto</strong>, que <strong>puede ser sobrecargado en las clases derivadas o ejecutado como está</strong>. De este modo, se proporcionan <strong>pasos opcionales</strong>, haciendo que las clases derivadas <em>enganchen</em> funcionalidad opcional en ciertos puntos del algoritmo. Estos <em>hooks</em> suelen utilizarse normalmente con cláusulas condicionales, de forma que se ejecuten en ciertas condiciones concretas.</p>
<p>En nuestro caso, añadiríamos un nuevo paso a nuestro algoritmo, al que llamaríamos <em>ComprimirTurbo()</em>, que implementaríamos en la clase con un comportamiento por defecto:</p>
<pre class="brush: csharp; title: ; notranslate">
        protected virtual void ComprimirTurbo()
        {
            Console.WriteLine(&quot;Turbo no presente&quot;);
        }
        // Método público que ejecutará el algoritmo completo
        public void RealizarFaseMotor()
        {
            ComprimirTurbo();       // Hook (método opcional)
            Admision();             // Parcialmente implementado en la clase base
            Compresion();           // Implementado en la clase base
            ConsumirCombustible();  // Delegado en las clases hijas
            Escape();               // Implementado en la clase base
        }
</pre>
<p>Al ser declarado como <em>virtual</em>, el método puede ser sobrecargado en las clases derivadas. Así, modificaremos nuestro motor diesel para que permita instanciar un motor turbo de la siguiente manera:</p>
<pre class="brush: csharp; title: ; notranslate">
    public class MotorDiesel : Motor
    {
        private bool turbo = false;

        public MotorDiesel(bool turbo)
        {
            this.turbo = turbo;
        }

        protected override void ComprimirTurbo()
        {
            // Si el coche es turbo, ejecutará su propio código. En caso contrario, efectuará
            // la operación por defecto
            if (turbo)
                Console.WriteLine(&quot;Comprimiendo aire en el turbo antes de la admisión&quot;);
            else
                base.ComprimirTurbo();
        }

        protected override void BajarPiston()
        {
            Console.WriteLine(&quot;Inyectando aire en el motor&quot;);
        }

        protected override void ConsumirCombustible()
        {
            Console.WriteLine(&quot;COMENZANDO FASE DE COMBUSTIÓN&quot;);

            Console.WriteLine(&quot;Inyectando combustible pulverizado en el motor&quot;);
            Console.WriteLine(&quot;La presión provoca el movimiento del pistón&quot;);

            anguloCiguenal = SumarAngulo(anguloCiguenal, 180);
            anguloArbolLevas = SumarAngulo(anguloArbolLevas, 90);

            Console.WriteLine(&quot;Angulo del ciguenal: &quot; + anguloCiguenal);
            Console.WriteLine(&quot;Angulo del arbol de levas: &quot; + anguloArbolLevas + &quot;\n&quot;);            
        }
    }
</pre>
<p>El motor gasolina no será modificado, de modo que ejecutará el método por defecto (no se «enganchará» al método <em>ComprimirTurbo</em>). Si ahora modificamos nuestro programa para instanciar un motor diesel turbo de la siguiente manera:</p>
<pre class="brush: csharp; title: ; notranslate">
            Motor mGasolina = new MotorGasolina();
            Motor mDiesel = new MotorDiesel(true);

            mGasolina.RealizarFaseMotor();
            Console.WriteLine(&quot;----------------------------------------------------&quot;);
            mDiesel.RealizarFaseMotor();
</pre>
<p>Veremos que el motor diesel hace uso del gancho para añadir su propia funcionalidad, mientras que el motor gasolina ha delegado en la clase base el funcionamiento por defecto:</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/050414_1810_patronesdec3.png" alt="" /></p>
<h2>¿Cuándo utilizar este patrón? Ejemplos reales</h2>
<p>Este patrón es aconsejable en los siguientes supuestos:</p>
<ul>
<li>Cuando se cuenta con un algoritmo aplicable a varias situaciones, cuya implementación difiere únicamente en algunos pasos.</li>
<li>Arquitecturas donde los pasos de un proceso estén definidos (el <strong>qué</strong>), pero sea necesario establecer los detalles sobre cómo realizarlos (el <strong>cómo</strong>).</li>
<li>Módulos en los que exista una gran cantidad de código duplicado que pueda ser factorizado en pasos comunes.</li>
</ul>
<p>Uno de los ejemplos más claros del uso de este patrón se da en los <em>Servlets</em> de Java. En ellos se produce una invocación secuencial de los métodos <em>init() </em>(al instanciar el Servlet) y <em>service()</em> (al realizar una petición) que, a partir del tipo de petición, ejecutarán el método correspondiente a su tipo, como <em>doGet(), doPost()… </em>Estos métodos son los que el programador deberá implementar para darles una funcionalidad concreta.</p>
<p>Otro ejemplo podría ser la ejecución de una transacción en base de datos: los pasos estarán bien definidos (apertura de la conexión, ejecución de la consulta, procesamiento de los datos, compromiso de la operación y cierre de la conexión), pero la implementación de éstos podría variar (por ejemplo, dependiendo de la base de datos a la cual se pretenda conectar).</p>
<h3>Fuentes:</h3>
<ul>
<li><a href="http://shop.oreilly.com/product/9780596007126.do">Head First Design Patterns</a> (Freeman et al.)</li>
<li><a href="http://www.dofactory.com/Patterns/PatternTemplate.aspx">Template Method</a> (doFactory.com)</li>
<li><a href="http://java.dzone.com/articles/design-patterns-template-method">Design Patterns Uncovered: The Template Method Pattern</a> (James Sugrue, dzone.com)</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://danielggarcia.wordpress.com/2014/05/05/patrones-de-comportamiento-iii-template-method/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1083</post-id>
		<media:content url="https://1.gravatar.com/avatar/77787450a00d8f7372bceaa70593a9c6156f81bb51204ddc5bb88b1ad375de8a?s=96&#38;d=https%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">danielggarcia</media:title>
		</media:content>

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/050414_1810_patronesdec1.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/050414_1810_patronesdec2.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/05/050414_1810_patronesdec3.png" medium="image" />
	</item>
		<item>
		<title>Patrones de Comportamiento (II): Patrón Command</title>
		<link>https://danielggarcia.wordpress.com/2014/04/28/patrones-de-comportamiento-ii-patron-command/</link>
					<comments>https://danielggarcia.wordpress.com/2014/04/28/patrones-de-comportamiento-ii-patron-command/#comments</comments>
		
		<dc:creator><![CDATA[Daniel García]]></dc:creator>
		<pubDate>Mon, 28 Apr 2014 15:27:08 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Nivel avanzado]]></category>
		<category><![CDATA[Patrones de Diseño]]></category>
		<category><![CDATA[Varios]]></category>
		<category><![CDATA[command pattern]]></category>
		<category><![CDATA[ejemplo]]></category>
		<category><![CDATA[patrón command]]></category>
		<category><![CDATA[patrones de comportamiento]]></category>
		<guid isPermaLink="false">http://danielggarcia.wordpress.com/?p=1077</guid>

					<description><![CDATA[Objetivo: «Encapsular una petición como un objeto, de modo que puedan parametrizarse otros objetos con distintas peticiones o colas de peticiones y proporcionar soporte para realizar operaciones que puedan deshacerse». Design Patterns: Elements of Reusable Object-Oriented Software Cuando decimos que un patrón es «estructural» es sencillo imaginar que su cometido será modelar las clases de [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong>Objetivo:<br />
</strong></p>
<blockquote><p><em>«Encapsular una petición como un objeto, de modo que puedan parametrizarse otros objetos con distintas peticiones o colas de peticiones y proporcionar soporte para realizar operaciones que puedan deshacerse».<br />
</em></p>
<p>Design Patterns: Elements of Reusable Object-Oriented Software</p></blockquote>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/042814_1526_patronesdec1.png" alt="" /></p>
<p>Cuando decimos que un patrón es «estructural» es sencillo imaginar que su cometido será modelar las clases de tal forma que cumplan un cometido concreto. Sin embargo, el concepto de diseñar clases orientando su funcionalidad hacia el comportamiento es algo más complicado. El patrón <em>command</em> u <em>orden</em> (como decía mi profesor de programación en primero de carrera, <em>command</em> se debería traducir por <em>órden</em>, no por <em>comando</em>, ya que un <em>comando</em> es un señor militar que pega tiros en la selva) tiene como objetivo encapsular la invocación de un método. Dicho así sin más, suena sencillo de entender pero… ¿cómo lo implementamos? La definición, a diferencia del patrón anterior, es un conglomerado de términos incomprensibles, ¿verdad? <em>Encapsular una petición como un objeto</em>. Vale, lo pillo. Pero ¿<em>parametrizarse</em>? ¿<em>Soporte para realizar peticiones que puedan deshacerse</em>?</p>
<p><span id="more-1077"></span></p>
<h2>Entendiendo el patrón Command</h2>
<p>A estas alturas ya deberíamos de estar saturados del concepto de <em>depender de abstracciones, no de concreciones</em>. Y por ello, seguramente nos sea mucho más sencillo entender este patrón si lo adaptamos a un lenguaje más técnico y algo menos abstracto (principal objetivo de esta serie de artículos). Si hacemos aterrizar este concepto al mundo real, podríamos traducirlo como lo siguiente:</p>
<p>«<em>Utilizar una interfaz con un método genérico de modo que los objetos que la implementen incluyan una referencia al objeto cuyo método queremos abstraer. Al invocar el método genérico se invocará este método, por lo que el objeto receptor no tiene por qué conocer el objeto original, bastándole una referencia a la interfaz para ejecutar el método</em>«.</p>
<p>¿Mejor así? Quizás sea todavía un poco complicado, ¿verdad? Intentemos desgranarlo un poco más.</p>
<p>Si tenemos una interfaz común <em>ICommand</em> con un método genérico <em>execute()</em>, cualquier objeto que la implemente podrá añadir dentro del código de <em>execute()</em> la llamada al método que queremos abstraer. De este modo, el objeto receptor queda completamente desacoplado del objeto invocado. Le bastará con invocar <em>ICommand.execute()</em> para que ocurra la magia. El cliente será el encargado de implementar las clases adecuadas para asegurar la funcionalidad que el objeto receptor espera. Nuestro objeto receptor puede ser una aplicación web esperando ejecutar una operación sobre una base de datos. Lo ideal sería que nuestra aplicación no tuviera que preocuparse ni qué objeto usar para realizar la operación ni el nombre de ésta. Si la interfaz <em>ICommand</em> proporciona un método genérico para realizar esta operación, nuestros programadores podrán implementar tantos conectores a distintas bases de datos como quieran. Nuestra aplicación simplemente dirá algo así como <em>«a mí no me cuentes tu vida. No me interesa saber qué hay más allá, yo ejecutaré el método ICommand.execute() y tú te encargas del resto del trabajo</em>«.</p>
<p>Por lo tanto, podemos afirmar que el <strong>patrón <em>Command</em> es la quintaesencia de una interfaz</strong>: ofrece la firma de un método genérico que las clases que la implementan se encargarán de completar. Resumiendo, <strong>el patrón <em>Command</em> hace que la implementación del método de una interfaz encapsule la invocación del método de otro objeto distinto.<br />
</strong></p>
<p>Si nos centramos en el diagrama de clases del diseño del patrón, podremos identificar los siguientes actores:</p>
<ul>
<li><strong>ICommand</strong>: interfaz que expone el método genérico (<em>execute()</em>).</li>
<li><strong>CommandGenerico</strong>: implementa <em>ICommand</em> y posee una referencia al objeto cuyo método <em>execute()</em> tendrá que encapsular. Este objeto recibe el nombre de <em>Receiver</em>.</li>
<li><strong>Receiver</strong>: como acabamos de decir, es el objeto que implementa la funcionalidad real. Alguno de sus métodos será encapsulado por <em>ICommand.execute()</em>.</li>
<li><strong>Invoker</strong>: clase encargada de invocar el método <em>ICommand.execute()</em>. Posee una referencia (o varias) a <em>ICommand</em>, y su método <em>SetCommand</em> le permite cambiar su funcionalidad en tiempo de ejecución. Ofrecerá también un método que invoque el método <em>ICommand.Execute() </em>que, a su vez, invocará <em>Receiver.MetodoAEncapsular()</em>.</li>
</ul>
<h2>Implementando el patrón Command</h2>
<p>Volvamos a nuestra fábrica de vehículos. Se nos ha encargado programar parte de la centralita de un nuevo modelo, concretamente de la activación y desactivación de las luces. Sabemos que contaremos con tres tipos de luces: posición, cortas y largas, pero la implementación de los métodos encargados de este proceso aún no están definidas, ya que se han subcontratado a una empresa coreana. Sin embargo, nuestro cliente nos exige que, pese a ello, debemos avanzar con el diseño de este módulo.</p>
<p>El patrón Command es perfecto en este escenario: contamos con un entorno en el que debemos ejecutar un método que aún no conocemos o que puede cambiar con el tiempo, por lo que crearemos una interfaz <em>ICommand</em> que exponga un método <em>Execute()</em>. Posteriormente, una vez que los requisitos estén claros y que sepamos <strong>qué</strong> hay que ejecutar, implementaremos clases que se acoplen entre nuestra centralita y el componente que la empresa coreana nos proporcionará.</p>
<p>Por lo tanto, comenzaremos creando una interfaz <em>ICommand</em> que se encargará de ofrecer una firma para el método que encapsulará el resto de los métodos: <em>Execute()</em>:</p>
<pre class="brush: csharp; title: ; notranslate">
    public interface ICommand
    {
        // El método Execute() será aquel que el objeto que reciba la referencia
        // será capaz de ejecutar.
        void Execute();
    }
</pre>
<p>A continuación modelaremos las clases que serán encapsuladas por el objeto <em>Command</em>. O más específicamente, las clases cuyos métodos serán encapsulados por el método <em>Execute()</em> del objecto <em>Command()</em>. Crearemos una clase abstracta de la que heredarán el resto de las clases que serán encapsuladas, aunque en realidad esto no es estrictamente necesario (un objeto <em>Command</em> podría albergar diversos objetos no necesariamente relacionados entre sí). <strong>Esta clase es conocida como <em>Receiver</em></strong>, y se caracteriza porque se encargará de <strong>albergar la lógica concreta del método</strong>. Si nos ceñimos a la descripción de una interfaz, la clase <em>Receiver</em> sería aquella clase que se encargaría de implementarla.</p>
<p><span style="text-decoration:underline;"><strong>LucesReceiver.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    // Clase abstracta de la que heredarán las clases que serán encapsuladas por los
    // objectos Command. Por lo tanto, sus métodos serán aquellos que encapsulará el
    // método Execute().
    public abstract class LucesReceiver
    {
        protected bool encendidas;
        protected int distanciaAlumbrado;

        // Propiedad de sólo lectura que devolverá el estado de las luces
        public bool Encendidas
        {
            get {return encendidas;}
        }

        // Método encargado de apagar las luces. Establece el estado del atributo 'encendidas'
        // a 'false'. Será común a todas las clases que hereden de ella.
        public void Apagar()
        {
            this.encendidas = false;
        }

        // El método Encender será distinto en cada una de las clases que hereden de esta clase.
        public abstract int Encender();
    }
</pre>
<p>A continuación implementaremos las clases concretas cuyos métodos serán encapsulados por <em>ICommand.Execute()</em>. Dado que heredan de la clase abstracta <em>LucesReceiver</em>, únicamente tendremos que implementar de forma explícita el método <em>Encender()</em>, ya que el resto de la funcionalidad será común. Comenzaremos por las luces de posición:</p>
<p><span style="text-decoration:underline;"><strong>LucesPosicion.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class LucesPosicion : LucesReceiver
    {
        private const int DISTANCIA = 1;

        public override int Encender()
        {
            this.encendidas = true;
            return DISTANCIA;
        }
    }
</pre>
<p>A continuación hacemos lo mismo con las luces cortas.</p>
<p><span style="text-decoration:underline;"><strong>LucesCortas.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class LucesCortas : LucesReceiver
    {
        private const int DISTANCIA = 40;

        public override int Encender()
        {
            this.encendidas = true;
            return DISTANCIA;
        }
    }
</pre>
<p>Finalmente, realizamos el mismo proceso con las luces largas.</p>
<p><span style="text-decoration:underline;"><strong>LucesLargas.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class LucesLargas : LucesReceiver
    {
        private const int DISTANCIA = 200;

        public override int Encender()
        {
            this.encendidas = true;
            return DISTANCIA;
        }
    }
</pre>
<p>Esto se resumiría ahora mismo en el siguiente esquema:</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/042814_1526_patronesdec2.png" alt="" /></p>
<p>Ya tenemos implementado uno de los elementos de nuestro patrón. Ahora haremos lo propio con la parte cliente, es decir, nuestra centralita. O más concretamente, el módulo encargado de encender y apagar las luces. Este se corresponderá con el elemento <em>Invoker</em>, que es aquel que tendrá como objetivo invocar la acción encapsulada por el objeto <em>Command</em>. Comenzaremos implementando una interfaz que ofrezca dos operaciones:</p>
<ul>
<li>Una operación <em>SetCommand(ICommand)</em> que permitirá a nuestro módulo cambiar el <em>ICommand</em> a ejecutar.</li>
<li>Una operación <em>Invoke()</em> que invoque el método <em>ICommand.Execute()</em> que esté asignado en el momento actual.</li>
</ul>
<p><span style="text-decoration:underline;"><strong>IInvoker.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public interface IInvoker
    {
        // Inyecta un ICommand, permitiendo cambiar la operación encapsulada en
        // tiempo de ejecución
        void SetCommand(ICommand command);

        // Ejecuta el método encapsulado
        void Invoke();
    } 
</pre>
<p>A continuación implementaremos la interfaz. Lo haremos a través de la clase <em>ControladorLucesInvoker</em>. Nuestra clase realizará justo aquello que acabamos de definir en la interfaz. Además, incluirá una referencia a un objeto que implemente la interfaz <em>ICommand</em></p>
<pre class="brush: csharp; title: ; notranslate">
    public class ControladorLucesInvoker : IInvoker
    {
        ICommand command;

        public void SetCommand(ICommand command)
        {
            this.command = command;
        }

        public void Invoke()
        {
            command.Execute();
        }
    }
</pre>
<p>Ya casi hemos completado nuestro patrón. Falta lo más importante: las clases que implementan la clase <em>ICommand</em> y que simbolizan <strong>las operaciones que se quieren encapsular</strong>. Estas operaciones serán, como podemos imaginar, <strong>encender y apagar</strong>. Por lo tanto, crearemos las clases <strong>EncenderLucesCommand<em><br />
</em></strong>y <strong>ApagarLucesCommand</strong>:</p>
<p><span style="text-decoration:underline;"><strong>EncenderLucesCommand.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class EncenderLucesCommand : ICommand
    {
        // Referencia al objeto cuyo método se quiere encapsular
        private LucesReceiver luces;

        // El constructor inyectará el objeto cuyo método se quiere encapsular
        public EncenderLucesCommand(LucesReceiver luces)
        {
            this.luces = luces;
        }

        // El método Execute() ejecutará el método encapsulado
        public void Execute()
        {
            int distancia = luces.Encender();
            Console.WriteLine(string.Format(&quot;Encendiendo luces. Alumbrando a una distancia de {0} metros.&quot;, distancia));
        }
    }
</pre>
<p>La clase <em>ApagarLucesCommand</em> realizará la operación contraria.</p>
<p><span style="text-decoration:underline;"><strong>ApagarLucesCommand.cs<br />
</strong></span></p>
<pre class="brush: csharp; title: ; notranslate">
    public class ApagarLucesCommand : ICommand
    {
        private LucesReceiver luces;

        public ApagarLucesCommand(LucesReceiver luces)
        {
            this.luces = luces;
        }

        public void Execute()
        {
            luces.Apagar();
            Console.WriteLine(&quot;Apagando las luces&quot;);
        }
    }
</pre>
<p>Esto completará nuestro diagrama de clases, dejándolo de la siguiente manera:</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/042814_1526_patronesdec3.png" alt="" /></p>
<p>Finalmente, añadimos el código que hará uso del patrón que acabamos de implementar. En él crearemos los tres tipos de luces (posición, cortas y largas) y utilizaremos el método <em>SetCommand()</em> de cada uno de los objetos destinados a encender y a apagar las luces para cambiar en tiempo de ejecución el tipo de luz a manejar.</p>
<pre class="brush: csharp; title: ; notranslate">
            // Instanciamos los objetos cuyos métodos serán encapsulados dentro de
            // objetos que implementan ICommand
            LucesReceiver lucesPosicion = new LucesPosicion();
            LucesReceiver lucesCortas = new LucesCortas();
            LucesReceiver lucesLargas = new LucesLargas();

            // Creamos los objetos Command que encapsulan los métodos de las clases anteriores
            ICommand encenderPosicion = new EncenderLucesCommand(lucesPosicion);
            ICommand apagarPosicion = new ApagarLucesCommand(lucesPosicion);

            ICommand encenderCortas = new EncenderLucesCommand(lucesCortas);
            ICommand apagarCortas = new ApagarLucesCommand(lucesCortas);

            ICommand encenderLargas = new EncenderLucesCommand(lucesLargas);
            ICommand apagarLargas = new ApagarLucesCommand(lucesLargas);

            // Creamos un nuevo Invoker (el objeto que será desacoplado de las luces)
            IInvoker invoker = new ControladorLucesInvoker();

            // Le asociamos los objetos Command y los ejecutamos
            // El objeto invoker invoca el método 'Execute()' sin saber en ningún momento
            // qué es lo que se está ejecutando realmente.
            invoker.SetCommand(encenderPosicion);      // Asociamos el ICommand
            invoker.Invoke();                          // Hacemos que se ejecute ICommand.Execute()

            // Realizamos lo mismo con el resto de instancias que implementan ICommand.
            // Como podemos ver, el ICommand puede asignarse en tiempo de ejecucion
            invoker.SetCommand(apagarPosicion);
            invoker.Invoke();

            // Luces cortas
            invoker.SetCommand(encenderCortas);
            invoker.Invoke();

            invoker.SetCommand(apagarCortas);
            invoker.Invoke();

            // Luces largas
            invoker.SetCommand(encenderLargas);
            invoker.Invoke();

            invoker.SetCommand(apagarLargas);
            invoker.Invoke();

</pre>
<p>El resultado de ejecutar este código será el siguiente:</p>
<p><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/042814_1526_patronesdec4.png" alt="" /></p>
<h2>¿Cuándo utilizar este patrón? Ejemplos reales</h2>
<p>Dado que este patrón nos permite encapsular la ejecución de un método como un objeto, una de las funcionalidades que nos ofrece este patrón es la de <strong>encadenar invocaciones</strong>. Si creamos una serie de objetos de este tipo y los almacenamos como objetos, éstos pueden pasarse como parámetros a un método que los vaya ejecutando de forma secuencial.</p>
<p>El segundo escenario en el que este patrón es útil es aquel que hemos visto en el ejemplo, es decir, aquel en el que <strong>el invocador del método deba ser desacoplado del objeto que maneja la invocación</strong>. Esto puede darse por necesidades del diseño o bien porque las especificaciones del módulo que maneja la invocación no estén definidas o existe previsión de que vaya a variar con el tiempo.</p>
<p>Recordemos además que la definición del patrón establecía que debía <em>proporcionar soporte para deshacer operaciones</em>. ¿Cómo realizar esto? Dado que estas operaciones se encapsulan como objetos, sería perfectamente posible mantener en memoria una pila con elementos ejecutados y otra que almacene objetos que modelen los distintos estados correspondientes a los instantes anteriores a ejecutar cada uno de los <em>Commands</em> de la primera pila. De este modo, realizar la opción <em>deshacer</em> sería tan sencillo como realizar un <em>pop </em>del primer objeto de cada pila y sobreescribir el estado actual del programa con el contenido del primer objeto almacenado en la pila de estados.</p>
<p>Otros ejemplos reales de este patrón serían, por ejemplo:</p>
<ul>
<li>Grabación de macros (secuencia de operaciones)</li>
<li>Asistentes de instalación (cada pantalla implementaría un <em>Command</em> que realizaría una operación <em>Execute() </em>al pulsar el botón «<em>Siguiente»</em>)</li>
<li>Elementos <a href="http://docs.oracle.com/javase/7/docs/api/javax/swing/Action.html"><em>Action</em></a> del framework <em>Swing</em> de Java.</li>
</ul>
<h3>Fuentes:</h3>
<ul>
<li><a href="http://shop.oreilly.com/product/9780596007126.do">Head First Design Patterns</a> (Freeman et al.)</li>
<li><a href="http://www.codeproject.com/Articles/339390/Understanding-and-Implementing-Command-Pattern-in">Understanding and Implementing Command Pattern in C#</a> (Rahul Rajat Singhj, CodeProject)</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://danielggarcia.wordpress.com/2014/04/28/patrones-de-comportamiento-ii-patron-command/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1077</post-id>
		<media:content url="https://1.gravatar.com/avatar/77787450a00d8f7372bceaa70593a9c6156f81bb51204ddc5bb88b1ad375de8a?s=96&#38;d=https%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">danielggarcia</media:title>
		</media:content>

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/042814_1526_patronesdec1.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/042814_1526_patronesdec2.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/042814_1526_patronesdec3.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/042814_1526_patronesdec4.png" medium="image" />
	</item>
		<item>
		<title>Patrones de Comportamiento (I): Patrón Iterator</title>
		<link>https://danielggarcia.wordpress.com/2014/04/14/patrones-de-comportamiento-i-patron-iterator/</link>
					<comments>https://danielggarcia.wordpress.com/2014/04/14/patrones-de-comportamiento-i-patron-iterator/#comments</comments>
		
		<dc:creator><![CDATA[Daniel García]]></dc:creator>
		<pubDate>Sun, 13 Apr 2014 23:57:03 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Nivel avanzado]]></category>
		<category><![CDATA[Patrones de Diseño]]></category>
		<category><![CDATA[Varios]]></category>
		<category><![CDATA[iterator]]></category>
		<category><![CDATA[iterator pattern]]></category>
		<category><![CDATA[patrón iterator]]></category>
		<category><![CDATA[patrones de comportamiento]]></category>
		<guid isPermaLink="false">http://danielggarcia.wordpress.com/?p=1064</guid>

					<description><![CDATA[Objetivo: «Proporcionar una forma de acceder a los elementos de un objeto agregado de forma secuencial sin exponer sus detalles». Design Patterns: Elements of Reusable Object-Oriented Software Pese a que no seamos conscientes de ello, cuando programamos utilizamos el patrón Iterator a diario. Casi todas las estructuras de datos que representan colecciones utilizan de algún [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong>Objetivo:<br />
</strong></p>
<blockquote><p><em>«Proporcionar una forma de acceder a los elementos de un objeto agregado de forma secuencial sin exponer sus detalles».<br />
</em></p>
<p>Design Patterns: Elements of Reusable Object-Oriented Software</p></blockquote>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/041314_2356_patronesdec1.png" alt="" /></p>
<p>Pese a que no seamos conscientes de ello, cuando programamos utilizamos el patrón <em>Iterator</em> a diario. Casi todas las estructuras de datos que representan colecciones utilizan de algún modo este patrón para proporcionar acceso secuencial a los elementos que las conforman, y tanto Java como .NET ofrecen interfaces que nos invitan a implementar este patrón codificando su comportamiento.</p>
<p>Ojo al detalle: hemos dicho recorrer <strong>secuencialmente</strong>, esto es, hacer uso de un proceso que sea capaz de <strong>situarse en el primer elemento</strong> de una colección y <strong>obtener la información de ese contenido</strong>. Tras esto, dado que hemos dicho que se trata de una operación secuencial, deberemos ser capaces de <strong>pasar del elemento actual al elemento al siguiente</strong>, obteniendo también su contenido. Por último, será necesario implementar algún mecanismo que nos informe si hemos alcanzado el <strong>final de la colección</strong> para detener el proceso de iteración.</p>
<p>Por lo tanto, el patrón <em>Iterator</em> debe proporcionar la siguiente funcionalidad:</p>
<ul>
<li>Obtener una referencia al <strong>elemento actual </strong>de la colección.</li>
<li>Obtener una referencia al <strong>siguiente elemento</strong> de la colección (el situado a continuación del elemento actual).</li>
<li>Obtener información sobre si existen más elementos después del actual.</li>
<li>Reiniciar la colección para que el iterador apunte nuevamente al <strong>primer elemento</strong> de la colección.</li>
</ul>
<p>Seguramente podremos pensar que no tiene mucho sentido implementar nuestro propio patrón <em>Iterator</em>, ya que prácticamente todas las colecciones implementan todas estas operaciones (e incluso alguna más). Sin embargo, existirán muchos supuestos en los que nos será útil.<em><br />
</em></p>
<p><span id="more-1064"></span></p>
<p>Comencemos por el principio. Imaginemos que disponemos de una fábrica de vehículos. Esta fábrica guarda un registro pormenorizado de los vehículos que fabrica, que están modelados a través de la siguiente clase:</p>
<pre class="brush: csharp; title: ; notranslate">
    public class Vehiculo
    {
        public string Marca { get; set; }
        public string Modelo { get; set; }
        public DateTime FechaFabricacion { get; set; }
        public double Precio { get; set; }

        public Vehiculo(string marca, string modelo, 
            DateTime fechaFabricacion, double precio)
        {
            this.Marca = marca;
            this.Modelo = modelo;
            this.FechaFabricacion = fechaFabricacion;
            this.Precio = precio;
        }

        public string CaracteristicasVehiculo()
        {
            return Marca + &quot; &quot; + Modelo + &quot; fabricado en &quot; +
                FechaFabricacion.ToShortDateString() + &quot; con un precio de &quot; +
                Precio + &quot; euros.\n&quot;;
        }
    }

</pre>
<p>Como nuestros ingenieros han sido previsores, han decidido que la estructura de datos en la cual se almacenarán los vehículos implemente una interfaz, a la que llamaremos <em>IRegistroVehiculos</em>. Esta interfaz definirá las operaciones básicas que se harán sobre el registro, que serán insertar un nuevo vehículo y mostrar información sobre éste (un ejemplo más completo también incluiría métodos para eliminar y modificar, pero nos centraremos de momento en esta funcionalidad básica para no desviarnos del ejemplo):</p>
<pre class="brush: csharp; title: ; notranslate">
    public interface IRegistroVehiculos
    {
        void InsertarVehiculo(string marca, string modelo, double precio);
        Vehiculo MostrarInformacionVehiculo(int indice);
    }
</pre>
<p>Nuestra fábrica de vehículos posee un sistema de gestión que almacena los vehículos en una estructura de datos agregada, como por ejemplo un ArrayList. Nuestra clase, como podremos imaginar, implementará la interfaz <em>IRegistroVehiculos</em>:</p>
<pre class="brush: csharp; title: ; notranslate">
    public class RegistroVehiculos : IRegistroVehiculos
    {
        private ArrayList listaVehiculos;

        public RegistroVehiculos()
        {
            this.listaVehiculos = new ArrayList();
        }

        public void InsertarVehiculo(string marca, string modelo, double precio)
        {
            Vehiculo v = new Vehiculo(marca, modelo, DateTime.Now, precio);
            listaVehiculos.Add(v);
        }

        public Vehiculo MostrarInformacionVehiculo(int indice)
        {
            return (Vehiculo)listaVehiculos[indice];
        }
    }
</pre>
<h2>Iterator entra en escena</h2>
<p>Hasta ahora hemos creado una clase que contendrá la información sobre los vehículos y otra que contendrá un listado de éstos y será capaz de añadir nuevos vehículos y recuperar un vehículo del cual le pasaremos un índice. Sin embargo, aún no hemos visto ni rastro del patrón <em>Iterator </em>por ningún sitio. Este patrón es, precisamente, la pieza que nos falta para que nuestro modelo esté completo. Si al método <em>MostrarInformacionVehiculo</em> le pasamos un índice mayor que el número de elementos que contenga el ArrayList, lo que obtendremos será una bonita excepción de <em>índice fuera de rango</em>. Una posible solución sería comprobar dentro del método que el número de elementos menos uno es siempre mayor o igual que el índice pasado como parámetro, pero esto no arreglaría el problema: necesitamos una estructura que sea capaz de iterar sobre la colección e informar al cliente si existen más elementos disponibles. Es hora de implementar un iterador.</p>
<p>Para esta implementación utilizaremos, nuevamente, una interfaz que definirá las operaciones que tendrá que realizar. Estas operaciones ya las hemos definido al principio del artículo: un método que «reinicie» el interador colocándolo en el primer elemento, otro que devuelva el elemento actual, otro que nos devuelva el siguiente elemento (incrementando el índice en una unidad) y otro que nos informe si quedan elementos disponibles en la colección:</p>
<pre class="brush: csharp; title: ; notranslate">
    public interface IIteratorVehiculo
    {
        void Primero();
        Vehiculo Actual();
        Vehiculo Siguiente();
        bool QuedanElementos();
    }
</pre>
<p>Comencemos a implementar nuestro iterador. Además de heredar de <em>IIteratorVehiculo</em>, deberá contener una referencia al listado completo de elementos del ArrayList. El método para realizar esta operación, como habremos podido imaginar, se realizará inyectándolo a través del constructor. Además, añadiremos una variable entera que se ocupe de almacenar el índice del elemento en el que se encuentra el iterador en este momento.</p>
<pre class="brush: csharp; title: ; notranslate">
    public class IteratorVehiculo : IIteratorVehiculo
    {
        // Referencia al listado completo
        private ArrayList vehiculos;

        // Almacenaremos el índice en el que se encuentra el iterador
        private int posicionActual = -1;

        // El constructor inyectará el ArrayList en el objeto
        public override IteratorVehiculo(ArrayList listado)
        {
            this.vehiculos = listado;
        }
    }
</pre>
<p>Hemos inicializado la variable <em>posicionActual</em> al valor <em>-1</em>, lo cual implica que nuestro iterador se encuentra en la <strong>posición inmediatamente anterior a la primera posición</strong>. El método <em>Primero()</em>, de hecho, debería realizar esta misma operación:</p>
<pre class="brush: csharp; title: ; notranslate">
        // Operación 1: Reinicio del índice, colocándolo en el elemento anterior al primero
        public void Primero()
        {
            this.posicionActual = -1;
        }
</pre>
<p>Espera, espera, ¿Por qué colocarlo <strong>antes</strong> del primer elemento en lugar de referenciar directamente el primer elemento? ¿No sería más intuitivo? Sí, pero sería erróneo. Si el método <em>Primero()</em> colocara el cursor en el primer elemento, ¿qué ocurriría si la lista estuviera vacía? Exacto: estaríamos referenciando un elemento que no existe, y lo que es peor: no tendríamos modo alguno de que nuestro iterador nos informara si existen elementos, ya que el método <em>QuedanElementos()</em>, encargado de esta operación, no podría actuar sobre el primer elemento de la colección. Colocando el índice en el elemento inmediatamente anterior solucionaríamos directamente estos dos problemas.</p>
<p>Lo siguiente que haremos será codificar el método <em>Actual()</em>, que nos devolverá una referencia al elemento cuyo índice se corresponda con el almacenado en <em>posicionActual()</em>, realizando, eso sí, las comprobaciones pertinentes.</p>
<pre class="brush: csharp; title: ; notranslate">
        // Operación 2: Acceso al elemento actual
        public Vehiculo Actual()
        {
            // Si no existen elementos, devolveremos null.
            // Si el indice actual es mayor que el mayor indice aceptable, devolveremos null.
            // Si el indice actual es -1, devolveremos null.
            if ((this.vehiculos == null) || 
                (this.vehiculos.Count == 0) || 
                (posicionActual &gt; this.vehiculos.Count - 1) ||
                (this.posicionActual &lt; 0))
                return null;

            // Devolvemos el elemento correspondiente al elemento actual
            else
                return (Vehiculo)this.vehiculos[posicionActual];
        }
</pre>
<p>Como el índice puede ser -1, será también necesario controlar esta posibilidad.</p>
<p>La siguiente operación nos ofrecerá una referencia al elemento siguiente, incrementando el índice en una unidad.</p>
<pre class="brush: csharp; title: ; notranslate">
        // Operación 3: Acceso al siguiente elemento
        public Vehiculo Siguiente()
        {
            // Si no existen elementos, devolveremos null.
            // Si el indice siguiente es mayor que el mayor indice aceptable, devolveremos null.
            if ((this.vehiculos == null) || 
                (this.vehiculos.Count == 0) || 
                (posicionActual + 1 &gt; this.vehiculos.Count - 1))
                return null;

            // Aumentamos el índice en una unidad y devolvemos ese elemento
            else
                return (Vehiculo)this.vehiculos[++posicionActual];
        }
</pre>
<p>Finalmente, el método <em>QuedanElementos()</em> comprobará si nos encontramos en el último elemento del listado o si, por el contrario, aún quedan elementos disponibles.</p>
<pre class="brush: csharp; title: ; notranslate">
        // Operación 4: Comprobación de si existen elementos en la colección
        public bool QuedanElementos()
        {
            // Devolvemos un booleano que será true si la posición siguiente es menor o igual que el
            // máximo índice aceptable (número de elementos del array - 1).
            return (posicionActual + 1 &lt;= this.vehiculos.Count - 1);
        }
</pre>
<p>Et voilà! Ya tenemos listo nuestro <em>Iterator</em>. Únicamente nos queda algo por hacer: proporcionar a nuestro listado <em>RegistroVehiculos</em> un método que nos genere un <em>Iterator</em> listo para ser utilizado con la colección contenida dentro de él. Es más, ya que tenemos disponibles sus respectivas abstracciones (las interfaces <em>IRegistroVehiculos</em> e <em>IIteratorVehiculo</em>), añadiremos un método a <em>IRegistroVehiculo</em> una función que nos devuelva una referencia a la interfaz <em>IIteratorVehiculo</em>, que será implementada por <em>RegistroVehiculos</em>. Por lo tanto, nuestra interfaz <em>IRegistroVehiculos</em> tendrá el siguiente aspecto definitivo:</p>
<pre class="brush: csharp; title: ; notranslate">
    public interface IRegistroVehiculos
    {
        void InsertarVehiculo(string marca, string modelo, double precio);
        Vehiculo MostrarInformacionVehiculo(int indice);
        IIteratorVehiculo ObtenerIterator();
    }
</pre>
<p>El método correspondiente dentro de <em>RegistroVehiculos</em> se limitará a instanciar un objeto de la clase <em>IteratorVehiculo</em> (que recordemos que implementaba <em>IIteratorVehiculo</em>) inyectándole el ArrayList, devolviendo el objeto como resultado de la función.</p>
<pre class="brush: csharp; title: ; notranslate">
        public IIteratorVehiculo ObtenerIterator()
        {
            return new IteratorVehiculo(listaVehiculos);
        }
</pre>
<p>Para probar el resultado de nuestro patrón, nos bastará el siguiente ejemplo:</p>
<pre class="brush: csharp; title: ; notranslate">
            // Declaramos el registro
            IRegistroVehiculos registro = new RegistroVehiculos();

            // Insertamos unos cuantos elementos
            registro.InsertarVehiculo(&quot;Volkswagen&quot;, &quot;Polo&quot;, 12300);
            registro.InsertarVehiculo(&quot;Volkswagen&quot;, &quot;Golf GTI&quot;, 18900);
            registro.InsertarVehiculo(&quot;Volkswagen&quot;, &quot;Passat&quot;, 27000);
            registro.InsertarVehiculo(&quot;Volkswagen&quot;, &quot;Scirocco&quot;, 32100);
            registro.InsertarVehiculo(&quot;Volkswagen&quot;, &quot;Touareg&quot;, 21800);

            // Obtenemos el iterator
            IIteratorVehiculo iterador = registro.ObtenerIterator();

            // Mientras queden elementos
            while (iterador.QuedanElementos())
            {
                // Obtenemos el siguiente elemento
                Vehiculo v = iterador.Siguiente();

                // Mostramos su contenido
                Console.WriteLine(v.Marca + &quot; &quot; + v.Modelo + &quot; fabricado el &quot; + v.FechaFabricacion.ToShortDateString() + &quot; (&quot; + v.Precio + &quot; euros)&quot;);
            }
</pre>
<p>Esto nos proporcionará la siguiente salida:</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/041314_2356_patronesdec2.png" alt="" /></p>
<h2>Aplicación del patron Iterator</h2>
<p>Este patrón, como podemos ver, no tiene demasiada complejidad: es más simple que la maquinaria de un chupete. Sin embargo, la pregunta que seguramente ronde la cabeza del lector sea similar a «pero si tenemos un ArrayList, ¿para qué recorrerlo secuencialmente? ¿Para qué usar esas comprobaciones cuando pueden codificarse en nuestro código de forma sencilla? ¿No es rizar el rizo? La verdad es que sí. Este patrón no está pensado para aplicarlo a una estructura de datos que ya posea mecanismos de acceso, como por ejemplo el ArrayList que hemos utilizado aquí: está pensado para ser utilizado en estructuras en los que <strong>el cliente no deba o no necesite conocer su estructura interna</strong>. Este ejemplo es estúpido porque hemos observado «las tripas» de la clase <em>RegistroVehiculos</em> y sabemos que dentro de ella vive un <em>ArrayList</em>. Pero si no lo supiéramos, el <em>Iterator</em> se encargaría de proporcionarnos acceso a sus miembros.</p>
<p>Vale, de acuerdo, en la ignorancia está la felicidad. Pero aún así, el programador original de la aplicación sabe que dentro de <em>RegistroVehiculos </em><strong>hay</strong> un ArrayList, independientemente de que el cliente necesite saberlo o no. ¿Por qué complicarse la vida de esta manera? Porque ¿qué ocurriría si dentro de nuestra estructura de datos <strong>no</strong> hubiese un ArrayList. O mejor aún: ¿qué ocurriría si nuestro cliente abriese una fábrica en otra ciudad y nuestra aplicación necesitara conectarse de forma remota a la información allí contenida? ¿Cambiaríamos todas nuestras clases e interfaces para proporcionar un conjunto de operaciones que nos permitiera conectarnos de forma remota al nuevo centro? Con este patrón no sería necesario. Bastaría con implementar otra vez la interfaz <em>IIteratorVehiculo</em> de forma que sus operaciones realizaran las peticiones necesarias al servicio remoto, haciéndolo transparente para el usuario. Por ejemplo, podríamos idear una implementación como la siguiente:</p>
<pre class="brush: csharp; title: ; notranslate">
    public class IteratorVehiculoRemoto : IIteratorVehiculo
    {

        private String urlServicio;

        // Almacenaremos el índice en el que se encuentra el iterador
        private int posicionActual = -1;

        // El constructor inyectará la dirección del servicio en el objeto
        public IteratorVehiculoRemoto(String urlServicio)
        {
            this.urlServicio = urlServicio;
        }

        #region IIteratorVehiculo Members

        public void Primero()
        {
            this.posicionActual = -1;
        }

        public Vehiculo Actual()
        {
            // Aquí realizaríamos las comprobaciones necesarias para determinar si la petición es válida
            // ...

            // Realizamos la petición HTTP
            WebRequest request = WebRequest.Create(urlServicio + &quot;?Index=&quot; + posicionActual);
            ((HttpWebRequest)request).UserAgent = &quot;Cliente IteratorVehiculoRemoto&quot;;
            request.Method = &quot;GET&quot;;

            // Obtenemos la respuesta
            WebResponse response = request.GetResponse();
            Stream data = response.GetResponseStream();
            response.Close();

            // Deserializamos el objeto
            byte[] buffer = new byte[data.Length];
            data.Read(buffer, 0, buffer.Length);
            MemoryStream ms = new MemoryStream(buffer);
            IFormatter formatter = new BinaryFormatter();
            ms.Seek(0, SeekOrigin.Begin);
            Vehiculo v = (Vehiculo)formatter.Deserialize(ms);

            return v;
        }

        public Vehiculo Siguiente()
        {
            // Aquí realizaríamos las comprobaciones necesarias para determinar si la petición es válida
            // ...

            // Realizamos la petición HTTP
            WebRequest request = WebRequest.Create(urlServicio + &quot;?Index=&quot; + (++posicionActual));
            ((HttpWebRequest)request).UserAgent = &quot;Cliente IteratorVehiculoRemoto&quot;;
            request.Method = &quot;GET&quot;;

            // Obtenemos la respuesta
            WebResponse response = request.GetResponse();
            Stream data = response.GetResponseStream();
            response.Close();

            // Deserializamos el objeto
            byte[] buffer = new byte[data.Length];
            data.Read(buffer, 0, buffer.Length);
            MemoryStream ms = new MemoryStream(buffer);
            IFormatter formatter = new BinaryFormatter();
            ms.Seek(0, SeekOrigin.Begin);
            Vehiculo v = (Vehiculo)formatter.Deserialize(ms);

            return v;
        }

        public bool QuedanElementos()
        {
            // Realizamos la petición HTTP
            WebRequest request = WebRequest.Create(urlServicio + &quot;?GetMaxElements&quot;);
            ((HttpWebRequest)request).UserAgent = &quot;Cliente IteratorVehiculoRemoto&quot;;
            request.Method = &quot;GET&quot;;

            // Obtenemos la respuesta
            WebResponse response = request.GetResponse();
            Stream data = response.GetResponseStream();
            response.Close();

            // Obtenemos el resultado de la petición
            StreamReader reader = new StreamReader(data);
            string strResultado = reader.ReadLine();
            if(!string.IsNullOrEmpty(strResultado))
                return Boolean.Parse(strResultado);

            return false;
        }

        #endregion
    }
</pre>
<p>Como podemos ver, ambos iteradores serán <em>IIteratorVehiculo</em>, y como tales, tendrán los mismos métodos. Por lo tanto, la clase cliente no necesitará saber si está obteniendo los datos desde un <em>ArrayList</em> de nuestra máquina o desde un servicio web alojado en otra Comunidad Autónoma. La transparencia es la clave de este patrón, y por lo tanto, será el objetivo que debemos buscar. Incluso podríamos crear un tercer <em>Iterator</em> que de algún modo fusionara ambos iteradores, haciendo que cuando se llegara al final del iterador del <em>ArrayList</em> se comenzaran a proporcionar elementos del servicio web, tratando ambas colecciones de cara al cliente como si fuera una sola.<br />
<span style="font-size:.8em;"><span style="text-decoration:underline;"><strong>Nota</strong></span>: el código que he mostrado para simbolizar la implementación de un iterador ejecutado sobre un servicio no es real. Se trata de una simulación en la que se pretende mostrar, de forma conceptual, cómo podría implementarse el patrón para acceder a elementos remotos. Ningún servicio web ha sido maltratado durante la redacción de este artículo.</span></p>
<h2>¿Cuándo utilizar este patrón? Ejemplos reales</h2>
<p>Ya hemos visto cuándo es aconsejable utilizar este patrón: cuando queramos proporcionar una forma de iterar sobre una colección sin que el cliente tenga que conocer los detalles de cómo está implementada. Por fortuna para nosotros, no tendremos que crear una interfaz <em>IIterator</em>, ya que tanto Java como .NET ofrecen una interfaz estándar de la cual es aconsejable que hereden los iteradores que decidamos implementar. Estas clases son <em>IEnumerator</em> en el caso de .NET e <em>Iterator</em> en el caso de Java.<br />
En el caso de .NET, la clase <em>IEnumerator </em>será la encargada de cumplir esta función. A diferencia del ejemplo anterior, no posee un método <em>QuedanElementos()</em>. Sin embargo, esta funcionalidad está cubierta por el método <em>MoveNext()</em>, que en lugar de devolver una referencia al elemento siguiente, comprueba si existen elementos y devuelve el resultado de la consulta. Además, en caso afirmativo, incrementará el índice en una unidad, permitiendo al método <em>Current()</em> acceder al siguiente elemento.</p>
<pre class="brush: csharp; title: ; notranslate">
    private class IteratorVehiculoEnumerable&lt;T&gt; : IEnumerator&lt;T&gt;
    {
        // Referencia al listado completo
        private ArrayList listaElementos;

        // Almacenaremos el índice en el que se encuentra el iterador
        private int posicionActual = -1;

        // El constructor inyectará el ArrayList en el objeto
        public IteratorVehiculoEnumerable(ArrayList listaElementos)
        {
            this.listaElementos = listaElementos;
        }

        public void Reset()
        {
            this.posicionActual = -1;
        }

        // Devuelve el elemento actual
        public T Current
        {
            get 
            {
                // Si no existen elementos, devolveremos null.
                // Si el indice actual es mayor que el mayor indice aceptable, devolveremos null.
                // Si el indice actual es -1, devolveremos null.
                if ((this.listaElementos == null) ||
                    (this.listaElementos.Count == 0) ||
                    (posicionActual &gt; this.listaElementos.Count - 1) ||
                    (this.posicionActual &lt; 0))
                    return default(T);

                // Devolvemos el elemento correspondiente al elemento actual
                else
                    return (T)this.listaElementos[posicionActual];
            }
        }

        object IEnumerator.Current
        {
            get { return Current; }
        }

        // La función ElementoSiguiente() de IEnumerable, a diferencia del ejemplo anterior, no devuelve una
        // referencia al siguiente elemento, sino que detecta si existe otro elemento (lo que en la implementación
        // anterior realizaba QuedanElementos()) y en caso afirmativo, incrementa el índice, apuntando al siguiente
        // elemento, que será recuperado mediante Current.
        public bool MoveNext()
        {
            bool quedanElementos = (posicionActual + 1 &lt;= this.listaElementos.Count - 1);
            if (quedanElementos)
                posicionActual++;

            return quedanElementos;
        }

        public void Dispose()
        {
            // Este método se implementará en caso de utilizar recursos no gestionados.
            // En ese caso, aquí se liberarán esos recursos antes de destruir el objeto.
            return;
        }
    }
</pre>
<p>Además de disponer de la interfaz IEnumerator, también disponemos de la interfaz IEnumerable, que serviría para implementar el registro de vehículos. Esta interfaz proporciona la función GetEnumerable(), que será la encargada de construir el IEnumerator correspondiente.<br />
Por su parte, tal y como hemos dicho, Java proporciona su interfaz Iterator, que tiene el siguiente aspecto:</p>
<pre class="brush: java; title: ; notranslate">
	public class IteratorVehiculo implements Iterator&lt;Vehiculo&gt; {

	@Override
	public boolean hasNext() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Object next() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void remove() {
		// TODO Auto-generated method stub
		
	}

</pre>
<h3>Fuentes:</h3>
<ul>
<li><a href="http://shop.oreilly.com/product/9780596007126.do" target="_blank">Head First Design Patterns</a> (Freeman et al.)</li>
<li><a href="http://www.codeproject.com/Articles/474678/A-Beginners-Tutorial-on-Implementing-IEnumerable-I" target="_blank">A Beginner&#8217;s Tutorial on Implementing IEnumerable Interface and Understanding yield Keyword </a> (Rahul Rajat Singh, Codeproject)</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://danielggarcia.wordpress.com/2014/04/14/patrones-de-comportamiento-i-patron-iterator/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1064</post-id>
		<media:content url="https://1.gravatar.com/avatar/77787450a00d8f7372bceaa70593a9c6156f81bb51204ddc5bb88b1ad375de8a?s=96&#38;d=https%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">danielggarcia</media:title>
		</media:content>

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/041314_2356_patronesdec1.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/041314_2356_patronesdec2.png" medium="image" />
	</item>
		<item>
		<title>Patrones Estructurales (VII): Patrón Proxy</title>
		<link>https://danielggarcia.wordpress.com/2014/04/07/patrones-estructurales-vii-patron-proxy/</link>
					<comments>https://danielggarcia.wordpress.com/2014/04/07/patrones-estructurales-vii-patron-proxy/#comments</comments>
		
		<dc:creator><![CDATA[Daniel García]]></dc:creator>
		<pubDate>Mon, 07 Apr 2014 05:12:06 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Nivel avanzado]]></category>
		<category><![CDATA[Patrones de Diseño]]></category>
		<category><![CDATA[Varios]]></category>
		<category><![CDATA[ejemplo]]></category>
		<category><![CDATA[patrón proxy]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[proxy patter]]></category>
		<guid isPermaLink="false">http://danielggarcia.wordpress.com/?p=1059</guid>

					<description><![CDATA[Objetivo: «Proporcionar un sustituto o intermediario para otro objeto de modo que pueda controlarse el acceso que se tiene hacia él». Design Patterns: Elements of Reusable Object-Oriented Software Supongo que todos conocemos el concepto de proxy, al menos en su acepción aplicada a la navegación web. Se trata de una máquina que actúa de intermediaria [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong>Objetivo:<br />
</strong></p>
<blockquote><p><em>«Proporcionar un sustituto o intermediario para otro objeto de modo que pueda controlarse el acceso que se tiene hacia él».<br />
</em></p>
<p>Design Patterns: Elements of Reusable Object-Oriented Software</p></blockquote>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/040614_2034_patronesest1.png" alt="" /></p>
<p>Supongo que todos conocemos el concepto de <em>proxy</em>, al menos en su acepción aplicada a la navegación web. Se trata de una máquina que actúa de intermediaria a la hora de servir páginas web (u otros servicios). En la configuración de área local podemos indicar la IP de esta máquina y será esta máquina la que se conecte a la URL por nosotros y la envíe a nuestro equipo.<em><br />
</em></p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/040614_2034_patronesest2.png" alt="" /></p>
<p>De este modo, un equipo no se conectará directamente a la URL, sino que lo hará a través de este intermediario. ¿Por qué hacer esto? Por múltiples motivos: podemos, por ejemplo, restringir las URLs que nuestros clientes (ordenadores de la red local) pueden visitar. O cachear las páginas que se visitan con más frecuencia, haciendo innecesario el acceso a la web «real» en los casos en los que el acceso se repita, proporcionando un ahorro en ancho de banda. En resumen, un <em>proxy</em> será una entidad en la que delegaremos la ejecución de ciertas tareas y que decidirá, en última instancia, qué acciones realizar antes y después de éstas. Los <em>proxies</em>, por tanto, podrían dedicarse perfectamente a la política <img src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><span id="more-1059"></span></p>
<h2>Tipos de proxy</h2>
<p>Dependiendo de las responsabilidades y del comportamiento del proxy, tendremos varios tipos que realizarán unos tipos de tarea u otras. Los proxies más comunes son los siguientes:</p>
<ul>
<li><strong>Proxy remoto</strong>: un proxy remoto se comporta como un representante local de un objeto remoto. Se encarga principalmente de abstraer la comunicación entre nuestro cliente y el objeto remoto. Es el embajador de los proxies.</li>
<li><strong>Proxy virtual</strong>: se encarga de instanciar objetos cuyo coste computacional es elevado. Es capaz de sustituir al objeto real durante el tiempo que el verdadero objeto está siendo construido y proporcionar funcionalidades como el <em>lazy loading </em>(realizar operaciones computacionalmente costosas únicamente cuando el acceso a el elemento es requerido).</li>
<li><strong>Proxy de protección</strong>: establece controles de acceso a un objeto dependiendo de permisos o reglas de autorización.</li>
</ul>
<h2>Estructura del patrón</h2>
<p>Si echamos un vistazo al diagrama, vemos que la estructura de este patrón es bastante sencilla:</p>
<ul>
<li>Tenemos una clase abstracta (o interfaz) <em>Elemento</em> que define las operaciones que deberá cumplimentar tanto nuestro objeto real (<em>ElementoReal</em>) como el proxy que actuará de intermediario (<em>ElementoProxy</em>). Ambos elementos, al heredar de <em>Elemento</em>, deberán ser, por tanto, intercambiables. De este modo, sustituir un objeto de la clase <em>ElementoReal</em> por un <em>ElementoProxy</em> debería de ser -idealmente- transparente.</li>
<li>La clase <em>ElementoReal</em> es aquella que contiene la verdadera funcionalidad, es decir, la clase que se quiere «proteger» a través del proxy. En el ejemplo de los navegadores, se correspondería al ordenador que realiza la petición HTTP. Este elemento tendrá un conjunto de operaciones, heredadadas desde <em>Elemento</em>. Usando el símil de los ordenadores, una operación podría ser <em>HttpGet</em> o <em>HttpPost</em>.</li>
<li>La clase <em>ElementoProxy</em> también hereda de <em>Elemento</em>, y como tal, posee todos sus métodos. La diferencia fundamental es que también incorpora una referencia a otro <em>Elemento</em>. Así, tal y como ocurría en otros patrones como <em>Adapter </em>o <em>Decorator</em>, el método codificado dentro de esta clase realizará ciertas operaciones de control y/o transformación para posteriormente invocar el método original del <em>ElementoReal</em> que tiene referenciado. Por ejemplo, si nuestro proxy no quisiera permitir las conexiones a una página en concreto, su comportamiento sería algo similar al siguiente:</li>
</ul>
<pre class="brush: csharp; title: ; notranslate">

    private class ElementoProxy : Elemento
    {
        // Incluímos una referencia a otro elemento.
        private Elemento elemento;

        // Inyectamos el elemento a través del constructor.
        public ElementoProxy(Elemento elemento)
        {
            this.elemento = elemento;
        }

        // El método HttpGet realizará comprobaciones y/o adaptaciones para
        // posteriormente realizar la llamada al método homónimo del objeto real
        public string HttpGet(string uri)
        {
            if (uri.ToLower().Contains(&quot;paginaprohibida.com&quot;))
                return null;
            else
                return HttpGet(uri);
        }
    };

 </pre>
<p>A estas alturas, si habéis echado un ojo a los patrones anteriores, este concepto os resultará pan comido. El patrón <em>Proxy</em> realiza una tarea similar a la que realizaba el patrón <em>Adapter</em>, salvo que en lugar de transformar la interfaz del objeto (ambos objetos heredan de la misma clase y, por tanto, comparten interfaz), éste utilizará la misma, pero realizando una serie de operaciones adicionales antes (o después) de realizar la llamada al método de la clase original.</p>
<p>Es más, el concepto de añadir funcionalidad a una clase que puede hacerse pasar por otra añadiendo nueva funcionalidad inyectando el objeto original a través del constructor es un concepto que también hemos visto antes en el patrón <em>Decorator</em>. El patrón <em>Proxy</em> es muy similar a éste último, con la diferencia (nuevamente) de su objetivo: mientras que el patrón <em>Decorator</em> añade nuevas responsabilidades a un objeto de forma dinámica, el patrón <em>Proxy</em> únicamente realiza operaciones de control de acceso sobre ese objeto. De hecho, el <em>Proxy</em> tiene una capacidad que no tiene el <em>Decorator</em>: tiene la capacidad de instanciar objetos de la clase que encapsula. En el ejemplo aquí mostrado el objeto es inyectado, pero en determinados casos, este podría ser perfectamente instanciado. Esto suele ser común en el llamado <em>Virtual Proxy</em>, en el que el <em>Proxy</em> puede proporcionar un comportamiento «por defecto» mientras realiza la operación que requiera cierto coste computacional.</p>
<p>Por lo tanto, nos encontramos una colección de cosas que ya nos son familiares: una clase abstracta de la que heredan ambos elementos, inyectar un objeto en otro a través de su constructor, realizar una composición de objetos al añadir una referencia del objeto original dentro del objeto de la clase proxy… Como vemos, los mismos conceptos se repiten una y otra vez. Una vez comprendidos, la comprensión de los patrones se simplifica muchísimo.</p>
<p>Otra posible versión de este patrón resultaría en realizar la herencia de forma lineal, es decir, haciendo que el proxy herede del elemento real y sobrecargando los métodos que requieran supervisión.</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/040614_2034_patronesest3.png" alt="" /></p>
<p style="text-align:center;">
<p>Con este modelo evitaremos que nuestro proxy tenga que incluir una referencia al objeto real, ya que podemos realizar la misma operación sobrecargando el método y llamando al método de la clase base en lugar de invocar el método del objeto inyectado a través del constructor. Usando esta estructura podríamos incluso evitar que <em>ElementoReal</em> herede de una clase abstracta o implemente una interfaz, simplificando el código… pero forzando a nuestro diseño que dependa de una concreción en lugar de depender de una abstracción. En la medida de la posible, intentaremos respetar este principio.</p>
<h2>Arrancando el vehículo</h2>
<p>Atrás quedaron los días en que el sistema de arranque de nuestro vehículo consistía en una llave dentada que encajaba con los pernos de la cerradura. La electrónica y la informática hace tiempo que ha llegado a la automoción, y por ello la nueva serie de vehículos Dorfwagen incorpora una centralita con un complejo sistema de seguridad que es capaz de comprobar si el código de la llave coincide con el de la centralita. En los modelos de gama alta, además de realizar esta operación estándar, la centralita proporciona un sistema de seguridad capaz de detectar si la llave ha sido falsificada.</p>
<p>Nuestra centralita, por tanto, proporciona dos atributos: uno que se corresponderá con el código de la llave y otro que identificará al código de seguridad.</p>
<pre class="brush: csharp; title: ; notranslate">


    public class CentralitaVehiculo
    {
        private int codigoLlave;
        private int codigoSeguridad;

        public CentralitaVehiculo(int codigoLlave, int codigoSeguridad)
        {
            this.codigoLlave = codigoLlave;
            this.codigoSeguridad = codigoSeguridad;
        }

        public int CodigoLlave {
            get { return codigoLlave; }
        }
        public int CodigoSeguridad {
            get { return codigoSeguridad; }
        }
    }
</pre>
<p>Dado que disponemos de dos gamas (alta y baja), necesitaremos implementar, partiendo de la misma centralita, un sistema que sea compatible con ambos pero que sea capaz de realizar una comprobación adicional si la llave del vehículo es de gama alta. Comenzaremos codificando la clase abstracta <em>Llave</em> de la cual heredará tanto la funcionalidad base de nuestra llave <em>LlaveReal</em> como la clase que hará de veces de <em>proxy</em>, <em>LlaveProxy</em>.</p>
<pre class="brush: csharp; title: ; notranslate">


    // Clase abstracta de la que heredará el elemento original y el proxy
    public abstract class Llave
    {
        // Código de la llave
        protected int codigoLlave;

        // Propiedad de sólo lectura para obtener el código de la llave
        public int CodigoLlave
        {
            get { return codigoLlave; }
        }

        // Métodos abstractos que implementarán el elemento real y el proxy
        public abstract void RealizarContacto(CentralitaVehiculo centralita);
        public abstract bool LlaveCorrecta(int codigoLlave);
    }
</pre>
<p>Esta llave contiene un atributo que almacenará el código de la llave, más dos métodos que deberán ser implementados por las clases hija: <em>RealizarContacto</em>, que arrancará el vehículo, y <em>LlaveCorrecta</em>, que será invocada por el método anterior y comprobará si el código de la centralita y de la llave coinciden.</p>
<p>Nuestra clase <em>LlaveReal, </em>por tanto, mostrará el comportamiento básico que se espera de ella: comprobará que llave y centralita comparten código y realizará el arranque del vehículo en caso de que así sea.</p>
<pre class="brush: csharp; title: ; notranslate">


    public class LlaveReal : Llave
    {
        // Constructor base: asigna el código de la llave a la llave
        public LlaveReal(int codigoLlave)
        {
            this.codigoLlave = codigoLlave;
        }

        // Realizar contacto: comprueba que el código de la llave sea correcto.
        // En caso de que lo sea, arranca el vehículo.
        public override void RealizarContacto(CentralitaVehiculo centralita)
        {
            if (LlaveCorrecta(centralita.CodigoLlave))
                Console.WriteLine(&quot;Contacto realizado&quot;);
            else
                Console.WriteLine(&quot;Código de llave inválido&quot;);
        }

        // Comprueba que el código proporcionado coincide con el de la llave
        public override bool LlaveCorrecta(int codigoLlave)
        {
            return codigoLlave == this.codigoLlave;
        }
    }
</pre>
<p>Hasta aquí, nada que se separe de un diseño convencional. Es hora de implementar nuestro <em>proxy</em>, que también hereda de <em>Llave</em>. La diferencia fundamental con la clase anterior radica en que:</p>
<ul>
<li>Su constructor acepta un objeto de la clase <em>Llave</em>, que será inyectado para ser invocado en los métodos <em>LlaveCorrecta</em> y <em>RealizarContacto</em>.</li>
<li>Debido a lo anterior, nuestra clase deberá incluir una referencia a <em>Llave</em>.</li>
<li>El método <em>LlaveCorrecta</em> se limitará a invocar el método <em>LlaveCorrecta</em> de la llave que se ha inyectado a través del constructor.</li>
<li>Finalmente, el método <em>RealizarContacto</em> será el encargado de realizar la comprobación adicional: antes de comparar los códigos de la llave y de la centralita invocando a <em>LlaveCorrecta</em> realizará una comprobación previa, utilizando algún tipo de algoritmo para asegurarse de que el código de seguridad de la centralita permite el código de la llave insertada. En caso de que sea correcto, el control de acceso habrá sido superado y se ejecutará el código correspondiente a <em>LlaveReal</em>. En caso contrario, se denegará el arranque:</li>
</ul>
<pre class="brush: csharp; title: ; notranslate">

    public class LlaveProxy : Llave
    {
        // Referencia a la llave original
        private Llave llaveOriginal;

        // Constructor en el que se inyectará el objeto real
        public LlaveProxy(Llave llave)
        {
            llaveOriginal = llave;
        }

        // Este método realizará el control de acceso sobre el método original.
        // Realizará una comprobación previa comparando el código de seguridad y, si este es
        // correcto, invocará el método del objeto real.
        public override void RealizarContacto(CentralitaVehiculo centralita)
        {
            // Realizamos una comprobación adicional de seguridad. En caso de no cumplirse, se
            // aborta la operación. Esta operación podría ser la ejecución de un algoritmo para
            // comprobar la autenticidad del código de la llave, una comprobación de nombre de
            // usuario y contraseña... o cualquier otra comprobación que queramos realizar.
            if (centralita.CodigoSeguridad &gt; llaveOriginal.CodigoLlave.ToString().GetHashCode())
            {
                Console.WriteLine(&quot;Código de seguridad incorrecto. Abortanto arranque&quot;);
                return;
            }

            if (LlaveCorrecta(centralita.CodigoLlave))
                Console.WriteLine(&quot;Contacto realizado&quot;);
            else
                Console.WriteLine(&quot;Código de llave inválido&quot;);
        }

        // Este método no realizará comprobaciones adicionales. Se limitará a invocar el método
        // del objeto real.
        public override bool LlaveCorrecta(int codigoLlave)
        {
            return llaveOriginal.LlaveCorrecta(codigoLlave);
        }
    }
</pre>
<p>La llave simple realizará un arranque normal y correcto siempre que el código de centralita y de la llave coincidan. No obstante, en los vehículos de gama alta, si utilizamos un código de seguridad erróneo, el motor no arrancará:</p>
<pre class="brush: csharp; title: ; notranslate">

            int codigoLlave = 532543463;
            int codigoSeguridad = 1038948470;

            CentralitaVehiculo centralita = new CentralitaVehiculo(codigoLlave, codigoSeguridad);

            Llave llaveSimple = new LlaveReal(codigoLlave);
            llaveSimple.RealizarContacto(centralita);

            Llave proxy = new LlaveProxy(llaveSimple);
            proxy.RealizarContacto(centralita);
</pre>
<p><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/040614_2034_patronesest4.png" alt="" /></p>
<p>Por el contrario, si el código es válido, se procederá al arranque de forma normal.</p>
<pre class="brush: csharp; title: ; notranslate">

            int codigoLlave = 532543463;
            int codigoSeguridad = -1098948470;

            CentralitaVehiculo centralita = new CentralitaVehiculo(codigoLlave, codigoSeguridad);

            Llave llaveSimple = new LlaveReal(codigoLlave);
            llaveSimple.RealizarContacto(centralita);

            Llave proxy = new LlaveProxy(llaveSimple);
            proxy.RealizarContacto(centralita);


</pre>
<p><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/040614_2034_patronesest5.png" alt="" /></p>
<p>Como podemos observar, ambos objetos pueden ser intercambiados, ya que al utilizarse una clase común (<em>Llave</em>), lo único que deberá hacer el cliente es invocar el método necesario para realizar el arranque (<em>RealizarContacto</em>). El código implementado por cada clase queda fuera del alcance del cliente, que lo único que espera es que el vehículo arranque o muestre un mensaje de error.</p>
<p>&nbsp;</p>
<h2>¿Cuándo utilizar este patrón? Ejemplos reales</h2>
<p>Este patrón es aconsejable en los siguientes supuestos:</p>
<ul>
<li>Retrasar una invocación a una petición con alto coste computacional hasta que sea necesario (<em>lazy loading</em>). Un ejemplo de este comportamiento sería, por ejemplo, cumplimentar un diccionario interno que requiera realizar varias conexiones a base de datos únicamente cuando se solicite información de uno de los elementos contenidos en el diccionario.</li>
<li>Simplificar la interacción con elementos remotos: si el objeto es local, las invocaciones serán las habituales. Si el objeto es remoto, el proxy implementará los mecanismos de comunicación haciéndolos transparentes al cliente.</li>
</ul>
<p>Ejemplos de este patrón pueden ser la <a href="http://es.wikipedia.org/wiki/Java_Remote_Method_Invocation">tecnología <em>RMI</em> de <em>Java</em></a>, en el que la invocación de un objeto remoto se realiza a través de un <em>Stub</em>. Este <em>Stub</em> no es más que una clase que expone las mismas operaciones que el objeto remoto, pero que hace que la petición sea transparente para el cliente, realizando de forma interna las operaciones de comunicación.</p>
<p>Otro ejemplo serían las pantallas de carga de ciertas aplicaciones. En este caso, se tratará de un <em>Proxy Virtual</em>, que mostrará el típico mensaje de «Cargando» mientras recupera la información solicitada por el usuario, sobreescribiendo el mensaje una vez que la petición al objeto real ha concluido.</p>
<p>&nbsp;</p>
<h3>Fuentes:</h3>
<ul>
<li><a href="http://shop.oreilly.com/product/9780596007126.do">Head First Design Patterns</a> (Freeman et al.)</li>
<li><a href="http://pluralsight.com/training/Courses/TableOfContents/patterns-library">Pluralsight – Design Patterns Library: Proxy Pattern</a> (Steve Smith)</li>
<li><a href="http://www.oodesign.com/proxy-pattern.html">OODesign: Proxy Pattern</a> (OODesign.com)</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://danielggarcia.wordpress.com/2014/04/07/patrones-estructurales-vii-patron-proxy/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1059</post-id>
		<media:content url="https://1.gravatar.com/avatar/77787450a00d8f7372bceaa70593a9c6156f81bb51204ddc5bb88b1ad375de8a?s=96&#38;d=https%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">danielggarcia</media:title>
		</media:content>

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/040614_2034_patronesest1.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/040614_2034_patronesest2.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/040614_2034_patronesest3.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/040614_2034_patronesest4.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/04/040614_2034_patronesest5.png" medium="image" />
	</item>
		<item>
		<title>Patrones Estructurales (VI): Patrón Composite</title>
		<link>https://danielggarcia.wordpress.com/2014/03/31/patrones-estructurales-vi-patron-composite/</link>
					<comments>https://danielggarcia.wordpress.com/2014/03/31/patrones-estructurales-vi-patron-composite/#comments</comments>
		
		<dc:creator><![CDATA[Daniel García]]></dc:creator>
		<pubDate>Mon, 31 Mar 2014 05:12:43 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Nivel avanzado]]></category>
		<category><![CDATA[Patrones de Diseño]]></category>
		<category><![CDATA[Varios]]></category>
		<category><![CDATA[composite]]></category>
		<category><![CDATA[composite pattern]]></category>
		<category><![CDATA[ejemplo]]></category>
		<category><![CDATA[patrón composite]]></category>
		<category><![CDATA[patrones estructurales]]></category>
		<guid isPermaLink="false">http://danielggarcia.wordpress.com/?p=1047</guid>

					<description><![CDATA[Objetivo: «Componer objetos en árboles para representar jerarquías todo-parte. Composite permite a los clientes tratar objetos individuales y objetos compuestos de una manera uniforme». Design Patterns: Elements of Reusable Object-Oriented Software El patrón Composite se aleja un poco de la línea tradicional de los patrones vistos hasta ahora, ya que rompe uno de los principios [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong>Objetivo:<br />
</strong></p>
<blockquote><p><em>«Componer objetos en árboles para representar jerarquías todo-parte. Composite permite a los clientes tratar objetos individuales y objetos compuestos de una manera uniforme».<br />
</em></p>
<p>Design Patterns: Elements of Reusable Object-Oriented Software</p></blockquote>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/03/033014_1801_patronesest1.png" alt="" /></p>
<p>El patrón <em>Composite</em> se aleja un poco de la línea tradicional de los patrones vistos hasta ahora, ya que rompe uno de los principios de la programación orientada a objetos: <strong>una clase, una responsabilidad</strong>. En realidad, los más puristas pueden decidir no hacerlo, pero el precio a pagar es demasiado alto para los ingenieros mortales: la simplicidad del modelo.</p>
<p>Cuando diseñamos debemos tener claro que la idea principal es alcanzar un equilibrio entre muchos factores como por ejemplo presupuesto, usabilidad y facilidad para que nuestro código sea reutilizable y pueda ser fácilmente mantenible en un futuro. Si el objetivo del anterior patrón, <em>Flyweight</em>, era el rendimiento, el <em>sine qua non</em> de este patrón es la <strong>facilidad de uso</strong>.</p>
<p><span id="more-1047"></span></p>
<p>A grandes rasgos, el patrón <em>Composite</em> permite crear una jerarquía de elementos anidados unos dentro de otros. Cada elemento permitirá alojar una colección de elementos del mismo tipo, hasta llegar a los elementos «reales» que se corresponderán con los nodos «Hoja» del árbol. Un ejemplo del concepto de la jerarquía que se pretende modelar sería el de los menús de una aplicación:</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/03/033014_1801_patronesest2.png" alt="" /></p>
<p>En este ejemplo tenemos un menú (Archivo) que contiene varios elementos, que pueden ser «hojas» que ejecutan una operación (Abrir, CreatePDF en línea.., Compartir archivos usando SendNow Online…, Adjuntar a correo electrónico…) o bien otro menú (Guardar como) que a su vez contiene más elementos «hoja» (PDF…, Texto…, Word o Excel Online…).</p>
<p>Creo que el ejemplo es lo suficientemente ilustrativo como para entender el concepto: poder anidar menús que puedan contener o bien otros menús, o bien directamente nodos hoja que ejecuten operaciones. Este ejemplo se aproxima bastante al concepto de <em>Composite</em>, pero no se ajusta exactamente a su filosofía, ya que le falta una funcionalidad: el submenú debería ser capaz de ejecutar una operación que se encargaría de iterar sobre todos los subelementos que contiene, ejecutando la operación de cada uno de ellos. Sin embargo, deja bastante claro el esquema lógico que seguirá este patrón.</p>
<h2>Llevando el coche al taller</h2>
<p>Para ilustrar el patrón, acudiremos a un taller, que tuvo a bien contratar a un ingeniero de software para que le diseñara una aplicación para realizar el inventariado de las piezas de recambio. El dueño del taller le expuso al ingeniero la dificultad que tenía para establecer los precios de los recambios, ya que dependiendo de la avería, a veces era necesario cambiar piezas enteras mientras que en otras ocasiones bastaba con sustituir un pequeño componente. Nuestro cliente había almacenado en una base de datos cada uno de los componentes con su respectivo precio, pero cuando el proveedor le aumentaba el precio de una pieza que formaba parte de otra, tenía que preocuparse de actualizar, una a una, todas las piezas de grano más grueso en las cuales estaba contenida esta pieza. Por poner un ejemplo, si el precio de un tornillo para una rueda aumentaba, nuestro mecánico tenía que acceder a su catálogo y modificar el precio total en:</p>
<ul>
<li>Tornillo para rueda</li>
<li>Llantas (en todos y cada uno de los modelos que usaran los tornillos anteriores)</li>
<li>Ruedas (en todos y cada uno de los modelos que usaran las llantas anteriores)</li>
</ul>
<p>Como podemos imaginar, esta situación era muy laboriosa. Así pues, nuestro ingeniero desarrolló un sistema que realizara el cálculo del precio de forma automática a la vez que modelaba el almacén de recambios con una estructura arborescente. En lugar de disponer del siguiente modelo:</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/03/033014_1801_patronesest3.png" alt="" /></p>
<p>Le proporcionamos este:</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/03/033014_1801_patronesest4.png" alt="" /></p>
<h2>Aplicando Composite</h2>
<p>Es hora de ensuciarnos un poco las manos y plantar cara a nuestro código. Comenzaremos creando nuestro elemento abstracto o interfaz correspondiente al «Componente». Esta clase o interfaz debe exponer los métodos comunes tanto a los elementos compuestos como a los elementos «hoja». Lo verdaderamente importante es que este elemento sea una abstracción (depender de abstracciones, no de concreciones).</p>
<ul>
<li>Si optamos por la interfaz, simplemente definiremos sus operaciones.</li>
<li>Si optamos por la clase abstracta, además de definir sus operaciones, añadiremos un comportamiento por defecto en el que lanzaremos una excepción que indique que la operación no está soportada. De este modo, las clases derivadas deberán encargarse de proporcionar la funcionalidad. En caso de no proporcionarla, lanzarán una excepción (por ejemplo, el método <em>add</em> en un elemento <em>Hoja</em> no tiene sentido, por lo que deberá tener este comportamiento por defecto).</li>
</ul>
<p>Nuestra clase <em>Componente</em> será, por tanto, el siguiente:</p>
<pre class="brush: csharp; title: ; notranslate">
    public abstract class ComponenteRecambio
    {
        #region Métodos comunes a objetos compuestos y hojas

        public virtual string getNombre()
        {
            throw new NotSupportedException(this.GetType().Name + &quot;getNombre()&quot;);
        }

        public virtual void setNombre(string nombre)
        {
            throw new NotSupportedException(this.GetType().Name + &quot;setNombre()&quot;);
        }

        public virtual string getDescripcion()
        {
            throw new NotSupportedException(this.GetType().Name + &quot;getDescripcion()&quot;);
        }

        public virtual void setDescripcion(string descripcion)
        {
            throw new NotSupportedException(this.GetType().Name + &quot;setDescripcion()&quot;);
        }

        public virtual double getPrecio()
        {
            throw new NotSupportedException(this.GetType().Name + &quot;getPrecio()&quot;);
        }

        public virtual void setPrecio(double precio)
        {
            throw new NotSupportedException(this.GetType().Name + &quot;setPrecio()&quot;);
        }

        #endregion

        #region Métodos exclusivos de los objetos compuestos

        public virtual void add(ComponenteRecambio componente)
        {
            throw new NotSupportedException(this.GetType().Name + &quot;add()&quot;);
        }

        public virtual void remove(ComponenteRecambio componente)
        {
            throw new NotSupportedException(this.GetType().Name + &quot;remove()&quot;);
        }

        public virtual ComponenteRecambio getElemento(int indice)
        {
            throw new NotSupportedException(this.GetType().Name + &quot;getElemento()&quot;);
        }

        #endregion
    }

</pre>
<p>Sobre esta clase trabajaremos creando otras dos clases que simbolizarán los dos tipos de elemento que puede contener nuestro patrón <em>Composite</em>: elementos hoja (ElementoRecambio) y elementos compuestos (Recambio). Así, nuestros elementos «hoja» serán los que incorporen la verdadera funcionalidad, que será invocada por los elementos compuestos en caso de que fuera necesario.</p>
<p>Hemos utilizado «nomenclatura Java» (getters y setters en lugar de una propiedad para ambas operaciones) porque a la hora de sobrecargar los métodos será más intuitivo si las operaciones se encuentran separadas, como veremos más adelante. Por supuesto, para quien lo desee, también es posible usar propiedades virtuales y sobrecargarlas del mismo modo que hacemos con estos dos métodos.</p>
<p>Volviendo a nuestro código, nuestra clase <em>ElementoRecambio</em> almacenará información como el nombre, la descripción y el precio:</p>
<pre class="brush: csharp; title: ; notranslate">

    public class ElementoRecambio : ComponenteRecambio
    {
        // Atributos propios del nodo hoja.
        private string nombre;
        private string descripcion;
        private double precio;

        // Constructor
        public ElementoRecambio(string nombre, string descripcion, double precio)
        {
            this.nombre = nombre;
            this.descripcion = descripcion;
            this.precio = precio;
        }

        // Sobrecargamos únicamente los métodos propios de los nodos hoja, destinados
        // a devolver la información y a asignarla

        // NOMBRE
        public override string getNombre()
        {
            return nombre;
        }

        public override void setNombre(string nombre)
        {
            this.nombre = nombre;
        }

        // DESCRIPCION
        public override string getDescripcion()
        {
            return descripcion;
        }

        public override void setDescripcion(string descripcion)
        {
            this.descripcion = descripcion;
        }

        // PRECIO
        public override double getPrecio()
        {
            return precio;
        }

        public override void setPrecio(double precio)
        {
            this.precio = precio;
        }

        // Los métodos add, remove y getElemento no se sobrecargarán, ya que
        // el nodo hoja no estará compuesto por más elementos que él mismo.
        // Por tanto, si se invocan estos métodos, se llamará el método padre
        // que lanzará una excepción de tipo NotSupportedException
    }

</pre>
<p>Seguramente, a estas alturas ya nos habremos dado cuenta de lo que comentábamos al principio del artículo respecto a la ruptura del principio de responsabilidad única. La clase <em>Elemento</em> implementa un conjunto de métodos, pero deja otro conjunto sin implementar (los métodos <em>add, remove </em>y <em>getElemento</em>), que lanzarán una excepción si te utilizan. Esos métodos serán implementados por la siguiente clase: <em>Recambio</em>.</p>
<pre class="brush: csharp; title: ; notranslate">
    public class Recambio : ComponenteRecambio
    {
        // Arraylist que contendrá los elementos hijo
        private ArrayList listaRecambios;

        // Atributos
        private string nombre;
        private string descripcion;

        // Constructor que recibirá el nombre, el precio y la descripción.
        public Recambio(string nombre, string descripcion, double precio)
        {
            // Instanciamos el ArrayList
            listaRecambios = new ArrayList();

            // Asignamos el nombre, la descripción y el precio
            this.nombre = nombre;
            this.descripcion = descripcion;
            this.precio = precio;

        }

        #region Métodos relacionados con el árbol

        // Añade un nuevo elemento al ArrayList
        public override void add(ComponenteRecambio componente)
        {
            listaRecambios.Add(componente);
        }

        // Elimina un elemento del ArrayList
        public override void remove(ComponenteRecambio componente)
        {
            listaRecambios.Remove(componente);
        }

        // Recupera un elemento del ArrayList
        public override ComponenteRecambio getElemento(int indice)
        {
            return (ComponenteRecambio)listaRecambios[indice];
        }

        #endregion

    } 

</pre>
<p>En esta primera etapa, hemos codificado la parte que se encarga de añadir, eliminar y consultar otros elementos. El método es sencillo: a través de un ArrayList interno, los métodos <em>add, remove</em> y <em>getElemento</em> realizarán operaciones sobre él.</p>
<p>A continuación codificaremos los métodos <em>get</em> que recuperarán el contenido de los atributos de cada <em>ElementoRecambio</em>: nombre, descripción y precio. Para ello iteraremos sobre los elementos contenidos dentro de cada <em>Recambio</em>.</p>
<p>El precio, sin ir más lejos, se calculará a partir de los precios de los elementos contenidos en cada <em>ElementoRecambio</em>, que se sumará al precio del propio componente.</p>
<pre class="brush: csharp; title: ; notranslate">
        #region Métodos relacionados con el elemento

        public override string getNombre()
        {
            string nombreCompleto = this.nombre + &quot;\n&quot;;

            foreach(ComponenteRecambio c in listaRecambios)
                nombreCompleto += c.getNombre();

            return nombreCompleto;
        }

        public override string getDescripcion()
        {
            string descripcionCompleta = this.descripcion + &quot;\n&quot;;

            foreach (ComponenteRecambio c in listaRecambios)
                descripcionCompleta += c.getDescripcion();

            return descripcionCompleta;
        }

        public override double getPrecio()
        {
            double precioTotal = this.precio;

            foreach (ComponenteRecambio c in listaRecambios)
                precioTotal += c.getPrecio();

            return precioTotal;
        }

        #endregion

</pre>
<p>También sobrecargaremos los métodos <em>setNombre, setDescripcion </em>y <em>setPrecio</em>.</p>
<pre class="brush: csharp; title: ; notranslate">
        public override void setNombre(string nombre)
        {
            this.nombre = nombre;
        }

        public override void setDescripcion(string descripcion)
        {
            this.descripcion = descripcion;
        }
        public override void setPrecio(double precio)
        {
            this.precio = precio;
        }

</pre>
<p>Recorriendo todos los elementos contenidos dentro de cada recambio podremos obtener la información almacenada tanto en un objeto nodo (<em>Recambio</em>) como en un objeto hoja (<em>ElementoRecambio</em>). Ambos se tratarán de la misma manera, aunque la implementación de los métodos sea distinta. Y dado que ambos objetos son intercambiables, estamos consiguiendo lo que declaramos en primera instancia: componer objetos de forma arborescente respetando la jerarquía todo-parte permitiendo que ambos elementos se traten de forma uniforme.</p>
<pre class="brush: csharp; title: ; notranslate">
            // Declaramos los tornillos incluidos en la llanta, que serán nodos hoja
            ComponenteRecambio tornillo1 = new ElementoRecambio(&quot;Tornillo llanta&quot;, &quot;Tornillo llanta marca ACME&quot;, 0.21);
            ComponenteRecambio tornillo2 = new ElementoRecambio(&quot;Tornillo llanta&quot;, &quot;Tornillo llanta marca ACME&quot;, 0.21);
            ComponenteRecambio tornillo3 = new ElementoRecambio(&quot;Tornillo llanta&quot;, &quot;Tornillo llanta marca ACME&quot;, 0.21);
            ComponenteRecambio tornillo4 = new ElementoRecambio(&quot;Tornillo llanta&quot;, &quot;Tornillo llanta marca ACME&quot;, 0.21);

            // Declaramos la llanta, que poseerá cuatro tornillos. Por tanto, se tratará de un elemento Composite (compuesto
            // por otros elementos, que pueden ser compuestos u hojas)
            ComponenteRecambio llanta = new Recambio(&quot;Llanta ACME 15'&quot;, &quot;Llanta ACME de 15'&quot;, 42.22);

            // Añadimos los tornillos a la llanta
            llanta.add(tornillo1);
            llanta.add(tornillo2);
            llanta.add(tornillo3);
            llanta.add(tornillo4);

            // Declaramos ahora otro elemento: la válvula de la rueda
            ComponenteRecambio valvula = new ElementoRecambio(&quot;Válvula&quot;, &quot;Válvula de neumático genérica&quot;, 0.49);

            // Realizamos lo mismo con el neumático
            ComponenteRecambio neumatico = new ElementoRecambio(&quot;Neumático 15'&quot;, &quot;Neumático Michelin de 15'&quot;, 13.42);

            // Declaramos un nuevo objeto compuesto: la rueda.
            // Este objeto estará compuesto por la llanta, la válvula y el neumático.
            // A su vez, la llanta incluirá los tornillos.
            // Establecemos el precio de la rueda a '0', ya que dependerá en exclusiva del contenido de sus elementos.
            ComponenteRecambio rueda = new Recambio(&quot;Rueda 15'&quot;, &quot;Rueda de 15' con llanta ACME y neumático Michelin&quot;, 0);

            // Añadimos a la rueda los elementos hoja que instanciamos previamente
            rueda.add(llanta);
            rueda.add(neumatico);
            rueda.add(valvula);

</pre>
<p>Si consultamos el método <em>getNombre()</em> de nuestra rueda, se mostrará el contenido del atributo privado <em>nombre</em> para, a continuación, iterar sobre cada elemento del ArrayList invocando a su vez el método <em>getNombre()</em> de cada elemento de forma recursiva. Así, obtendríamos lo siguiente:</p>
<pre class="brush: csharp; title: ; notranslate">
            Console.WriteLine(rueda.getNombre());
</pre>
<p>Lo cual nos daría la siguiente salida:</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/03/033014_1801_patronesest5.png" alt="" /></p>
<p>Si hacemos lo propio con el precio, obtendríamos la suma de todos los precios de sus elementos hoja. Si después de esto realizamos una modificación en el precio de uno de los elementos contenidos dentro del objeto compuesto, el cambio se propagará de forma automática sin necesidad de modificar el precio total de cada rueda.</p>
<pre class="brush: csharp; title: ; notranslate">
            double precioTotal = rueda.getPrecio();

            Console.WriteLine(&quot;El precio total de la rueda es &quot; + precioTotal);

            // Modificamos el precio de los tornillos para ver cómo afecta al precio total
            tornillo1.setPrecio(0.34);
            tornillo2.setPrecio(0.34);
            tornillo3.setPrecio(0.34);
            tornillo4.setPrecio(0.34);

            precioTotal = rueda.getPrecio();
            Console.WriteLine(&quot;El precio total de la rueda tras la subida de precio es &quot; + precioTotal);
</pre>
<p>Esto producirá la siguiente salida:</p>
<p style="text-align:center;"><img src="https://danielggarcia.wordpress.com/wp-content/uploads/2014/03/033014_1801_patronesest6.png" alt="" /></p>
<h2>Purismo vs. Transparencia</h2>
<p>Nos acabamos de encontrar con el primer patrón que viola deliberadamente uno de los principios de la programación orientada a objetos. El motivo ha sido que el incremento en la transparencia (y usabilidad) es tan importante que merece la pena el sacrificio de permitir que una clase adquiera más de una responsabilidad. Recordemos que los patrones de diseño son <strong>soluciones genéricas a problemas concretos</strong>, por lo que su objetivo es la de facilitar el desarrollo de software. Hay ocasiones, por tanto, en las que las que las ventajas de romper las normas sobrepasan de largo seguirlas a rajatabla.</p>
<h2>¿Cuándo utilizar este patrón? Ejemplos reales</h2>
<p>Los escenarios en los que este patrón suele utilizarse son, principalmente:</p>
<ul>
<li>Como su propia definición indica, cuando se requiere representar jerarquías todo-parte que superen cierto tamaño.</li>
<li>Cuando se desea que los clientes puedan ignorar la diferencia entre colecciones de objetos y objetos individuales, haciendo que ambos se traten de la misma manera.</li>
</ul>
<p>El ejemplo más sencillo de visualizar de este patrón son los controles de un formulario, por ejemplo de WinForms. Los objetos (botones, literales, paneles…) heredan de la clase <em>Control</em>, que, de base, puede contener a su vez una colección de otros objetos que hereden de la clase <em>Control</em>. Cada uno de estos controles pueden tratarse bien como un control individual en sí o como una colección de controles (un panel puede contener, por poner un ejemplo, un Label, un Button y un RadioButton).</p>
<p>El sistema del pipeline de petición/respuesta de ASP.NET también sigue este esquema.</p>
<p>Finalmente, la estructura de ficheros y directorios de un sistema de archivos también actúa en consonancia con este patrón.</p>
<h3>Fuentes:</h3>
<ul>
<li><a href="http://shop.oreilly.com/product/9780596007126.do">Head First Design Patterns</a> (Freeman et al.)</li>
<li><a href="http://www.dofactory.com/Patterns/PatternComposite.aspx">Composite</a> (doFactory)</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://danielggarcia.wordpress.com/2014/03/31/patrones-estructurales-vi-patron-composite/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1047</post-id>
		<media:content url="https://1.gravatar.com/avatar/77787450a00d8f7372bceaa70593a9c6156f81bb51204ddc5bb88b1ad375de8a?s=96&#38;d=https%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">danielggarcia</media:title>
		</media:content>

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/03/033014_1801_patronesest1.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/03/033014_1801_patronesest2.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/03/033014_1801_patronesest3.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/03/033014_1801_patronesest4.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/03/033014_1801_patronesest5.png" medium="image" />

		<media:content url="https://danielggarcia.wordpress.com/wp-content/uploads/2014/03/033014_1801_patronesest6.png" medium="image" />
	</item>
	</channel>
</rss>
