Hola a todos los lectores de este blog, aquí les dejo un video muy bueno con el resumen de las estadísticas, experiencias y pensamientos sobre las mujeres en el mundo de la innovación. El video es una introducción a este tema, en general plasma la idea de los datos reales de las mujeres en esta área de la innovación, comenzando por el pasado, para pasar al presente y el futuro. ¡Échele un vistazo! y comente lo que percibió.

Buen día a todos los lectores de este blog de código, esta vez me encuentro aquí para de manera simple, rápida y conjunta entregarles lo que al menos yo considero esencial en cuanto a atajos de teclado para mac.

Recientemente migré a mac; en el pasado ya había utilizado como SO personal y de trabajo a Windows y Linux, y en general mi preferido es Linux, sin embargo le estoy dando la oportunidad a Mac y su suite de SO, Apps y Hardware. Realmente lo que más me llamó la atención de comprar una mac fue el hardware por su fama de buena calidad y duración, además de otras monerías también en hardware como disco duro de estado sólido, la pantalla retina, teclado backlit (retroiluminado), el trackpad, y sobre todo ligereza. Como se darán cuenta jamás pensé en el Software (:p), y en realidad así fue, no tomé las medidas necesarias sobre software y en el momento en que la encendí y la comencé a utilizar ya era un completo desastre queriendo abrir ventanas,  bloquear pantalla, minimizar ventanas, copiar, pegar y demás con shortcuts de Windows y Linux, entonces paré y me dije a mi misma ¡Muy mal hecho Marcela!, e inmediatamente me dispuse a corregir mi error buscando en Internet lo necesario para sobrevivir de manera básica en Mac; aquí entonces el recopilado de lo que obtuve:

Minimizar ventanas

En Mac no es posible minimizar al Dock todas las ventanas abiertas de la manera en que lo hacen Windows y Linux, pero es posible simularlo dependiendo de la perspectiva que se tenga de minimizar.
Command + M Minimiza la ventana activa al Dock.
Command + Option + M  Minimiza todas las ventanas de la aplicación activa al Dock.
Command + Option + H + M  Combinación teclas que da la sensación de que minimiza todas las ventanas, pero sin ser esto cierto ya que no quita el foco de la última aplicación activa minimizada y por ende es necesario ponerlo manualmente dando clic al escritorio. Otra es que algunas aplicaciones no se minimizan si son las ventanas activas en ese momento (Ejemplo: la calculadora).
Fn + F11 Oculta las ventanas abiertas en la parte superior y así muestra el escritorio, sin poner el foco en este, es necesario hacerlo manualmente dando clic al escritorio.
La más parecida, efectiva y rápida me parece que es la última opción porque aunque no minimiza las ventanas abiertas, las oculta, permitiendo ver el escritorio que es lo que se necesita cuando solemos querer minimizar todas las ventanas.

Bloquear pantalla

Control + Shift + Power button Bloquea la pantalla.

Abrir ventana Finder

En mac no es posible abrir una ventana del Finder de manera directa como lo hacen Windows y Linux, pero si es posible abrir una ventana nueva desde la perspectiva en que se necesite.
Command + Tab Debido a que el Finder es un elemento que siempre está abierto desde que inicia el SO podemos simplemente movernos entre ventanas abiertas con esta combinación de teclas.
Option + Command + Space bar  Si nos encontramos ejecutando alguna otra aplicación o tenemos alguna otra ventana activa es imposible llamar al Finder directamente, pero lo que si es posible hacer con esta combinación de teclas, es simular esta acción llamando a la ventana de búsqueda en el Finder. 

Shortcuts principales del Finder

La versión Maverick del SO ha incluido por primera vez el uso de pestañas en el Finder por lo que te recomiendo hagas uso de esta muy buena funcionalidad. Parece que mac ya no se quiere quedar abajo y comienza a hacer competencia con este tipo de funcionalidades bastante útiles.
Shift + Command + HAbrir la ventana de Home.
Shift + Command + CAbrir la ventana de Computer.
Shift + Command + AAbrir la ventana de Applications.
Shift + Command + FAbrir la ventana de All my Files.
Command + NAbrir una nueva ventana del Finder.
Command + TAbrir una nueva pestaña en el Finder.
Control + TMovernos entre pestañas del Finder.
Command+ WCerrar una pestaña del Finder.
Command + W / Shift + Command + WCerrar una ventana del Finder / Si existen pestañas se añade Shift para cerrar la ventana del Finder.
Command + FColocar el cursor en el campo de búsqueda.

Shortcuts Generales

Command + CCopiar al Clipboard lo que se tenga seleccionado.
Command + VPegar lo que se tenga en el Clipboard en el lugar seleccionado.
Command + ZDeshacer algún cambio hecho.
Command + ASeleccionar todos los Items en una carpeta ó todo el texto en un archivo o editor.
Command + Option + ADe-seleccionar los Items previamente seleccionados en una carpeta. No funciona para texto.
Command + QSalir de una aplicación.
Command + Flecha Der / Control + EIr al fin de una línea de texto. Agregar Shift para seleccionar.
Command + Flecha Izq / Control + AIr al inicio de una línea de texto. Agregar Shift para seleccionar.
Command + Flecha Arriba / Fn + Flecha ArribaIr al inicio de un archivo de texto. Agregar Shift para seleccionar todo.
Command + Flecha Abajo / Fn + Flecha AbajoIr al fin de un archivo. Agregar Shift para seleccionar todo.
Control + D / Fn + DeleteSuprimir letra siguiente.
Option + Flecha Der o Flecha IzqMoverse entre palabras en una línea de texto. Agregar Shift para seleccionar palabras.

Este es el recopilado que tengo hasta el momento, espero sea de su interés y les facilite la vida como a mi me la hubiera facilitado si hubiera habido una blog con todos los nuevos shortcuts en Mac, digo nuevos porque estoy en la versión de Maverick y al menos para esta versión si han cambiado cosas con respecto a versiones anteriores.
Como ya saben, son bienvenidos todos sus comentarios, dudas, sugerencias y cualquier cosa que enriquezca el contenido de este blog. ¡Hasta pronto!
¿Alguna ves habían imaginado la cantidad de datos que fluyen por segundo en Internet?

Pues no lo imaginen más, les dejo una página interesante que muestra esta estadística en tiempo real. Me di cuenta de ella gracias a mi colaborador Juan Antonio Sandoval Delgado/@juanitodread



Click the image to open the interactive version (via http://pennystocks.la).
Hola a tod@s, en este post les vengo a hablar de los famosos XML Schemas o bien llamados XSD. Esta es una introducción con fundamentos para crear XSD para validar una estructura XML.

Se asume que el que lee tiene conocimientos de HTML / XHTML, XML, XML Namespaces y un poco de conocimientos de DTD. Si no los tiene se sugiere lea un poco sobre estos temas antes de continuar leyendo.

¿Qué es un XML Schema ó XSD?

Un XML Schema tiene como propósito definir la estructura correcta de tags en un archivo XML como lo hacen los DTD.

Un XML Schema define elementos que pueden aparecer en un documento XML así como sus atributos. Define cuales elementos son hijos, el orden de los elementos, su tipo y el de sus atributos, si están vacíos, etc.

¿Por qué usarlos?

Se considera que los XML Schemas vienen a substituir a los DTD por que poseen varias ventajas sobre los anteriores.

Al ser un archivo con formato XML éste puede ser validado y saber si está bien formado. Además soportan datatypes y namespaces lo que los hace más poderosos y ricos que los DTD, y extensibles para posibles cambios.

Propone un ambiente seguro para la comunicación de datos ya que de esta forma podemos asegurarnos que al existir una transferencia de datos por XML ambos lados estarán transmitiendo la información en los formatos adecuados y así evitar diferencias en la información.

¿Cómo usarlos?

Como dijimos anteriormente un XSD existe para un XML, para definirlo y validarlo. A partir de esta premisa podemos partir de 2 cosas: podemos tener una XML el cual queramos validar y a partir de él crear un XSD ó podemos crear un XSD que defina la estructura de un XML y posterior a eso crear el archivo XML para validarlo. Por lo general es más sencillo verlo de la primer forma en la que ya existe un XML y lo validaremos y definiremos con un XSD ya que es más fácil pensar en un XML que en un definidor de XML.

XML

Tomando en cuenta el primer caso en que ya tenemos un XML que validar observe el siguiente código XML del archivo llamado XMLAgenda.xml

<?xml version="1.0" encoding="UTF-8"?>
<Contacts name="MyContacts" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="XSDAgendaNamedTypes.xsd">
 <userID>msena</userID>
 <info>
  <name>Marcela Sena</name>
  <age>25</age>
  <tel type="Mobile">
   <number>3312345678</number>
  </tel>
 </info>
 <contact>
  <name>Liliana Sena</name>
  <address>15 California St.</address>
  <tel type="Mobile">   
   <number>1234567890</number>
  </tel>  
 </contact>
 <contact>
  <name>Juan Sandoval</name>  
  <email>jsandoval@domain.com</email>
  <address>189 San Francisco St.</address>
  <tel type="Home">   
   <number>0987654321</number>
  </tel>  
 </contact>
</Contacts>

El código estructura la información de una lista de contactos iniciando con un nombre, nombre de usuario, datos personales del owner y una lista de elementos que engloban los datos de cada contacto.

XSD

Ahora que tenemos el XML debemos definir una estructura XSD para definir nuestro XML y así validarlo.
Lo primero que debemos hacer es definir nuestro archivo como un XML y crear la estructura base del schema con un namespace default xs de la siguiente forma:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
.
.
</xs:schema>

La URI asociada al xs namespace de nuetro XSD es el Lenguaje de Definición de Schemas con un valor estándar http://www.w3.org/2001/XMLSchema.


Ya que tenemos nuestra estructura base del Schema debemos crear los elementos y atributos que lo conforman, primero comenzaremos con "Contacts" que tiene un atributo y más elementos y es considerado como un complex type. Los elementos de Contacts estarán definidos dentro de xs:sequence que define una secuencia ordenada de sub elementos:

<xs:element name="Contacts">
 <xs:complextype>
  <xs:sequence>
  .
  .
  </xs:sequence>
 </xs:complextype>
</xs:element>

A continuación debemos definir el elemento "userID" como un tipo simple ya que no tiene atributos ni otros sub elementos. El type xs:string tiene el prefijo xs default del schema definiendo así que es un tipo base del schema:

<xs:element name="userID" type="xs:string"/>

Los siguientes elementos complex type a definir son "info" y "contact", vamos a comenzar con info:

<xs:element name="info">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="name" type="xs:string"/>
   <xs:element name="age" type="xs:positiveInteger"/>
   <xs:element name="tel">
    <xs:complexType>
     <xs:sequence>
      <xs:element name="number" type="xs:string"/>                  
     </xs:sequence>
     <xs:attribute name="type" type="xs:string" use="required"/>
    </xs:complexType>       
   </xs:element>
  </xs:sequence>
 </xs:complexType>
</xs:element>

El elemento "info" tiene 2 elementos de tipo simple y un complex type es por eso que <tel> es definido como un complex type con un atributo y un elemento simple.

Para el elemento "contact" tenemos 3 elementos simples y el mismo complex type <tel> que en "info". En el caso de "contact" utilizamos maxOccurs como "unbounded" que indica que este elemento puede haber muchas ocurrencias de éste.  Nosotros podemos utilizar maxOccurs y minOccurs para indicar la cantidad máxima y mínima de veces que puede aparecer un elemento, el valor por default para ambos es 1.

<xs:element name="contact" maxOccurs="unbounded">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="name" type="xs:string"/>
   <xs:element name="email" type="xs:string" minOccurs="0"/>
   <xs:element name="address" type="xs:string"/>
   <xs:element name="tel">
    <xs:complexType>
     <xs:sequence>
      <xs:element name="number" type="xs:string"/>                  
     </xs:sequence>
     <xs:attribute name="type" type="xs:string" use="required"/>
    </xs:complexType>       
   </xs:element>
  </xs:sequence>
 </xs:complexType>
</xs:element>

Ahora podemos definir el atributo "name" del elemento "Contacts", y como es un atributo requerido lo definimos como use=required.
Nota: Los atributos deben ser definidos siempre al final.

<xs:attribute name="name" type="xs:string" use="required"/>

Listo, ahora tenemos el código completo de nuestro schema XSDAgendaAnidada.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Contacts">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="userID" type="xs:string"/>
   <xs:element name="info">
    <xs:complexType>
     <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="age" type="xs:positiveInteger"/>
      <xs:element name="tel">
       <xs:complexType>
        <xs:sequence>
         <xs:element name="number" type="xs:string"/>                  
        </xs:sequence>
        <xs:attribute name="type" type="xs:string" use="required"/>
       </xs:complexType>       
      </xs:element>
     </xs:sequence>
    </xs:complexType>
   </xs:element>
   <xs:element name="contact" maxOccurs="unbounded">
    <xs:complexType>
     <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="email" type="xs:string" minOccurs="0"/>
      <xs:element name="address" type="xs:string"/>
      <xs:element name="tel">
       <xs:complexType>
        <xs:sequence>
         <xs:element name="number" type="xs:string"/>                  
        </xs:sequence>
        <xs:attribute name="type" type="xs:string" use="required"/>
       </xs:complexType>       
      </xs:element>
     </xs:sequence>
    </xs:complexType>
   </xs:element>
  </xs:sequence>
  <xs:attribute name="name" type="xs:string" use="required"/>
 </xs:complexType>
</xs:element>
</xs:schema>



Schema Dividido


Hemos visto un ejemplo muy básico de como crear un XSD, como ven el código es muy estructurado y anidado y no permite que podamos reutilizar elementos. Aquí presentamos otra versión con un código dividido que permite la reutilización de elementos. Esta forma de dividir define primero los elementos de tipo simple, en seguida los atributos y por último los elementos complex type que harán referencia a los elementos simples antes declarados con ref. Observe que ahora el elemento <tel> se puede reutilizar en "info" y en "contact".

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!--************Elements************-->
<xs:element name="userID" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="age" type="xs:positiveInteger"/>
<xs:element name="email" type="xs:string"/>
<xs:element name="address" type="xs:string"/>

<!--************Attributes************-->
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="type" type="xs:string"/>

<!--************Elements with ComplexType************-->
<xs:element name="tel">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="number" type="xs:string"/>                  
  </xs:sequence>
  <xs:attribute name="type" use="required"/>
 </xs:complexType>       
</xs:element>


<xs:element name="info">
 <xs:complexType>
  <xs:sequence>
   <xs:element ref="name"/>
   <xs:element ref="age"/>
   <xs:element ref="tel"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>

<xs:element name="contact">
 <xs:complexType>
  <xs:sequence>
   <xs:element ref="name"/>
   <xs:element ref="email" minOccurs="0"/>
   <xs:element ref="address" />
   <xs:element ref="tel"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>

<xs:element name="Contacts">
 <xs:complexType>
  <xs:sequence>
   <xs:element ref="userID" />
   <xs:element ref="info"/>
   <xs:element name="contact" maxOccurs="unbounded"/>
  </xs:sequence>
  <xs:attribute ref="name" use="required"/>
 </xs:complexType>
</xs:element>
</xs:schema>


Schema de Named Types


Otra forma de reutilizar es definiendo tipos nombrados ó Named Types. Esto es que podemos definir tipos simples y complejos (simple and complex types), tipos simples que definan mejor nuestras necesidades basados en tipos de schemas, y tipos complejos que permitan agrupar y simplificar código como en el caso de <tel>.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:simpleType name="myString">
 <xs:restriction base="xs:string"/>
</xs:simpleType>

<xs:simpleType name="myIntegerAge">
 <xs:restriction base="xs:positiveInteger">
  <xs:totalDigits value="2"/> 
 </xs:restriction>
</xs:simpleType>

<xs:simpleType name="myStringEmail">
 <xs:restriction base="xs:string">
  <xs:pattern value="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"/>
 </xs:restriction>
</xs:simpleType>

<xs:simpleType name="myStringTel">
 <xs:restriction base="xs:string">
  <xs:pattern value="[0-9]{10}"/>
 </xs:restriction>
</xs:simpleType>

<xs:simpleType name="myStringTelAttribute">
 <xs:restriction base="xs:string">
  <xs:enumeration value="Mobile"/>
  <xs:enumeration value="Home"/>
  <xs:enumeration value="Work"/>
 </xs:restriction>
</xs:simpleType>

<xs:complexType name="teltype">
 <xs:sequence>
  <xs:element name="number" type="myStringTel"/>                  
 </xs:sequence>
 <xs:attribute name="type" type="myStringTelAttribute" use="required"/>
</xs:complexType>       

<xs:complexType name="infotype">
 <xs:sequence>
  <xs:element name="name" type="myString"/>
  <xs:element name="age" type="myIntegerAge"/>
  <xs:element name="tel" type="teltype"/>
 </xs:sequence>
</xs:complexType>

<xs:complexType name="contacttype">
 <xs:sequence>
  <xs:element name="name" type="myString"/>
  <xs:element name="email" type="myStringEmail" minOccurs="0"/>
  <xs:element name="address" type="myString" />
  <xs:element name="tel" type="teltype"/>
 </xs:sequence>
</xs:complexType>


<xs:element name="Contacts">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="userID" type="myString"/>
   <xs:element name="info" type="infotype"/>
   <xs:element name="contact" type="contacttype" maxOccurs="unbounded"/>
  </xs:sequence>
  <xs:attribute name="name" type="myString" use="required"/>
 </xs:complexType>
</xs:element>
</xs:schema>

Note que existe un nuevo tag llamado restriction para los tipos simples que nos ayuda a definir a partir de un tipo base una restricción que nos ayuda a hacer más específica nuestra definición. El tag restriction puede tener diferentes sub tags como pattern, enumeration o totalDigits según sea el tipo base. En el caso del tipo base string xs:string tenemos que pattern nos ayuda a definir una expresión regular con la cual definir específicamente un valor (vease "myStringEmail") en caso de no hacer match con la expresión marcará error. También es posible definir una enumeración de valores que puede contener un tipo definiendo dentro de restriction una serie de enumeration tags con los valores válidos; en caso de que el valor existente en el XML no coincida con los valores de la enumeración marcará un error. Para el caso del tipo xs:positiveInteger tenemos que podemos definir el número total de Dígitos que puede tener con totalDigits; en caso de no tener  los dígitos especificados marcará error.

<xs:restriction base="xs:string">
 <xs:pattern value="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"/>
 <!-- OR -->
 <xs:enumeration value="Mobile"/>
 <xs:enumeration value="Home"/>
 <xs:enumeration value="Work"/>
</xs:restriction>
<!--*****************************************************************-->
<xs:restriction base="xs:positiveInteger">
 <xs:totaldigits value="2"/> 
</xs:restriction>

Este post esta basado en el Tutorial de Esquemas de w3school.


Espero este post con fundamentos sea de utilidad para alguien y como siempre invito a todos a colaborar con sus comentarios, sugerencias, dudas y demás. ¡Hasta pronto!

Principio de Diseño

Pugna por un diseño de bajo acoplamiento en objetos que interactuan. Esto se refiere a no hacer dependientes nuestras clases que se relacionan y pugnar por hacer un diseño flexible que minimice el impacto del cambio manejando la interdependencia entre objetos para poder modificarla cuando deseemos sin tener que afectar a las clases relacionadas.

Observer

Define una dependencia entre objetos de uno a muchos de modo que cuando un objeto cambia su estado todos sus dependientes son notificados y actualizados automáticamente.

El Patrón Observador es muy usado tal vez lo puedas recordar en interfaces gráficas en los eventos de un objeto, o quizá simplemente hayas escuchado la analogía con "Las revistas y sus suscriptores", en sí ejemplificarlo puede llegar a ser fácil, pero eso no significa que sea sencillo. Como hemos visto en entradas anteriores aplicar un patrón no solo implica poner código aquí y allá, significa que todo tiene un porque y debe ser entendido para se vuelva útil y nos brinde una solución. A continuación haremos una reflexión sobre el patrón Observador, pon mucha atención.

Utilizando la analogía antes mencionada sobre "Las revistas y sus suscriptores" te presentamos al patrón observador, infórmate sobre lo que acontece en Objectville.

¿Sabes cómo funcionan las suscripciones de revistas y periódicos?

  1. Un editor de revistas o periódicos entra en el negocio y comienza a publicar noticias y artículos.
  2. Usted se suscribe a un editor y cada cierto tiempo se le entrega una nueva edición de la revista o periódico. Siempre que usted sea un suscriptor recibirá nuevas ediciones.
  3. Usted se da de baja como suscriptor porque ya no desea recibir más ediciones y las ediciones dejan de ser entregadas.
  4. Mientras exista un editor publicando ediciones existirán personas, empresas, hoteles, aerolíneas suscribiéndose para recibir las ediciones. 
Editores + Suscriptores = Patrón Observador.

Si entendemos esta analogía de suscripciones podemos entender muy fácilmente el patrón observador sólo que nosotros llamaremos al Editor como Sujeto y al Suscriptor como Observador. Echemos un vistazo.

Como vemos en la imagen existe un Sujeto el cual tiene sus observadores (relación uno a muchos) y cuando el sujeto cambia su estado sus observadores son notificados y actualizados automáticamente igual que la forma de trabajo de un Editor y sus suscriptores, el que esta suscrito recibe las ediciones y el que no, no. Viendo el mismo ejemplo de la imagen Duck Object no es un observador de Subject Object pero puede hacerlo si se suscribe notificándole a Subject y empezar a recibir notificaciones y actualizaciones, y de igual forma Mouse Object que es un observador puede dejar de serlo en el momento en que desee, sólo tiene que avisarle al Subject  y dejará de recibir las notificaciones y actualizaciones.

Bien ya vimos un ejemplo muy claro de la forma de trabajar del Patrón Observador ¿Lo haz comprendido? Suena fácil, ¿no?. ¡Aplicalo entonces! . . .  Bien veo que aquí te detuviste y pensaste ¿Cómo implemento el Patrón Observador? ¿Debo usar una interfaz o una clase abstracta para los Observadores y el Sujeto?,  ¿Cómo hago la relación uno a muchos?, ¿Cómo se suscriben los Observadores al Sujeto y cómo dejan de estar suscritos?. Sé que como buen diseñador de patrones ya pensaste algunas cosas e intentaste aplicar los principios de diseño vistos anteriormente y pensaste en el principio de diseño que te presentamos al inicio de este post. Concentra tus ideas y observa el diagrama de clases de la definición del Patrón Observador:
¿Se parece al que pensaste?, ¿Ya viste los principios de diseño aplicados?. Si es tal cual lo pensaste Felicidades eres un gran diseñador de patrones y haz comprendido cómo trabaja el Patrón Observador y sabes aplicar los principios de diseño. Si no fue tal cual lo pensaste te invito a continuar con la lectura y seguir el caso práctico para que lo comprendas a la perfección.

Caso Práctico:
¡FELICIDADES! Su equipo de trabajo acaba de ganar el contrato para construir la próxima generación de la Estación de Monitoreo del Tiempo basada en Internet de Weather-O-Rama, Inc.

La estación del tiempo estará basada en la patente pendiente WeatherData Object de Weather-O-Rama, Inc., la cual rastrea las condiciones actuales del tiempo (humedad, temperatura y la presión atmosférica). Usted y su equipo debe hacer una aplicación la cual muestre 3 diferentes pantallas del tiempo: Condiciones actuales, Estadísticas del tiempo y un Pronóstico simple, todas actualizadas en tiempo real cuando el objeto WeatherData obtenga las mediciones mas recientes. Además Weather-O-Rama desea hacer su estación del tiempo extensible por lo que solicita se haga una API la cuál permita a otros desarrolladores escribir sus propias pantallas del tiempo. 

Weather-O-Rama espera tus diseños y una aplicación alpha para probar, ¿qué esperas?.
Tienes mucho trabajo y debes tomar calma para pensar que hacer al respecto. Como somos muy buena onda, te echaremos una mano y te ayudaremos con la tarea encargada, pero no significa que lo haremos por ti, si pensaste eso estas muy equivocado. Manos a la Obra, primero repasemos que es lo que el cliente te pidió. 
Los 3 elementos en juego en el sistema son: La estación del tiempo, el Objeto WeatherData y las Pantallas del Tiempo que debemos mostrar, por lo que tenemos:

El Objeto WeatherData sabe como comunicarse con la Estación física del tiempo para obtener la actualización de la información. Por lo que nuestro trabajo es hacer una aplicación que implemente el Objeto WeatherData que actualice las Pantallas de tiempo, condiciones actuales, estadísticas del tiempo y el pronóstico. Dicho Objeto nos será proporcionado por el cliente.

Desempaquetando la Clase WeatherData.

Al día siguiente como lo prometió el cliente nos entregó el paquete con la clase WeatherData, echemos un vistazo:

Como vemos en la imagen el cliente nos dejó una pista sobre lo que necesitamos agregar y nuestro trabajo es implementar el método measurementsChanged() el cual actualizará las pantallas del tiempo. Este método es llamado cada vez que existe nueva información de la estación del tiempo. Nosotros no sabemos cómo es que este método es llamado y no debe interesarnos, solo debemos saber que es llamado de alguna forma. Existen 3 métodos más los cuales obtienen la información de humedad, temperatura y presión, y nosotros debemos implementar 3 pantallas que muestren las condiciones actuales, las estadísticas del tiempo y el pronóstico. Además el sistema debe ser extensible debemos crear una API que permita a otros desarrolladores escribir su propio código de nuevas pantallas del tiempo. 
Hagamos una primer implementación de la Clase WeatherData con lo que tenemos.

¡Bien hecho! ahí tienes el primer diseño y porque no la aplicación alpha que el cliente pidió. Muy rápido ¿no?. Demasiado rápido diría yo, lo cuál me hace pensar que creíste que todo estaba correcto. ¿Notaste acaso algo raro en nuestro código? ¡Claro! y los principios de diseño ¿dónde están?, y el patrón observador ¿cuándo lo aplicamos?. Qué bueno que te diste cuenta a tiempo, sino hubieras entregado el horror de código del año. Ahora sí, tomemos los principios de diseño que ya teníamos y detectemos nuestros errores.

Ahora recordemos la definición del patrón observador (apóyate del diagrama que hicimos para el patrón observador y crea el tuyo) y apliquemosla junto a nuestros principios de diseño. Tómate tu tiempo, sabemos que diseñar no siempre es fácil, lo que debes hacer es preguntarte ¿Porque debemos aplicar el patrón observador a esta aplicación? Si respondes a tu pregunta haciendo la analogía de los editores y suscriptores haz dado en el blanco y podrás avanzar rápidamente. Como información adicional toma en cuenta lo siguiente para aplicar el último principio de diseño que te mencionamos al inicio del post.
El poder del Bajo Acoplamiento: Cuando dos objetos tienen bajo acoplamiento, pueden interactuar y tener poco conocimiento uno del otro. El patrón observador provee un diseño de objetos donde los sujetos y los observadores tienen bajo acoplamiento ya que lo único que sabe el sujeto sobre los observadores es que ellos implementan una interfaz en específico, lo que nos hace poder agregar observadores en el momento que queramos sin tener que modificar el sujeto para agregar nuevos observadores. Además podemos rehusar sujetos y observadores independientemente unos de otros y si cambiamos cualquiera de los dos no afectaría a los demás. Esto lo puedes observar en el diagrama del patrón observador. 
Implementación del Patrón Observador y principios de diseño.
¿Ya tienes tu diagrama de clases del Patrón Observador para la aplicación de La estación del tiempo? Comparémoslo.

¿Qué tanto se parece al tuyo?. Como ves hemos creado un diseño que nos permite a partir de que las nuevas mediciones de la Estación del tiempo llegan, actualizar en tiempo real las pantallas del tiempo. Podemos ademas agregar cuantas pantallas nuevas del tiempo deseemos sin necesidad de mover código gracias al bajo acoplamiento. Tenemos encapsaladas las partes que varían y creamos interfaces para poder cambiar en tiempo de ejecución nuestra implementación.
Ahora vayamos a la implementación de nuestro diseño, lo primero que implementremos serán nuestras interfaces.

Borremos de nuestra mente la implementación pasada de la Clase WeatherData, ahora ya conocemos el patrón observador y no tenemos porque dejar ese diseño funcional pero con errores de diseño que nos harían re trabajar. Recuerde que nuestra Clase WeatherDatase ha convertido en nuestro Sujeto concreto y debemos implementar la interfaz <<Subject>> y proveer los métodos registerObserver(), removeObserver() y notifyObservers(), además de implementar el método measurementsChanged() el cual será llamado cuando exista nueva información que actualizar. 

Para fines prácticos y ya que no sabemos en qué momento la Estación Física del Tiempo actualizará los datos crearemos un método setMeasurements() el cuál se encargará de setear los datos simulando la actualización de información enviada por la Estación Física del Tiempo.

Por último hagamos una implementación de las pantallas del tiempo, aquí sólo te mostraremos la implementación de la pantalla de condiciones actuales pero puedes obtener el código completo de la página de headfirstlab.
Y ahora las pruebas, sólo necesitamos unir las piezas y tendremos nuestro sistema WeatherStation listo para entregar.
¿Así imaginabas la implementación de las pantallas del tiempo?, ¿Te diste cuenta en que momento un observador se suscribe? Como se observa los observadores mantienen una relación con su sujeto y ellos deciden suscribirse al momento de ser creados para estar actualizados, si nosotros dejamos la suscripción en el constructor como se ve en la imagen tenemos la oportunidad de que si deseamos dejar de estar suscritos lo podemos hacer en tiempo de ejecución ya que el sujeto ha sido creado y mantenemos una relación a él, y de igual forma podríamos cambiar de sujeto para actualizar nuestros datos desde otro lugar.

¡FELICIDADES! Ahora ya sabes como diseñar el Patrón Observador. Por tu gran esfuerzo te proporcionaremos una segunda implementación en código del Patrón Observador (by @juanitodread) para que la puedas ver, probar, extender, etc., ¡Disfrútala!.

Aquí el código adicional del Patrón de Diseño Observador.

NOTA: Java maneja su propia implementación del patrón observador en el paquete java.util, que utiliza la clase Observable como el sujeto y la interfaz Observer como el observador. Esta implementación provee de mucha funcionalidad fuera del contexto que puede ser de gran utilidad. Sin embargo observa que Observable es una clase y por tanto deberás extenderla si deseas crear un sujeto concreto lo que provoca un rompimiento a nuestro principio de diseño "Favorece la composición en vez de la herencia". Esto no significa que sea por completo malo pero promueve un diseño no tan flexible como el que creamos, toma en cuenta la funcionalidad que te puede dar esta implementación de java y evalúa tú situación para implementarla o crear la tuya propia, porque ahora ya sabes como así que no tengas miedo de crear la tuya.

¿Entendiste el patrón?, ¿Tienes dudas?, no olvides preguntar, comentar, sugerir o corregir algo si lo deseas, con gusto responderé a cualquiera de tus comentarios.
Espero les sea de utilidad y puedan aprender algo nuevo con esta serie de posts, esperen muy pronto el siguiente. ¡Saludos!
¡Saludos!, aquí estoy de regreso para hablarles de Escape Characters utilizando Apache Commons y esperando les guste. Iniciamos . . . 

Alguna vez te habrás topado con la librería de Apache Commons, quizá cuando agregaste alguna otra librería a tu proyecto que necesitaba de ella, o cuando se presentó un error de librerías cuando agregaste dos librerías que la usaban y había conflictos por versiones, o ambigüedades de clases, o la viste en algún proyecto al que llegaste. Cualquiera que fuera el caso habrás escuchado de ella ya que es muy usada y famosa y si no, pues hoy será la primera vez y quizá te enamores de ella aunque sólo te presente un poco de lo que puedes hacer con Commons.

Commons es un proyecto de Apache el cuál está enfocado en todos los aspectos de componentes reusables  de Java. Prácticamente lo que hace es extender al lenguaje con Apis muy finas que se basan en la reutilización de código en Java. ¿Cuántas veces has pensado en que todo sería más fácil si ya existiera algo para resolver tu problema?, pues Apache se hizo la misma pregunta que tú y se puso a trabajar para darte ese algo que resuelve tú problema y otros más. No con esto quiero decir que Apache ya resolvió todo, y vas a encontrar la solución de todos tus problemas en Apache, pero lo que si encontrarás es lo más común como su nombre lo dice. ¿Imaginabas que alguien pudiera ahorrarte trabajo y mejor aún tuviera el respaldo de una empresa de renombre como Apache?, ahora que lo sabes porque no vas a echarle un vistazo.
No te fíes y echa un vistazo a la licencia de uso.

Ya que dí la introducción te puedo contar acerca de una de librerías de este proyecto que es Lang. Lang es un librería que provee extensiones muy necesarias para la librería java.lang de JDK SE, son muy genéricas y reutilizables para el uso diario. Dentro de ella existe un conjunto de clases que nos ayudarán con la manipulación de Strings, lo cuál usamos diariamente o ¿no?. 

En el uso diario de un String, ¿cuántas veces no haz tenido que escapar algún caracter que el lenguaje no te lo permite?, me imagino que muchas veces, a mi me pasa seguido en expresiones regulares. Java tiene su forma de escapar ciertos caracteres con \ (diagonal inversa), pero esto sólo tu lo puedes saber cuando lo estás tecleando, y en el caso de que los caracteres que necesites manipular vengan de otro lugar, ya sea de la web en un request, de una archivo, un componente swing, desde teclado en consola, etc., ¿cómo sabes que caracter escapar si tu no sabes cuales son?, bien pues para eso Apache Commons presenta una clase muy útil para escapar estos caracters. 
StringEscapeUtils nos permite escapar y des escapar caracteres en textos completos que contengan JavaScript, HTML, XML y SQL (y otros dependiendo la versión). Veámos el ejemplo.

//Escape Safe
public static String escapeXML(String escape){
  String escapeSafe = "";
  if(escape != null && escape.length() > 0){
        /*escapeXml,escapeHtml,escapeJava...*/
 escapeSafe = StringEscapeUtils.escapeXml(escape);
  }

  return escapeSafe;
}

¿En que podría usar el escape de caracteres?

  • Para escapar caracteres de código malicioso de SQL ó JavaScript que quieran intentar ejecutar desde nuestra aplicación. Inyección de SQL, XSS Cross-Site Scripting.
  • Si necesitas persistir información por ejemplo en BD y quieres guardar un script de JavaScript para después retornarlo y ejecutarlo, necesitaras escapar caracteres ya que al hacer un insert de la texto del script habrá caracteres que SQL no soporte y no te permita generar un query válido.

Esto es algo de que puedes encontrarte a diario, y que puede ayudarte a solucionarlo. ¿Tienes alguna duda, sugerencia, comentario, corrección?, no dudes en comentarlo. 

Strategy

Define una familia de algoritmos, encapsulados cada uno, e intercambiables. Strategy hace que los algoritmos varíen independientemente del cliente que los esté usando.

¿Te suena conocido?, tal vez lo hayas usado ya, sin saberlo. A continuación un caso práctico a resolver con este patrón. Sugerencia: Antes de ver el código solución del patrón aplicado, intenta aplicar los principios de diseño que mencioné anteriormente.

Caso Práctico:
Joe trabaja para una compañía que hace videojuegos y se quiere un juego que muestra a las distintas especies de patos en el mundo simulando sus características. Como primer entendimiento con el cliente se acordó únicamente simular el sonido que emiten dichas aves con un "Quak" y que se muestren nadando.
¿Cómo lo hizo Joe? Con una clase general "Duck" que encapsule las características más generales de todos los patos, implementar los métodos quak() swim() y crear un método abstracto display() para mostrar gáficamente el ave y del cual van a hacer un override todas sus hijas, que representan a todos los patos que existen  y que heredan de Duck. Joe hace el demo con 2 clases de patos distintas con sus implementaciones propias de display y todos hacen "Quack" y nadan.

Al cliente le gustó su demo, de hecho quedó fascinado y quiere comprarlo y hacerlo en grande, lo que significa "cambios". El cliente quiere obviamente agregar más patos, y que ahora se muestren volando.
¿Cómo lo hizo Joe? Fácil, implementando un nuevo método a la clase Duck que se llame fly()  y ahora todos los patos van a volar ya que heredan de Duck. Caso resuelto, !Es un genio!. Hacen el release al cliente.

Al siguiente día la jefa de Joe le habla furiosa desde la junta de presentación del demo preguntándole porque había patitos de hule volando y haciendo quak en la pantalla, haciendo referencia a si eso era su idea de una broma, Joe dijo que no y entonces su jefa con tono severo le sugirió ponerse a trabajar.

¿Qué fue lo que hizo mal Joe? Joe utilizó herencia. Cuando Joe agregó un nuevo comportamiento a la Superclase Duck automáticamente sus hijas heredaron este comportamiento, cosa que no todos los patos pueden hacer.
¿Qué pensó Joe para corregirlo? Joe pensó en convertir los métodos fly() y quak() en abstractos para que las sublcases implementaran el comportamiento que quisieran, sin embargo en el caso del "Patito de hule" no debe haber una implementación del método fly ni quak, a lo cuál pensó Joe ¿Tendría caso tener un método vacío? y ¿Qué tal si existen más patos que no vuelen o no hagan quak?. Entonces se le ocurrió, y ¿Qué tal una Interfaz? Así si creo una interfaz Flyable y una Quackable con su método fly() y quak() correspondientes sólo las clases que ocupen volar o hacer quak las implementarían, ¡Muy buena idea!. Joe informó a su jefa, a lo que esta respondió: Esa es la idea más tonta que he recibido. Lo que estás proponiendo es "Duplicar código". Si pensabas que sobrescribir unos métodos era malo, ¿que harás cuando tengas que hacer una modificación a fly(), modificarás las más de 48 clases?.

Joe tiene un problema. ¿Que harías si fueras Joe? Ya vimos que la herencia no es la solución, y la interfaz sólo resolvería parte del problema pues rompe con el principio de "reutilizar código". Lo que haremos será aplicar el primer principio de diseño que vimos en el post anterior y separar lo que varía de lo que no lo hace. ¿Ya sabes que es? El "Comportamiento (fly y quak)". Ahora que lo sabes debes aislar este comportamiento y encapsularlo fuera del que no cambia, por lo que ahora tendremos un conjunto de comportamientos para volar y otro para hacer quak. Comportamientos como fly, not fly, quackear, squeakear, silece, etc. 


¿Y qué sigue? Ahora que tenemos separados los comportamientos lo que debemos hacer es definir una interfaz la cuál nos dará la presentación de los comportamientos a otras clases y los generalizará, ¿Te recuerda a algo esto?. Claro es el segundo principio que vimos en el post anterior. Con esto conseguimos flexibilidad ya que lo que queremos es agregarle comportamiento a las subclases de Duck y si le asignamos un comportamiento definido después no vamos a poder modificarlo en tiempo de ejecución.
¿Y cómo diseñamos una interfaz que pueda modificarse en tiempo de ejecución? Realmente diseñar una interfaz significa diseñar una superclase y sus subclases, así de esta manera podemos utilizar polimorfismo y hacer que instancia de la superclase pueda referirse a cualquiera de sus subclases, en tiempo de ejecución, por lo que haremos una interfaz FlyingBehavior y QuackingBehavior con sus subclases correspondientes.

Ya tenemos aislados nuestros comportamientos y ya hicimos una interfaz con ellos, ahora sólo queda aplicar el último de los principios que vimos en el post anterior e integrar los comportamientos con Duck. ¿Por que con Duck? No habrás pensado que cometeríamos el mismo error anterior, ya dijimos que el hecho de tener una interfaz y hacer que solo implementen de ella las clases que lo ocupen no es la solución y esto no favorecería la reutilización de código, si lo ponemos en Duck lo que las subclases van a heredar será un comportamiento no una implementación. ¿Entonces que haremos? Lo que haremos es hacer una composición en la que podamos decir que Duck tiene un comportamiento de volar y de hacer quack, la cual van a heredar las subclases como atributos, y puedan instanciarlo en su constructor con el comportamiento deseado (FlyWithWings, Quak, Squeak, etc.), pero además agregaremos un método performQuak() y uno performFly() en Duck para que en este método podamos mostrar la implementación de fly() o quak() del comportamiento elegido en las subclases.

Como se ve en la imagen en Duck no nos interesa que comportamiento sea, únicamente nos interesa que sepa volar o hacer quak. Ahora sólo nos falta agregar el último toque que describa por completo nuestro Patrón Strategy y es "Hacer lo que varía intercambiable", en nuestro caso hacer los comportamientos intercambiables, esto es que podamos intercambiar de tipos de comportamiento en tiempo de ejecución ya que como lo tenemos cada subclase al instanciarse tiene definido un comportamiento, y lo que queremos es que ese comportamiento pueda cambiar. ¿Y para que?, pues imaginemos que el cliente quiere que el pato muestre su ciclo de vida desde que nace hasta que se hace adulto, entonces un pato  no hace quack, ni vuela al nacer, pero en su adultez si lo hará, por lo que debemos hacer que en tiempo de ejecución su comportamiento pueda cambiar a que si pueda volar y hacer quack. Esto lo podemos resolver con un nuevo método setFlyBehavior(FlyingBehavior fb) y setQuackBehavior(QuackingBehavior qb) de tipo setter que nos permita asignar un nuevo comportamiento.
¡FELICIDADES! Ahora ya sabes cómo diseñar el Patrón Strategy y así es como el juego de patos de Joe se resolverá y tendrá éxito. Como premio te mostraremos cómo quedó el diseño y te mostraré el código (by @juanitodread) para que lo puedas ver, probar, extender, etc. ¡Disfrútalo!
Strategy Pattern in Duck Game of Joe. 

Y aquí el código en el repositoro de github de StrategyPattern.

¿Entendiste el patrón?, ¿Tienes dudas?, no olvides preguntar, comentar, sugerir o corregir algo si lo deseas, con gusto responderé a cualquiera de tus comentarios.
Espero les sea de utilidad y puedan aprender algo nuevo con esta serie de posts, esperen muy pronto el siguiente. ¡Saludos!

Categories

Seguidores

MarceStarlet. Con la tecnología de Blogger.
Powered By Blogger