Programación https://sg.com.mx/ en JavaScript y Herencia Basada en Prototipos https://sg.com.mx/revista/51/javascript-y-herencia-basada-en-prototipos <span class="field field--name-title field--type-string field--label-hidden">JavaScript y Herencia Basada en Prototipos</span> <div class="images-container clearfix"> <div class="image-preview clearfix"> <div class="image-wrapper clearfix"> <div class="field field--name-field-image field--type-image field--label-hidden field__item"> <img src="/sites/default/files/images/js.png" width="785" height="340" alt="" loading="lazy" typeof="foaf:Image" /> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><a title="View user profile." href="/user/1" lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="" class="username">sg</a></span> <span class="field field--name-created field--type-created field--label-hidden">Sat, 07/02/2016 - 19:39</span> <div class="field field--name-field-numrevista field--type-entity-reference field--label-inline field--entity-reference-target-type-taxonomy-term clearfix"> <h3 class="field__label inline">Publicado en</h3> <ul class='links field__items'> <li><a href="/revista/51" hreflang="und">SG #51</a></li> </ul> </div> <div class="field field--name-field-seccion field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix"> <ul class='links field__items'> <li><a href="/revista/secciones/programacion" hreflang="und">Programación</a></li> </ul> </div> <div class="text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p dir="ltr">Para los programadores que vienen de lenguajes basados en clases, como Java o Ruby, JavaScript puede ser un poco confuso.</p> <p dir="ltr">A diferencia de estos lenguajes, Javascript es dinámico y no provee una implementación de clase como tal. Para soportar herencia, JavaScript solo tiene un constructo: Object. Cada objeto tiene una referencia a otro objeto, llamado su prototipo.</p> <p dir="ltr">Aunque esto pueda parecer una debilidad, en realidad este modelo de herencia basada en prototipos es muy poderoso. En este artículo explicaremos como funciona la herencia en JavaScript y la cadena de prototipos.</p> <h3 dir="ltr">Herencia de propiedades</h3> <p dir="ltr">Los objetos en JavaScript no son más que estructuras de datos con varias propiedades. Cada objeto tiene una referencia a su objeto padre, o prototipo.</p> <p dir="ltr">Al intentar acceder una propiedad en un objeto, la propiedad se busca primero en el objeto, y si no se encuentra se procede a buscar la propiedad en el prototipo del objeto original, y si no se encuentra se busca en el prototipo del prototipo, y así subsecuentemente hasta que se encuentre la propiedad o se llegue al final de la cadena.</p> <p dir="ltr">El listado 1 muestra un ejemplo de este caso.</p> <p dir="ltr"><script type="text/javascript" src="https://gist.github.com/pedrogk/918c4ce124f1afcb5bc60d35171e1d92.js"></script></p> <p dir="ltr">Listado 1. Herencia de propiedades.</p> <h3 dir="ltr">Herencia de “métodos”</h3> <p dir="ltr">En realidad, Javascript no tiene métodos como los de los lenguajes de programación basados en clases. En JavaScript, cualquier función se puede agregar a un objeto como si fuera una propiedad. Estos objetos, y sus respectivas propiedades se asemejan a los pares llave-valor de un Hash.</p> <p dir="ltr"><script type="text/javascript" src="https://gist.github.com/pedrogk/3bcff533da986225b86fb6008a45e443.js"></script></p> <p dir="ltr">Listado 2. Función como propiedad.</p> <p dir="ltr">Como podemos ver, el objeto o tiene dos propiedades: a con el valor 2 y m con valor function(b), que regresa el valor de la propiedad a + 1, que en este caso equivaldría a 3.</p> <p dir="ltr">Ahora vamos a extender el código anterior para mostrar cómo funciona la herencia basada en prototipos cuando la combinamos con funciones.</p> <p dir="ltr"><script type="text/javascript" src="https://gist.github.com/pedrogk/5fce53de844cbc6f2ec13857d46fbd58.js"></script></p> <p dir="ltr">Listado 3. Ejemplo extendido.</p> <p dir="ltr">Como puedes ver, el valor de ‘this’ apunta al objeto heredado, a partir de ahí busca las propiedades. Como en el objeto p se encuentra que a = 12, no es necesario seguir recorriendo la cadena de herencia.</p> <p dir="ltr">Ahora que entendemos cómo funciona la herencia basada en prototipos, consideremos cómo funcionan los arreglos en JavaScript. Consideremos el siguiente arreglo:</p> <p dir="ltr">var a = [“hola”, “qué onda”, “?”]</p> <p dir="ltr">Todos los arreglos en JavaScript heredan de Array.prototype. Es a este nivel donde están definidos métodos como indexOf, forEach, etcétera. La cadena de prototipo es a -&gt; Array.prototype -&gt; Object.prototype -&gt; null.</p> <h3 dir="ltr">Clases en ES6</h3> <p dir="ltr">Posiblemente estés enterado de que una de las novedades en EcmaScript 6 es que soporta clases y te preguntes cómo afecta a lo que hemos visto aquí. En realidad, lo único que se ha agregado en ES6 es que se soporta sintaxis similar a la de otros lenguajes basados en clases usando keywords como class, extends y super, pero internamente el comportamiento es el mismo que ya estudiamos en este artículo. El listado 4 muestra el ejemplo de una clase y una subclase usando sintaxis de ES6.</p> <p dir="ltr"><script type="text/javascript" src="https://gist.github.com/pedrogk/8f437c4c095c4263ae5255f19fd7dd37.js"></script></p> <p dir="ltr">Listado 4. Definición de clases con sintaxis de ES6</p> <h3 dir="ltr">Conclusión</h3> <p dir="ltr">Entender cómo funciona la herencia basada en prototipos es clave para poder hacer programación avanzada en JavaScript. Esperamos que estos ejemplos te hayan sido de ayuda.</p> </div> <div class="text-formatted field field--name-field-autor-bio field--type-text-long field--label-above"> <div class="field__label">Bio</div> <div class="field__item"><p dir="ltr" style="line-height: 1.38; margin-top: 10pt; margin-bottom: 10pt;">&nbsp;</p> <p>&nbsp;</p> </div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> </section> Sun, 03 Jul 2016 00:39:44 +0000 sg 6533 at https://sg.com.mx https://sg.com.mx/revista/51/javascript-y-herencia-basada-en-prototipos#comments Cuadrados Mágicos y Recursión https://sg.com.mx/revista/49/cuadrados-magicos-y-recursion <span class="field field--name-title field--type-string field--label-hidden">Cuadrados Mágicos y Recursión</span> <div class="images-container clearfix"> <div class="image-preview clearfix"> <div class="image-wrapper clearfix"> <div class="field field--name-field-image field--type-image field--label-hidden field__item"> <img src="/sites/default/files/images/melancholia_I.jpg" width="3146" height="1842" alt="" loading="lazy" typeof="foaf:Image" /> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><a title="View user profile." href="/user/1" lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="" class="username">sg</a></span> <span class="field field--name-created field--type-created field--label-hidden">Tue, 12/22/2015 - 20:53</span> <div class="field field--name-field-numrevista field--type-entity-reference field--label-inline field--entity-reference-target-type-taxonomy-term clearfix"> <h3 class="field__label inline">Publicado en</h3> <ul class='links field__items'> <li><a href="/revista/49" hreflang="und">SG #49</a></li> </ul> </div> <div class="field field--name-field-seccion field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix"> <ul class='links field__items'> <li><a href="/revista/secciones/programacion" hreflang="und">Programación</a></li> </ul> </div> <div class="field field--name-field-autor field--type-entity-reference field--label-inline field--entity-reference-target-type-taxonomy-term clearfix"> <h3 class="field__label inline">Autor</h3> <ul class='links field__items'> <li><a href="/buzz/autores-sg/manuel-lopez-michelone" hreflang="und">Manuel López Michelone</a></li> </ul> </div> <div class="text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p dir="ltr">En las matemáticas hay muchos problemas que son básicamente recreativos. Uno de ellos es el de los cuadrados mágicos, en donde se trata de colocar números en una matriz de celdas de n x n, de forma tal que la suma de los números por columnas, filas y diagonales principales sea la misma, la constante mágica. Usualmente los números empleados para rellenar las casillas son consecutivos, de 1 a n², siendo n el número de columnas y filas del cuadrado mágico.</p><p dir="ltr">Estos cuadrados se conocen ya en la antigua China, desde el III milenio A.C. Hay también referencias a los mismos en las culturas india, egipcia, árabe y griega. Y aunque muchas veces se han asociado con cuestiones astrológicas o de índole mágico, la realidad es que es una simple recreación matemática que es interesante por sí misma.</p><p dir="ltr">El artista renacentista Alberto Durero, en su obra Melancolía I, incluye un cuadrado mágico de orden 4 (4x4 celdas), en donde la constante mágica es 34. La figura 1 tiene los valores de dicho cuadrado.</p><p><img src="/sites/default/files/images/stories/sg49/cuadrado.jpg" alt="" width="250" /></p><p>Figura 1. El cuadrado mágico de Durero.</p><p>Existen una serie de procedimientos para crear cuadrados mágicos de orden par o impar. Un ejercicio interesante es escribir un programa que siga estos procedimientos para generar cualquier cuadrado mágico. No obstante esto, la pregunta que surge es si se puede generar un cuadrado mágico a prueba y error, sin necesidad de conocer algoritmo alguno. La respuesta es: sí, y para ello lo mejor que podemos hacer es usar un lenguaje de programación al que se le den los datos correspondientes y el programa resuelva automáticamente lo que buscamos. Este tipo de lenguajes declarativos forman un paradigma diferente al de los lenguajes imperativos y Prolog es uno de los mejores ejemplos del mismo.</p><p>Prolog nació en los años 70 del siglo pasado, en la Universidad de Aix-Marseille I (Francia), ideado por dos estudiantes, Alain Colmerauer y Philippe Roussel. La primera versión del lenguaje se escribió en Algol 60 y era interpretado. Más tarde (1983), llegaría David H.D. Warren, quien habría desarrollado un compilador que traducía Prolog en una serie de instrucciones de una máquina virtual, la cual se denominó a la postre la Máquina Abstracta de Warren (también conocida como WAM - Warren Abstract Machine).</p><p>Los programas en Prolog se componen de cláusulas de Horn que constituyen reglas del tipo “modus ponendo ponens”, es decir, “si es verdad el antecedente, entonces es verdad el consecuente”. Básicamente Prolog usa hechos y reglas. Los hechos son verdades que son ciertas en el entorno de un programa y las reglas definen verdades cuando se cumplen una serie de hechos. Prolog se basa así, en inferencias lógicas. A manera de ejemplo, si me presentan a alguien que se llama Jorge Flores y yo encuentro un parecido con un amigo mío llamado Luis Flores, quizá mi cerebro haga automáticamente una inferencia y me nazca preguntarle a Jorge: “¿no tienes un hermano llamado Luis?”. Ese tipo de inferencias las puede hacer Prolog, como en el siguiente ejemplo:</p><p class="code">padre(juan, manuel). /* el padre de juan es manuel */<br />padre(pedro, manuel). /* el padre de pedro es manuel */<br />hermanos(X,Y) :- /* X y Y son hermanos si tienen el mismo padre */<br />&nbsp; padre(X,Z),<br />&nbsp; padre(Y,Z),<br />&nbsp; X&lt;&gt;Y,<br />&nbsp; write(X, “es hermano de “, Y).</p><p>La regla se lee de la siguiente manera: “X y Y son hermanos si: el padre de X es Z, y el padre de Y es Z, y X no es Y”. Nótese que no se dice en ninguna parte que pedro y juan son hermanos. Prolog, a través de la regla definida, llega a esa conclusión.</p><p>Es importante hacer la aclaración de que X no es Y, sino el programa reportaría que X es hermano de sí mismo.</p><p>Prolog resuelve todo a través de un motor de inferencias, también reconocido como algoritmo de Robinson (en honor al autor que publicó por primera vez el mecanismo en 1968). De esta manera y abreviando el asunto, en Prolog describimos el problema y el lenguaje nos da las soluciones a través de dos mecanismos: la recursión y el backtrack.</p><p>La recursión es simplemente llamarse a sí mismo. En términos de programación significa que una rutina se llame a sí misma hasta que cierta condición impida que se cicle eternamente.</p><p>El backtrack consiste en regresar sobre nuestros pasos si resulta que la solución hallada no cumple con nuestras expectativas. Un ejemplo simple de backtrack puede verse en el recorrer un laberinto. Caminamos dentro de éste hasta que topamos con pared. Si esto ocurre, entonces retrocedemos sobre nuestros pasos hasta encontrar la primera bifurcación posible. Seguimos este procedimiento hasta hallar la salida.</p><p>Regresando a los cuadrados mágicos, veamos la creación de un cuadrado mágico de orden 3. El listado 1 muestra código en Prolog que resuelve este problema. Todo consiste en describir las condiciones iniciales y las de frontera. Luego le pedimos a Prolog que nos dé las soluciones a través de probar todas las posibilidades exhaustivamente (el árbol solución).</p><script type="text/javascript" src="https://gist.github.com/pedrogk/d048d13308dc47a623a8.js"></script><p>Listado 1. Encontrar cuadrados mágicos con Prolog.</p><p>El código del listado 1 básicamente hace lo siguiente:</p><ul><li>Elegir 9 números (todos diferentes).</li><li>Hacer las combinaciones de dichos números —en las ecuaciones correspondientes— que entreguen un resultado R. Este resultado debe ser igual en todas las ecuaciones.</li><li>Si se logra esto, escríbase la solución.</li><li>Búsquese una nueva solución a través de backtrack (aplicando la instrucción fail).</li></ul><p>El algoritmo es no determinista, es decir, no sabemos de antemano cuál será el resultado de la ejecución y el sistema, a las mismas entradas, puede dar muchos resultados posibles.</p><p>La forma más sencilla de ejecutar este código es por medio de SWISH, que es un ambiente de ejecución de Prolog que funciona en el navegador web. Simplemente entra a&nbsp;<a href="http://swish.swi-prolog.org">http://swish.swi-prolog.org</a>, crea un programa nuevo, pega el código fuente y en la sección donde pones tu query teclea “cuadrado” y da clic a “Run”. El sistema comenzará a calcular e irá desplegando matrices conforme las encuentre.</p><p>Como verás, el programa en Prolog es relativamente compacto y simple de entender. Intenta hacer esto en otro lenguaje y verás que tendrás código más grande y complejo. Por otro lado, un inconveniente es que Prolog dista de ser un lenguaje eficiente. En este caso hicimos el cálculo de un cuadrado de un orden relativamente pequeño (3), pero conforme vayamos aumentando el orden, el consumo de memoria aumentará significativamente y podríamos agotarla. Sin embargo, lo importante en este caso es la posibilidad de que, dando solamente los hechos y reglas relevantes, el programa busque con el algoritmo de Robinson, todas las posibles soluciones.</p></div> <div class="text-formatted field field--name-field-autor-bio field--type-text-long field--label-above"> <div class="field__label">Bio</div> <div class="field__item"><p>Manuel López Michelone (@morsa) es Físico por la UNAM y maestro en Ciencias por la Universidad de Essex en el tema de Inteligencia Artificial. Ha sido columnista por muchos años en publicaciones de la industria del cómputo y ávido programador. Actualmente realiza su doctorado en ciencias de la computación en la UNAM. morsa@la-morsa.com</p></div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> </section> Wed, 23 Dec 2015 02:53:05 +0000 sg 6213 at https://sg.com.mx https://sg.com.mx/revista/49/cuadrados-magicos-y-recursion#comments Desarrollo de Sistemas Distribuidos https://sg.com.mx/revista/58/desarrollo-de-sistemas-distribuidos <span class="field field--name-title field--type-string field--label-hidden">Desarrollo de Sistemas Distribuidos</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><a title="View user profile." href="/user/72" lang="" about="/user/72" typeof="schema:Person" property="schema:name" datatype="" class="username">lasr21</a></span> <span class="field field--name-created field--type-created field--label-hidden">Fri, 09/25/2015 - 17:57</span> <div class="field field--name-field-numrevista field--type-entity-reference field--label-inline field--entity-reference-target-type-taxonomy-term clearfix"> <h3 class="field__label inline">Publicado en</h3> <ul class='links field__items'> <li><a href="/revista/48" hreflang="und">SG #48</a></li> </ul> </div> <div class="field field--name-field-seccion field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix"> <ul class='links field__items'> <li><a href="/revista/secciones/programacion" hreflang="und">Programación</a></li> </ul> </div> <div class="field field--name-field-autor field--type-entity-reference field--label-inline field--entity-reference-target-type-taxonomy-term clearfix"> <h3 class="field__label inline">Autor</h3> <ul class='links field__items'> <li><a href="/buzz/autores-sg/pedro-ramirez" hreflang="und">Pedro Ramírez</a></li> </ul> </div> <div class="text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p dir="ltr">Los buscadores de Google, World of Warcraft, Seti@Home, Bitcoin, Windows Azure tienen algo en común: son sistemas distribuidos. A pesar de utilizarse en sistemas con propósitos tan distintos, comparten ciertas características. En este artículo veremos la teoría y las bases para construir un sencillo motor de búsqueda distribuido.</p> <p dir="ltr">Antes de entrar de lleno a nuestro buscador, necesitamos conocer un poco de teoría para entender las características de este tipo de sistemas, así como lo necesario para construirlos.</p> <h3 dir="ltr">¿Qué es un sistema distribuido?</h3> <p dir="ltr">Un sistema distribuido es un sistema de software cuyos componentes están separados físicamente y conectados entre sí por una red de computadoras, se comunican y coordinan entre ellos pasando mensajes. Dichos componentes interactúan entre ellos para lograr una meta común.</p> <p dir="ltr">Las tres características principales de un sistema distribuido son:</p> <ol><li dir="ltr"> <p dir="ltr">Concurrencia de componentes: Los componentes pueden ejecutar sus acciones de manera concurrente e independiente.</p> </li> <li dir="ltr"> <p dir="ltr">No hay un reloj global: Los componentes (nodos) de un sistema distribuido no dependen de un reloj que sincronice o indique las acciones de los distintos nodos.</p> </li> <li dir="ltr"> <p dir="ltr">Falla independiente de componentes: La falla de un componente no afecta al resto de los componentes.</p> </li> </ol><p dir="ltr">Para comunicar los nodos de un sistema distribuido es necesario un middleware; es decir, un software que proporciona un enlace entre programas independientes. Hay distintos tipos de middleware, pero en este caso nos enfocaremos en middleware orientado a mensajes (MOM). Los dos modelos de mensajeo más comunes y soportados por la mayoría de los sistemas de mensajeo son:</p> <ul><li dir="ltr"> <p dir="ltr">Publish-Subscribe (pub/sub) – Los emisores (publishers) no envían mensajes directamente a receptores (suscriptores) específicos, sino que simplemente etiquetan su mensaje con una o más categorías y lo publican, ignorando si hay o no suscriptores recibiendo los mensajes de dicha(s) categoría(s). De manera similar, los suscriptores se suscriben a categorías ignorando si hay emisores publicando mensajes en ellas.</p> </li> <li dir="ltr"> <p dir="ltr">Cola de Mensajes: El publicador envía mensajes a una cola donde son guardados hasta que el receptor los recibe, los mensajes pueden expirar después de cierto tiempo. A diferencia de publish–subscribe, en la cola de mensajes el receptor del mensaje activamente tiene que ir a la cola y buscar por nuevos mensajes.</p> </li> </ul><p dir="ltr">Nuestro motor de búsqueda usará el patrón publish–subscribe. La principal ventaja de este modelo es que genera bajo acoplamiento, ya que los publicadores y suscriptores no necesitan conocer la existencia unos de otros, y por lo tanto pueden operar independientemente. Al tener bajo acoplamiento, este modelo es más fácil de escalar horizontalmente. En cuanto a las desventajas del modelo, hay que tener en cuenta que nos obliga a tener bien definida la estructura de datos a publicar, y que los suscriptores tengan conocimiento de ella. Es así que si cambia la estructura de datos, hay que modificar tanto al publicador como al subscriptor. Mantener compatibilidad con distintas versiones no es fácil, es más sencillo lanzar nuevos eventos que usen las nuevas versiones de la estructura de datos y crear nuevos subscriptores que escuchen a dichos eventos. Otro inconveniente a tener en cuenta es que dado que el publicador no sabe si hay o no subscriptores, el middleware que distribuye los mensajes debe tener mecanismos que garanticen, en la medida de lo posible, la entrega de dichos mensajes.</p> <h3>El motor de búsqueda</h3> <p dir="ltr">El objetivo de este artículo es plantear y resolver un escenario sencillo que pueda ser usado como base para desarrollar un buscador más robusto o incluso cualquier sistema distribuido. Siendo así, nuestro motor de búsqueda se encargará de buscar una palabra en archivos de texto que estén localizados en distintas computadoras. Desde una aplicación web publicaremos eventos para lanzar la búsqueda, distintos nodos estarán escuchando por esos eventos y buscarán dicha palabra en el contenido de todos los archivos de texto en una ruta específica; como resultado, los nodos regresarán el nombre del archivo donde encontró la palabra y el número de línea donde fue encontrado. La figura 1 ilustra el comportamiento del buscador. El proceso es el siguiente:</p> <ol><li dir="ltr"> <p dir="ltr">El browser publica un evento de búsqueda con el término a buscar.</p> </li> <li dir="ltr"> <p dir="ltr">El middleware informa a los suscriptores el evento de búsqueda les envía el término a buscar.</p> </li> <li dir="ltr"> <p dir="ltr">Cada suscriptor itera sobre los archivos de texto locales buscando el término.</p> </li> <li dir="ltr"> <p dir="ltr">Cada suscriptor publica un evento con los resultados de su búsqueda.</p> </li> <li dir="ltr"> <p dir="ltr">El browser a su vez, es suscriptor del evento “resultados”, así que por cada conjunto de resultados el middleware le avisa al browser y le provee dichos resultados.</p> </li> </ol><img alt="Figura 1" data-entity-type="file" data-entity-uuid="27e6e680-03d8-4981-adf2-577e1596d613" src="/sites/default/files/inline-images/sg48-programacion-figura1.png" class="align-center" width="700" height="458" loading="lazy" /><p>Figura 1.</p> <p dir="ltr">Siendo que cada nodo es independiente, que no necesitan sincronizarse entre ellos con un reloj y que las búsquedas en cada nodo pueden ejecutarse de manera simultánea, nuestro motor de búsqueda cumple con las tres características principales de un sistema distribuido.</p> <h3 dir="ltr">DiPS como middleware</h3> <p dir="ltr">Antes de empezar a desarrollar el motor de búsqueda debemos escoger el middleware que usaremos. Hay varias opciones como RabbitMQ, Websphere MQ, Microsoft Message Queue Server, todos ellos muy conocidos y estables pero basados en colas (queues). Nosotros queremos queremos usar el patrón publish–subscribe por lo que usaremos un servicio que aún está en fase alpha llamado DiPS (Distributed Publish Subscribe), que se puede descargar en <a href="http://pedro-ramirez-suarez.github.io/DiPS/">http://pedro-ramirez-suarez.github.io/DiPS/</a></p> <p dir="ltr">Otra razón por la que usaremos DiPS, es porque hay clientes disponibles para .Net (100% compatible con Mono), Javascript y Ruby. Desarrollaremos nodos buscadores en .Net y en Ruby.</p> <p dir="ltr">Conectarse con DiPS es muy sencillo:</p> <script src="https://gist.github.com/pedro-ramirez-suarez/00c1525f5d19bfe565f1.js"></script><p dir="ltr">Listado 1. Conexión a DiPS</p> <h3 dir="ltr">Desarrollando el buscador</h3> <p dir="ltr">Habiendo elegido el middleware a usar, necesitamos definir los distintos componentes que debemos implementar como parte de nuestra solución. El listado 2 muestra los distintos pedazos de código que utilizaremos.</p> <script src="https://gist.github.com/pedro-ramirez-suarez/6655b7df8d4383aed40a.js"></script><ul dir="ltr"><li>Lo primero que necesitamos es definir las entidades que representen los datos de nuestro término de búsqueda, así como los resultados de dicha búsqueda. Para esto usaremos las clases SearchWord y SearchWordResult. La primera representa el término de búsqueda y la segunda representa una ocurrencia encontrada del término en cuestión, indicando en qué documento y línea se encontró la palabra, así como el texto de dicha línea. Un agente de búsqueda regresaría una lista con 0 a n elementos de esta entidad.</li> <li>A continuación requerimos definir el código de los suscriptores. Es decir, los agentes que reciben una petición de búsqueda, la ejecutan y regresan una lista de resultados. Program.cs muestra el esqueleto del código que usaría un suscriptor para recibir una petición de búsqueda y realizarla localmente.  </li> <li>El último paso es desplegar los resultados en un navegador web los resultados de los distintos suscriptores (que al enviar resultados se convierten en publicadores). Index.cshtml muestra un ejemplo en ASP.Net de cómo se podrían recibir y desplegar dichos resultados.</li> </ul><p> </p> <p dir="ltr">Todo el código fuente del motor de búsqueda, así como otros ejemplos de cómo usar DiPS para desarrollar un chat o el back end de una aplicación web pueden encontrarse en <a href="https://github.com/pedro-ramirez-suarez/DiPSClientSample">https://github.com/pedro-ramirez-suarez/DiPSClientSample</a>  </p> <p> </p> <p dir="ltr">Adicionalmente, en <a href="https://www.youtube.com/watch?v=2rrBOsE61ZE">https://www.youtube.com/watch?v=2rrBOsE61ZE</a> pueden ver una demostración de cómo funciona.</p> <h3 dir="ltr">Puntos a mejorar</h3> <p dir="ltr">Los resultados de cada nodo podrían primero preprocesarse antes de ser enviados al proceso que lanzó la búsqueda. De esta manera podríamos hacer cosas como ordenarlos alfabéticamente o por alguna otra clasificación. El motor de búsqueda tampoco implementa un modelo de programación MapReduce, ni organiza, mantiene o busca  el contenido de los archivos de texto de manera que las búsquedas sean más eficientes.</p> <p dir="ltr">DiPS está bien para experimentar y aprender, pero aún no es un servicio maduro, no recomendaría usarlo en aplicaciones críticas.</p> <p dir="ltr">Lo que aprendimos aquí, podemos aplicarlo a cualquier tipo de sistema distribuido, solo es cuestión de separar la funcionalidad en componentes que puedan correr de manera independiente, por ejemplo, podríamos desarrollar un PaaS creando componentes que administren y monitoreen bases de datos, otros para administrar y monitorear servidores web, dns, etc., para resolver problemas científicos que requieran mucho poder de cálculo, podríamos separar los datos y los cálculos necesarios en distintos procesos que correrían en distintos nodos. Una vez que aprendemos las bases y empezamos a pensar desde el punto de vista de un sistema distribuido, empezamos a ver muchas oportunidades de aplicación.</p> </div> <div class="text-formatted field field--name-field-autor-bio field--type-text-long field--label-above"> <div class="field__label">Bio</div> <div class="field__item"><p dir="ltr" style="line-height: 1.38; margin-top: 10pt; margin-bottom: 10pt;"><span style="font-size: 14.666666666666666px; font-family: 'Open Sans'; color: #000000; background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline;">Chief Architect en Scio Consulting, líder y colaborador en varios proyectos open source en distintos lenguajes, siempre aprendiendo y buscando nuevas formas de usar la tecnología. </span><a href="https://github.com/pedro-ramirez-suarez" style="text-decoration: none;"><span style="font-size: 14.666666666666666px; font-family: 'Open Sans'; color: #1155cc; background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: underline; vertical-align: baseline;">https://github.com/pedro-ramirez-suarez</span></a><span style="font-size: 14.666666666666666px; font-family: 'Open Sans'; color: #000000; background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline;"> &nbsp;&nbsp;</span><a href="mailto:pramirez@sciodev.com" style="text-decoration: none;"><span style="font-size: 14.666666666666666px; font-family: 'Open Sans'; color: #1155cc; background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: underline; vertical-align: baseline;">pramirez@sciodev.com</span></a><span style="font-size: 14.666666666666666px; font-family: 'Open Sans'; color: #000000; background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline;">&nbsp; </span></p> </div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> </section> Fri, 25 Sep 2015 22:57:30 +0000 lasr21 6109 at https://sg.com.mx https://sg.com.mx/revista/58/desarrollo-de-sistemas-distribuidos#comments Visualización de Datos con D3.js https://sg.com.mx/revista/40/visualizaci%C3%B3n-datos-d3js <span class="field field--name-title field--type-string field--label-hidden">Visualización de Datos con D3.js</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><a title="View user profile." href="/user/72" lang="" about="/user/72" typeof="schema:Person" property="schema:name" datatype="" class="username">lasr21</a></span> <span class="field field--name-created field--type-created field--label-hidden">Tue, 06/11/2013 - 12:31</span> <div class="field field--name-field-numrevista field--type-entity-reference field--label-inline field--entity-reference-target-type-taxonomy-term clearfix"> <h3 class="field__label inline">Publicado en</h3> <ul class='links field__items'> <li><a href="/revista/40" hreflang="und">SG #40</a></li> </ul> </div> <div class="field field--name-field-seccion field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix"> <ul class='links field__items'> <li><a href="/revista/secciones/programacion" hreflang="und">Programación</a></li> </ul> </div> <div class="text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Uno de los pasos más importantes cuando se realiza un análisis de datos es la exploración. En esta fase se detectan errores, se verifican los supuestos y se seleccionan modelos predictivos adecuados dependiendo de los datos. Este proceso de análisis exploratorio de datos se puede realizar con métodos estadísticos o con visualización.</p> <p> Existen varias herramientas que facilitan la visualización de datos. Mientras algunas son provistas por lenguajes de programación como Python o R, otras son de uso general y orientado al web como Flot, Raphael.js o D3.js.</p> <p> D3 (Data-Driven Documents) [1] es una librería JavaScript para presentar y manipular visualmente documentos basados en datos. Con D3 podemos crear desde gráficas sencillas como barras e histogramas, hasta visualizaciones complejas e interactivas. D3 utiliza las tecnologías estándar como HTML, SVG y CSS, por lo que funciona en cualquier navegador web moderno.</p> <p> En este artículo mostraré cómo hacer tus primeras visualizaciones con D3. El código usado para este tutorial está disponible en <a href="https://github.com/hmcuesta/SG40">https://github.com/hmcuesta/SG40</a> por si quieres descargarlo y probarlo.</p> <h4>Gráfica de barras</h4> <p>Nuestra primera visualización será una gráfica de barras que muestre la cantidad de pelotas de colores en una tómbola. Los datos los obtendremos de un archivo separado por tabuladores tombola.tsv que contiene los siguientes valores:</p> <p> <code><br /> Color Cantidad<br /> Rojo 2<br /> Azul 1<br /> Verde 4<br /> Amarillo 3<br /> </code></p> <p> Creamos el archivo Bar-Chart.html y comenzamos a editarlo. En el cuerpo del archivo HTML incluimos la librería de D3.<br /> <code>&lt;script src="http://d3js.org/d3.v3.min.js"&gt;</code></p> <p>Definimos el script que tendrá todo el código de nuestro ejemplo. Comenzamos configurando el área de trabajo (márgenes y tamaño) y los ejes horizontales y verticales.</p> <p> <code><br /> &lt;script&gt;<br /> var margin = {top: 20, right: 40, bottom: 20, left: 40},<br />  width = 700 - margin.left - margin.right,<br />  height = 350 - margin.top - margin.bottom;<br />  var x = d3.scale.ordinal().rangeRoundBands([0, width], .1);<br />  var y = d3.scale.linear().range([height, 0]);<br />  var xAxis = d3.svg.axis().scale(x).orient("bottom");<br />  var yAxis = d3.svg.axis().scale(y).orient("left");,\<br /> </code></p> <p> Definimos la variable svg que contendrá nuestra visualización.<br /> <code><br /> var svg = d3.select("body").append("svg")<br />  .attr("width", width + margin.left + margin.right)<br />  .attr("height", height + margin.top + margin.bottom)<br />  .append("g")<br />  .attr("transform", "translate(" + margin.left + "," + margin.top + ")")<br /> </code></p> <p> Ahora cargamos los datos de nuestro archivo tombola.tsv y mapeamos las columnas a atributos de nuestros objetos.<br /> <code><br /> d3.tsv("tombola.tsv", function(error, data) {<br />  data.forEach(function(d) {<br />   d.cantidad = +d.cantidad;<br />  });<br />  x.domain(data.map(function(d) { return d.color; }))<br />  y.domain([0, d3.max(data, function(d) { return d.cantidad; })]);<br /> </code></p> <p>  Nótese que en el caso del eje y, indicamos que el eje comienza en el valor 0 y llega hasta el valor más alto de la columna cantidad. Para obtener dicho valor utilizamos la función <code>d3.max()</code>. Ahora utilizamos la función svg.<code>append()</code> para agregar algunos elementos como las etiquetas de los ejes.<br /> <code><br /> svg.append("g")<br />  .attr("class", "x axis")<br />  .attr("transform", "translate(0," + height + ")")<br />  .call(xAxis);<br /> svg.append("g")<br />  .attr("class", "y axis")<br />  .call(yAxis)<br />  .append("text")<br />  .attr("transform", "rotate(-90)")<br />  .attr("y", 6)<br />  .attr("dy", ".7em")<br />  .style("text-anchor", "end")<br />  .text("Cantidad");<br /> </code></p> <p> Para configurar los distintos elementos de la visualización (en este caso, las barras) podemos utilizar el patrón de selección: selectAll + data + enter + append.<br /> <code><br /> svg.selectAll(".bar")<br />  .data(data)<br />  .enter().append("rect")<br />  .attr("class", "bar")<br />  .attr("x", function(d) { return x(d.color); })<br />  .attr("width", x.rangeBand())<br />  .attr("y", function(d) { return y(d.cantidad); })<br />  .attr("height", function(d) { return height - y(d.cantidad); });<br /> });<br /> &lt;/script&gt;<br /> </code></p> <p> Podemos agregar algo de CSS para estilizar un poco nuestra gráfica.<br /> <code><br /> &lt;style&gt;<br /> body { font: 16px sans-serif; }<br /> .bar { fill: #00a0e0; }<br /> &lt;/style&gt;<br /> </code></p> <p>La figura 1 muestra la gráfica que generamos.</p> <p><strong>Figura 1.</strong> Visualización de gráfica de barras.</p> <h4>Ejemplo con dos dimensiones</h4> <p> En el siguiente ejemplo trabajaremos con dos dimensiones en grupo de pares de coordenadas. Utilizaremos un arreglo bidimensional como el siguiente:<br /> <code><br /> var datos = [<br />  [50, 160],<br />  [20, 20],<br />  [70, 320],<br />  [540, 380],<br />  [200, 200],<br />  [640, 80],<br />  [300, 50],<br />  [350, 260]<br /> ];<br /> </code></p> <p> Creamos el área de trabajo con la función d3.select y establecemos el tamaño del área.<br /> <code><br /> var svg = d3.select("body")<br />  .append("svg")<br />  .attr("width", 600)<br />  .attr("height",400);<br /> </code></p> <p> Agregamos al gráfico los puntos del arreglo datos, indicando un radio de 20px.<br /> <code><br /> svg.selectAll("circle")<br />  .data(datos)<br />  .enter()<br />  .append("circle")<br />  .attr("cx", function(d) { return d[0]; })<br />  .attr("cy", function(d) { return d[1]; })<br />  .attr("r", function(d) { return 20; })<br />  .attr("fill", "#e02000");<br /> </code></p> <p>  Agregamos las etiquetas con los valores para cada punto y establecemos el estilo de la tipografía.<br /> <code><br /> svg.selectAll("text")<br />  .data(datos)<br />  .enter()<br />  .append("text")<br />  .text(function(d) { return d[0] + "," + d[1]; })<br />  .attr("x", function(d) { return d[0]; })<br />  .attr("y", function(d) { return d[1]; })<br />  .attr("font-family", "sans-serif")<br />  .attr("font-size", "14px")<br />  .attr("fill", "black");<br /> </code></p> <p>La Figura 2 muestra el mapa de coordenadas.</p> <p><strong>Figura 2.</strong> Visualización de scatter plot</p> <h4>Conclusión </h4> <p>Como podemos apreciar, D3 nos ofrece una forma simple de generar diferentes tipos de visualizaciones. Su uso de orígenes de datos diversos lo hacen perfecto para bases de datos orientadas a documentos como MongoDB.</p> <p> Si bien la visualización nos ofrece posibilidades de comunicación y abstracción de información, esta no debe de ser sustituto de métodos predictivos o estadísticos de análisis, ya que muchas veces se pueden dar falsas correlaciones cuando el humano usa su percepción. El objetivo de la visualización debe de ser de carácter exploratorio de datos y de comunicación de información ya analizada. La visualización es una forma muy útil de presentar grandes cantidades de información al usuario final.</p> <p><strong>Referencias </strong><br /> [1] N. Yau. Visualize This: The FlowingData Guide to Design, Visualization, and Statistics. Wiley, 2011. <a href="http://swgu.ru/sg40r15 ">http://swgu.ru/sg40r15 </a><br /> [2] S. Murray. Interactive Data Visualization for the Web. O’Reilly, 2013. <a href="http://swgu.ru/sg40r16">http://swgu.ru/sg40r16</a></p> </div> <div class="text-formatted field field--name-field-autor-bio field--type-text-long field--label-above"> <div class="field__label">Bio</div> <div class="field__item"><strong>Hector Cuesta-Arvizu</strong> (<a href="https://twitter.com/hmcuesta">@hmcuesta</a>) provee servicios de consultoría en Ingeniería de Software y Análisis de Datos. Adicionalmente se desempeña como instructor para NYCE en certificaciones de Desarrollo e Ingeniería de Software. Cuenta con maestría en ciencias de la computación y ha sido Revisor Técnico en los libros “Raspberry Pi Networking Cookbook” y “Hadoop Operations and Cluster Management” para Packt Publishing. </div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> </section> Tue, 11 Jun 2013 17:31:52 +0000 lasr21 3980 at https://sg.com.mx https://sg.com.mx/revista/40/visualizaci%C3%B3n-datos-d3js#comments Disciplínate: Aplica prácticas de programación ágil https://sg.com.mx/revista/28/disciplinate-programacion-agil <span class="field field--name-title field--type-string field--label-hidden">Disciplínate: Aplica prácticas de programación ágil</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mon, 06/14/2010 - 18:02</span> <div class="field field--name-field-numrevista field--type-entity-reference field--label-inline field--entity-reference-target-type-taxonomy-term clearfix"> <h3 class="field__label inline">Publicado en</h3> <ul class='links field__items'> <li><a href="/revista/28" hreflang="und">SG #28</a></li> </ul> </div> <div class="field field--name-field-seccion field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix"> <ul class='links field__items'> <li><a href="/revista/secciones/programacion" hreflang="und">Programación</a></li> </ul> </div> <div class="text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><div align="justify"><em><strong>Nota del Editor</strong>: Este texto es una versión traducida y condensada del artículo “Programming Practices” disponible en http://www.versionone.com/Agile101/Programmer_Practices.asp. Ha sido traducido y reproducido por SG con el permiso de VersionOne, Inc.</em><br /> <br /> En un proyecto ágil, los programadores tienen una misión: entregar periódicamente (cada 2, 3 o 4 semanas dependiendo de la duración de las iteraciones) software que funcione y esté probado. Para lograr esto, los programadores requieren mantenerse ágiles tanto a sí mismos, como al código que generan. Esto requiere mucha disciplina. El código ágil es aquel que solamente implementa los requerimientos actuales, tiene pocos defectos y se basa en un diseño robusto que permite extenderlo fácilmente para incorporar requerimientos adicionales en futuras iteraciones. Un código ágil está factorizado adecuadamente, y bien protegido por pruebas unitarias. Entre los métodos ágiles, Extreme Programming (XP) es posiblemente el que entre en mayor detalle acerca de como los programadores pueden hacer código ágil. Cada vez es más común encontrar equipos ágiles que aunque no apliquen XP en su totalidad, sí apliquen al menos algunas prácticas de XP que tienen que ver con la forma de trabajar de los programadores.</div> <p>Dichas prácticas son:<br /> • Desarrollo dirigido por pruebas<br /> • Refactorización rigurosa y constante<br /> • Integración continua<br /> • Diseño simple<br /> • Programación en pares<br /> • Compartir una base de código entre los programadores<br /> • Adherirse a un estándar de programación<br /> • Un área de trabajo común</p> <p>Estudiémoslas en mayor detalle.</p> <h3>Desarrollo dirigido por pruebas</h3> <p>Tener pruebas unitarias para solamente algunas partes de nuestro código puede resultar en código de baja calidad. Por otro lado, cubrir el 100% no es muy práctico y resulta en baja productividad. Una cobertura de pruebas unitarias de entre 75% y 85% del código es típicamente considerada como óptima. Una excelente forma de lograr tener estos niveles de cobertura es aplicar el Test-First programming. Esta técnica consiste en que antes de que creemos el código para satisfacer un requerimiento, primero generemos pruebas unitarias automatizadas que validen dicho código. Tal acercamiento puede sentirse extraño en un principio, sin embargo es de gran utilidad. Pensemos en los escaladores de montañas que crean caminos al ir dejando anclas; hacer esto es mucho más tardado que simplemente escalar, pero será de gran utilidad para los próximas veces que se tome este camino. Para implementar esta técnica, típicamente se utiliza algun framework de la familia xUnit (Junit para Java, Nunit para C#, etcétera). Dichos frameworks facilitan la creación, ejecución y organización de pruebas unitarias. Otra ventaja es que la mayoría de los IDEs soportan estos frameworks. El desarrollo dirigido por pruebas (test driven development, TDD) es un caso especial de test-first programming que agrega el elemento del diseño continuo. Con TDD, el diseño del sistema no es restringido por un diseño estático en papel, sino que el diseño es continuamente retroalimentado por el proceso de creación de pruebas y código de producción. Conforme el código se refactoriza para simplificarlo y clarificarlo, es posible encontrar mejores métodos, clases y modelos que los que establece el diseño original. TDD se basa en la premisa de que no puedes determinar cual será el mejor diseño, hasta que estés implementando el código. Conforme te vas dando cuenta de qué funciona, y qué no, estás en el mejor momento para ajustar el diseño, mientras tienes las ideas frescas. Y para protegerte de que pudieras realizar cambios que afecten elementos ya implementados, estás protegido por tu conjunto de pruebas unitarias automatizadas.</p> <h3>Refactorización</h3> <p>La refactorización (refactoring) es el proceso de clarificar y simplificar el diseño de un código existente, sin cambiar su comportamiento. Esta actividad se realiza de forma continua. El código que no es continuamente refactorizado, se pudre. Dicha putrefacción se puede notar de distintas formas: demasiadas dependencias entre clases o paquetes, asignación incorrecta de responsabilidades en clases, duplicación de código, tan solo por nombrar algunas. Cada vez que cambiamos un código existente y no intentamos refactorizar, la putrefacción aumenta. Sin embargo, hay que estar conscientes de que la única forma de que sea sano y viable refactorizar de forma continua, es que contemos con una buena base de pruebas unitarias automatizadas. Si no somos capaces de ejecutar dichas pruebas cada que refactorizamos código, corremos el riesgo de estar introduciendo defectos sin darnos cuenta. El libro “Refactoring: Improving the Design of Existing Code” de Martin Fowler es una excelente guía que describe oportunidades de refactorización comunes, y distintas formas de resolverlas. Pero la refactorización no solo ocurre a nivel de<br /> código, sino que se puede llevar al nivel de patrones de diseño. En su libro “Refactoring to Patterns”, Joshua Kerievsky explica cómo hacer esto, así como su utilidad.</p> <p><br /> <strong>Integración continua</strong></p> <div align="justify">Los métodos tradicionales de desarrollo de software no indican cada cuando se debe integrar todo el código fuente de un proyecto y generar una versión ejecutable. Los programadores pueden trabajar por separado por horas, días o incluso semanas en un código sin darse cuenta de cuantos conflictos y defectos están generando. Como comentamos en un principio, los equipos ágiles requieren producir código ejecutable y robusto en cada iteración, por lo que si dejan la integración del código hasta el final de la iteración, se encuentran con un arduo proceso de resolución de conflictos y depuración de código. Ante esto, los equipos ágiles comúnmente escogen aplicar la integración continua. La integración continua involucra construir un ejecutable (build) del sistema varias veces al día, apoyándose en herramientas de gestión de la configuración (software configuration management). Los equipos ágiles típicamente configuran la integración continua para incluir compilación automática, ejecución de pruebas unitarias e integración de código fuente. Una regla popular de la integración continua establece que los programadores no dejen elementos sin integrar al final del día, es decir que no se pueden dejar builds rotos para el siguiente día. Adicionalmente se puede combinar esta regla con la de que el programador que “rompe” un build al hacer check-in es al que le toca arreglarlo, lo cual genera un incentivo natural para que los programadores hagan check-in frecuentemente durante el día.</div> <div align="justify">&nbsp;</div> <div align="justify"><strong>Diseño simple</strong></div> <div align="justify">Los equipos ágiles ponen gran valor en la extensibilidad de su código. Esto se refiere a qué tan fácil es mantenerlo y extenderlo. Ya discutimos lo importante que es la refactorización continua para tener código extendible. El otro elemento clave para esto es la simplicidad del diseño. La extensibilidad del código es inversamente proporcional a la complejidad del diseño. Parafraseando al poeta Wallace Stevens, un diseño simple significa: “el arte de lo que es suficiente”. Esto se traduce en programar para los requerimientos de hoy, y nada más. Sin embargo, esta no es una inclinación natural de nosotros los programadores. Es común que por querer utilizar las herramientas y tecnologías más novedosas, terminemos complicando nuestro diseño más de lo que deberíamos. Cualquier elemento extra que agregamos, es un lastre que debemos cargar a lo largo del proyecto. In Extreme Programming, se utiliza el término “You aren’t gonna need it” (YAGNI) para detectar esta situación. Las empresas que trabajan de forma ágil tienden a preferir contratar gente con experiencia en el arte de la extensibilidad y el diseño simple, por encima de aquellas con mayor conocimiento de las tecnologías.</div> <p><br /> <strong>Programación en pares</strong></p> <div align="justify">La programación en pares es claramente la más controversial de las técnicas de programación ágil. Esta técnica consiste en tener dos programadores trabajando en una sola computadora. Un programador “conduce” operando el teclado, mientras el otro “navega” observerando, aprendiendo, preguntando, y haciendo sugerencias. En teoría, el conductor se enfoca en el código que está haciendo (la sintáxis, semántica y algoritmos), y el navegador se enfoca en mayores niveles de abstracción (la prueba que están tratando de hacer pasar, los próximos pasos, la calidad del diseño en general). La teoría es que la programación en pares resulta en un mejor diseño, menos defectos, y una mayor difusión del conocimiento a través del equipo de trabajo. Los resultados de investigación reportan que al usar programación en pares la productividad puede disminuir en un 15% al corto plazo, pero como el código es mejor, la productividad al largo plazo se incrementa. Todo depende de cómo se mida la productividad, y en qué marco de tiempo. En un contexto ágil, la productividad típicamente se mide en base a características implementadas (y probadas) por iteración. Por otro lado, alguien que mida la productividad en base a líneas de código por semana, seguramente encontrará que se disminuye drásticamente con la programación en pares.Los beneficios de la programación en pares se incrementan si se considera un plazo<br /> suficientemente largo como para incluir la rotación de staff. Esto es porque la programación en pares mitiga el problema de que haya personas que sean “islas de conocimiento”, y que al abandonar un proyecto lo afecten significativamente. Al estar continuamente<br /> compartiendo el conocimiento dentro de un equipo, se reduce el impacto de la rotación. En Extreme Programming se utiliza el término “número de camiones” (truck number) para referirse al número de personas que tendrían que ser atropellados por un camión<br /> para que el proyecto tuviera que cancelarse, y XP busca que dicho número sea lo más cercano al número total de personas en el equipo. No es que no haya especialización entre los miembros del equipo, es solo que todos están enterados de qué es lo que está<br /> pasando, y por qué se hizo así.</div> <p><strong>&nbsp;</strong></p> <div align="justify"><strong>Adherirse a un estándar de programación</strong><br /> Si los programadores se adhieren a un mismo estándar de programación (incluyendo detalles como tabuladores vs. espacios, posicionamiento de corchetes, y nomenclatura de elementos), todo funciona mejor. Es más sencillo mantener y extender código, refactorizarlo, y reconciliar conflictos de integración, cuando se utiliza un mismo estándar a través de todo el código de un proyecto. No importa cual estándar se utilice, lo importante es adherirse a él.</div> <p><br /> <strong>Base de código común</strong></p> <div align="justify">Esta técnica se refiere a que todos, o al menos la mayoría, de los miembros del equipo compartan la misma base de código fuente. Esto solo es viable si se están aplicando otras técnicas como la integración continua y la adherencia a un estándar de programación. También sirve de mucho aplicar programación en pares. La principal ventaja de utilizar una base de código común es minimizar el impacto de la rotación de personal. Si todo el equipo utiliza una misma base de código y tiene una buena idea de en qué está trabajando cada quién, entonces es más fácil tanto quitar como agregar programadores al equipo. Esta práctica también facilita el tener un diseño consistente a lo largo de todo el proyecto.</div> <p>&nbsp;</p> <div align="justify"><strong>Un área de trabajo común</strong><br /> Durante la segunda guerra mundial, cuando Inglaterra se convenció de que necesitaba poder romper los complicados algoritmos criptográficos de los Nazis, ensamblaron un grupo con los mejores matemáticos y criptógrafos. Al hacer esto, no los pusieron en oficinas separadas para que trabajaran aislados, sino que los juntaron lo más posible, fomentando la interacción entre ellos. Este grupo estaba aislado del resto del mundo. Trabajaban, comían y dormían juntos. Fue de esta tumultuosa convergencia que surgieron ideas brillantes que los llevaron a construir las máquinas (computadoras) que hicieron posible descifrar los códigos Nazis. Se ha demostrado en repetidas ocasiones que los espacios de trabajo abiertos facilitan la comunicación en el equipo. Cuando un programador tiene una pregunta técnica, duda sobre algún requerimiento, o encuentra un conflicto de integración, cuenta con ayuda a la mano. Cuando las personas hablan entre sí exactamente en el momento que lo necesitan (en lugar de esperar a la próxima junta), los problemas se resuelven más rápido y mejor.</div> <p><br /> <strong>Conclusión</strong><br /> Invitamos a los equipos de desarrollo de software a adoptar las prácticas descritas en este artículo. Sin duda encontrarán que les permiten desarrollar mejor software de forma consistente.</p> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> </section> Mon, 14 Jun 2010 23:02:06 +0000 Anonymous 964 at https://sg.com.mx https://sg.com.mx/revista/28/disciplinate-programacion-agil#comments Programación Declarativa https://sg.com.mx/revista/24/programacion-declarativa <span class="field field--name-title field--type-string field--label-hidden">Programación Declarativa</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous</span></span> <span class="field field--name-created field--type-created field--label-hidden">Tue, 05/19/2009 - 11:17</span> <div class="field field--name-field-numrevista field--type-entity-reference field--label-inline field--entity-reference-target-type-taxonomy-term clearfix"> <h3 class="field__label inline">Publicado en</h3> <ul class='links field__items'> <li><a href="/revista/24" hreflang="und">SG #24</a></li> </ul> </div> <div class="field field--name-field-seccion field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix"> <ul class='links field__items'> <li><a href="/revista/secciones/programacion" hreflang="und">Programación</a></li> </ul> </div> <div class="field field--name-field-autor field--type-entity-reference field--label-inline field--entity-reference-target-type-taxonomy-term clearfix"> <h3 class="field__label inline">Autor</h3> <ul class='links field__items'> <li><a href="/author-speaker/gast-n-milano" hreflang="und">Gastón MIlano</a></li> </ul> </div> <div class="text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Si al escribir un programa de cómputo lo que hacemos es explicarle a la computadora por medio de instrucciones detalladas “cómo hay que realizar una tarea”, entonces estamos programando en forma imperativa. Es decir, estamos alimentando los pasos o conjunto de instrucciones necesarias para resolver un problema. Por otro lado, si al escribir un programa estamos describiendo “qué hay que hacer”, entonces estamos programando en forma declarativa. Es decir, describimos el problema que queremos solucionar, pero no las instrucciones necesarias para resolverlo. La programación declarativa es tan solo eso.</p><!--break--><p>En realidad, la programación declarativa es un término que agrupa los siguientes paradigmas de programación:</p><ul><li>Programación lógica. Los problemas se representan por medio de lógica matemática.</li><li>Programación funcional. Todo se resuelve por medio de la evaluación de funciones matemáticas.</li><li>Lenguajes de dominio específico (DSLs). Lenguajes descriptivos para un propósito específico, tales como HTML, CSS y SQL.</li><li>Lenguajes híbridos. Un ejemplo son los archivos “make” que combinan la descripción de dependencias entre componentes, con instrucciones imperativas para compilar o instalar una aplicación.</li></ul><h3>Ventajas de la programación declarativa</h3><p>Cuando pensamos en los beneficios de programar en forma declarativa, en general se empieza pensando en las ventajas propias del lenguaje a utilizar. Por ejemplo, si se está usando un lenguaje funcional, la principal ventaja es que al lidiar puramente con funciones, no necesitamos preocuparnos por el estado de la información, ya que los datos sean inmutables. Por otro lado, en el caso de los lenguajes basado en reglas, los programas son más claros y entendibles incluso por los usuarios.</p><p>A pesar de todo esto, la ventaja más importante de la programación declarativa consiste en que el indicar a la computadora“qué” tarea es la que tiene que hacer, en lugar de “cómo” hacerla nos protege de cambios en el contexto tecnológico. En ese sentido, el qué perdura mucho más que el cómo.</p><h3>Un primer ejemplo</h3><p>Veamos un ejemplo de cómo nos puede ayudar la programación declarativa. Supongamos un caso sencillo de un programa que suma los números del 1 al 100. Una posible solución procedural podría ser un programa similar al siguiente:</p><p><code>int suma = 0;<br /> for (int i = 1 to 100)<br />&nbsp;&nbsp;&nbsp; suma += i;<br /> return suma;</code></p><p>Una solución declarativa podría ser simplemente:</p><p><code>suma = Sum(1, 100)</code></p><p>Dado este ejemplo sencillo, lo primero que uno advierte es que se necesita un lenguaje de más alto nivel que dé soporte a las cosas que declaramos: en este caso alguien tiene que implementar el Sum, y el programador no tiene idea cómo se está resolviendo el proceso de la suma.</p><p>Hoy, luego de mucho tiempo, estamos frente al fenómeno de que la mejora en desempeño para una máquina no se da simplemente cambiando el procesador, sino que necesitamos sumar más procesadores. Ya muchas computadoras están equipadas con tecnología de cuádruple núcleo.</p><p>Aquellos programas como el que hace la suma imperativamente, deberá decir explícitamente (por ejemplo mediante el uso de threads) que necesita hacer uso de los nuevos procesadores. Sin embargo, el programa declarativo no cambia, será exactamente igual y la implementación de cómo se hace la suma es un tema de capas tecnológicas de más bajo nivel. Como desarrollador de aplicaciones de negocio, no quiero perder el foco de lo que quiero hacer y perderme en temas tales como threading, serialización y sincronización.</p><h3>Lenguajes declarativos</h3><p>Existen una gran cantidad de lenguajes declarativos. En el caso de los funcionales, entre los más populares están Scheme, Erlang, y otros más nuevos como F#. para cierto dominio específico. Los lenguajes de dominio específico comunmente son utilizados para declarar formulario, por ejemplo HTML, XAML, XUL e incluso las hojas de cálculo.</p><p>En Artech, la empresa donde laboro, tenemos un producto llamado GeneXus que permite crear aplicaciones de negocio utilizando programación declarativa. La herramienta utiliza lenguajes declarativos para el modelado de las entidades de negocio, la declaración de reglas de negocio, la especificación de formularios, y la exposición de datos.</p><h3>Conclusión</h3><p>Ahora, después de 20 años, los grandes de la industria comienzan a darse cuenta de los beneficios de programar en forma declarativa. Antes de su retiro de Microsoft, el propio Bill Gates aconsejó que “deberíamos estar haciendo las cosas en forma declarativa (…) no deberíamos estar escribiendo tanto código procedural”. Si queremos lograr un verdadero incremento de productividad, es importante que todos dentro de la comunidad del desarrollo de software nos demos cuenta que claramente debe existir un cambio de paradigma a la hora de programar.</p></div> <div class="text-formatted field field--name-field-autor-bio field--type-text-long field--label-above"> <div class="field__label">Bio</div> <div class="field__item"><p>Gastón Milano es un ingeniero uruguayo quien ha trabajado durante muchos años en el desarrollo de software utilizando lenguajes declarativos. Actualmente es Arquitecto de Software de Genexus una herramienta de generación de aplicaciones partiendo de conocimiento declarado.</p></div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> </section> Tue, 19 May 2009 16:17:07 +0000 Anonymous 785 at https://sg.com.mx https://sg.com.mx/revista/24/programacion-declarativa#comments J2ME: Desarrollo de aplicaciones para teléfonos celulares https://sg.com.mx/revista/05/j2me-desarrollo-aplicaciones-para-tel-fonos-celulares <span class="field field--name-title field--type-string field--label-hidden">J2ME: Desarrollo de aplicaciones para teléfonos celulares</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous</span></span> <span class="field field--name-created field--type-created field--label-hidden">Wed, 11/21/2007 - 17:17</span> <div class="field field--name-field-numrevista field--type-entity-reference field--label-inline field--entity-reference-target-type-taxonomy-term clearfix"> <h3 class="field__label inline">Publicado en</h3> <ul class='links field__items'> <li><a href="/revista/05" hreflang="und">SG #05</a></li> </ul> </div> <div class="field field--name-field-seccion field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix"> <ul class='links field__items'> <li><a href="/revista/secciones/programacion" hreflang="und">Programación</a></li> </ul> </div> <div class="field field--name-field-autor field--type-entity-reference field--label-inline field--entity-reference-target-type-taxonomy-term clearfix"> <h3 class="field__label inline">Autor</h3> <ul class='links field__items'> <li><a href="/buzz/autores/victor-quijano" hreflang="und">Víctor Quijano</a></li> </ul> </div> <div class="text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>En este artículo hablaremos de conceptos básicos de J2ME, la versión de Java para dispositivos móviles, y aprenderemos a hacer un “hola mundo”.</p><!--break--><p>Los dispositivos móviles están en todas partes, en particular los teléfonos celulares; tan simple como mirar a las personas en la calle, 4 de cada 10 tiene un teléfono celular. Gartner estima que en el 2005 se venderán 750 millones de unidades en todo el mundo, lo que significa un 13% de aumento respecto al 2004. Más que una evolución, es una explosión de dispositivos móviles.</p><p>Existen varios lenguajes (tecnologías) para programar teléfonos celulares, como BREW, Symbian C++, J2ME, etc. Para fines de este artículo vamos a experimentar con J2ME. La Tabla 1 muestra un pequeño listado de diferentes aparatos y sus capacidades.</p><h3><span class="subtitulo2">Ediciones de Java</span></h3><p>La plataforma Java está compuesta por tres ediciones distintas:<br /> • Java 2 Edición Empresarial (J2EE), para servidores empresariales y estaciones de trabajo que integran sus operaciones entre clientes, proveedores y empleados.<br /> • Java 2 Edición Estándar (J2SE), para su uso en computadoras personales y servidores.<br /> • Java 2 Edición Micro (J2ME), para dispositivos móviles.</p><p><img src="/images/stories/200505/programacion_1.gif" width="400" height="323" /></p><p><span class="pie_foto">Tabla 1. Ejemplos de capacidad en distintos teléfonos.<br /></span></p><h3><span class="subtitulo2">Conceptos básicos en J2ME</span></h3><p>¿Cómo puede correr Java en un refrigerador, en un celular, en un PDA? Para responder a esta pregunta se requiere explicar cuatro elementos importantes: (Ver Fig. 1)</p><p><img src="/sites/default/files/images/stories/200505/programacion_2.gif" width="250" height="149" /> <br /> <span class="pie_foto"> Figura 2. Configuraciones en J2ME. </span></p><ul><li>Sistema Operativo. Sistema que controla las funciones básicas del dispositivo, por lo general cerrado y propiedad del fabricante.</li><li>Maquina virtual (JVM). Java es un lenguaje interpretado que requiere de una máquina virtual, sin embargo, la JVM de un PDA no es la misma que un servidor corporativo, intervienen factores como el recolector de basura, el tamaño de la pila, entre otros.</li><li>Configuraciones. La configuración define el núcleo de J2ME (runtime environment) en la JVM. Se incluye un subconjunto de clases de la edición estándar de Java (J2SE), mas las clases específicas de J2ME por familias (dispositivos con características similares). (Ver Fig. 2).</li><li>Perfiles (profiles) - Son librerías de alto nivel que se agregan a la configuración o también por tipos de aplicación; los perfiles son específicos al tipo de dispositivo. Un perfil puede ser agregado a otro perfil. De ahí que los fabricantes como Nokia provean APIs de programación para sus modelos más recientes.</li></ul><p><img src="/sites/default/files/images/stories/200505/j2me-fig2.jpg" width="366" height="201" /></p><p>Figura 2. Configuraciones.</p><p>Al mencionar las siglas CLDC/MIDP nos referimos a la configuración (CLDC) y el perfil (MIDP) para programar aplicaciones Midlets en teléfonos celulares.</p><p>Existe una natural resistencia a programar Midlets. Por ejemplo, alguien puede decir “yo soy un programador Java de aplicaciones corporativas”, ¿cómo afecta al ciclo de desarrollo Java el uso de configuraciones y perfiles?</p><p>Las configuraciones aceptan archivos Java (.class) y JAR, la diferencia está en el compilador y la forma de compilar. El principal cambio es no usar la versión más reciente de Java; SUN recomienda JSDK 1.3 (sí, leyó usted bien); en sí, con Java 2 es suficiente. Recuerde que si maneja adecuadamente sus variables de ambiente, como JAVA_HOME, es posible tener varias versiones de JDK instaladas en una computadora.</p><h3><span class="subtitulo2">Hola Mundo Midlet</span></h3><p>Ahora vamos a hacer el ejemplo clásico, un hola mundo (HolaMidlet). El código lo vamos a comentar y razonar línea por línea.</p><p>Favor de verificar que tenga la versión 2 de Java instalado en su computadora (se probó con buenos resultados JSDK 1.4.2 para Windows). Luego se debe instalar la herramienta Wireless Toolkit 2.2 (WTK) de Sun. Una vez instalados, pruebe el buen funcionamiento al correr un proyecto demo (ej. Demo3D) con el programa Ktoolbar localizado en Inicio/Programas/J2ME Wireless Toolkit.</p><p>*Nota: Al momento de escribir este artículo ya estaba disponible la versión 2.3 beta, para los aventureros.</p><p><img src="/images/stories/200505/programacion_4.gif" width="400" height="309" /> <br /> <span class="pie_foto"> Figura 3. Ktoolbar.</span></p><p>En la figura 3 se observa que es un entorno bastante simple pero carece de un editor de texto. Para el ejemplo es suficiente NotePad. Este entorno está basado en proyectos, por lo que se requiere crear uno. A continuación, nos pedirá nombre del proyecto y clase principal para ejecutar nuestra aplicación. Los pasos en orden son:</p><ol><li>Crear un nuevo proyecto (New Project) o abrir uno existente (Open Project).</li><li>Configurar la aplicción Midlet (Preferences).</li><li>Compilar (Build).</li><li>Ejecutar (Build).</li><li>Empacar en archivos JAR y JAD (Project/Package/Create Package).</li></ol><p>*Nota: La mayoría de los equipos con MIDP 1.0 sólo soportan archivos JAR máximo 64K. Sin embargo, los equipos más recientes vienen con MIDP 2.0 y mayor capacidad de almacenamiento, algunos incluso utilizan tarjetas de ampliación de memoria.</p><p>La configuración es importante para distribuir la aplicación (Preferences en el paso 2), y son parte de la especificación del archivo JAD:</p><p><img src="/sites/default/files/images/stories/200505/programacion_5.gif" width="300" height="237" />&nbsp;<br /> <span class="pie_foto"> Tabla 2. Archivo JAD. </span></p><p>Las configuraciones opcionales son:</p><p><img src="/images/stories/200505/programacion_6.gif" width="300" height="295" /></p><p><span class="pie_foto">Tabla 3. Configuración en WTK.</span></p><p>Con la opción User Defined el usuario puede ingresar sus configuraciones personales o que dependan del equipo.</p><p>Al crear un proyecto, el WTK, también crea una estructura de directorios. En este caso en el directorio c:\WTK2.2\HelloMidlet con los siguientes subdirectorios:</p><p><img src="/sites/default/files/images/stories/200505/programacion_7.gif" width="300" height="199" /></p><p>Programar Midlets recuerda mucho a programar Applets, los cuales cayeron en desuso (mejor dicho, se perdió el gusto de programarlos).</p><p>Un MIDlet hereda o extiende la clase javax.microedition.midlet.MIDlet. Los métodos requeridos son:</p><ul><li>startApp - Inicia la aplicación.</li><li>pauseApp – Pausa la aplicación.</li><li>destroyApp – Destruye la aplicación, para que pueda ser eliminada de memoria.</li></ul><p>Como pueden ver, un Midlet incluso tiene un comportamiento más simple que el de un Applet (arranca, para y se detiene).</p><p>El siguiente código muestra el esqueleto mínimo de un MIDlet:</p><p><script type="text/javascript" src="https://gist.github.com/pedrogk/923f2053781935d3d7983ad0e20d8e42.js"></script></p><p>&nbsp;</p><p>El código anterior es un código zombie, camina pero no reacciona. Para corregir esto falta el manejo de eventos, lo cual requiere implementar la interface CommandListener y esto nos lleva a definir el método CommandAction().</p><p>Para hacer esto, agregamos el import correspondiente:</p><p><code>import javax.microedition.lcdui. CommandListener;</code></p><p>y modificamos la definición de la clase:</p><p><code>public class HolaMidlet extends MIDlet implements CommandListener {</code></p><p><span class="subtitulo2"> ¿Qué nos falta? Implementar el método CommandAction. </span></p><p><code>public void commandAction(Command c, Displayable s) <br /> { <br />&nbsp; if (c == cmdExit) {<br />&nbsp;&nbsp;&nbsp; destroyApp(false); <br />&nbsp;&nbsp;&nbsp; notifyDestroyed(); <br />&nbsp; }<br /> }</code></p><p>Para que esto funcione, es necesario importar las clases correspondientes a Command y Displayable.</p><p><code>import javax.microedition.lcdui.Command;<br /> import javax.microedition.lcdui.Displayable;</code></p><p>Así como definir la variable cmdExit, la cual representa al comando para el botón de salida (exit).</p><p><code>private Command cmdExit;</code></p><p>Ahora declaramos un objeto display, que utilizaremos como referencia a la pantalla. Primero importamos la clase correspondiente:</p><p><code>import javax.microedition.lcdui.Display;</code></p><p>y luego definimos la variable a nivel de clase:</p><p><code>private Display display;</code></p><p>En nuestro constructor vamos a inicializar el valor de los objetos display y cmdExit.</p><p><code>display = Display.getDisplay(this);<br /> cmdExit = new Command(“Salir”, Command.EXIT, 1);</code></p><p>La instancia de clase cmdExit muestra en pantalla la palabra “Salir” con la función de más alta prioridad (1) y que sea del tipo EXIT.</p><p>Falta agregar el texto “Hola mundo móvil”, lo cual haremos utilizando un objeto TextBox, que permite al usuario ingresar y editar texto.</p><p>Primero importamos la clase correspondiente</p><p><code>import javax.microedition.lcdui.TextBox;</code></p><p>y definimos el objeto</p><p><code>private TextBox tbxMain;</code></p><p>Posteriormente creamos la instancia de la clase TextBox, lo cual se hace indicando el título, texto de mensaje, y tamaño</p><p><code>tbxMain = new TextBox(“HelloMidlet”, “Hola Mundo Móvil”, 50, 0);</code></p><p>Por último agregamos el comando de salida, y preparamos al programa que esté al pendiente de este evento.</p><p><code>tbxMain.addCommand(cmdExit);<br /> tbxMain.setCommandListener(this);</code></p><p>Después de compilar la aplicación y generar el archivo JAR correspondiente, la forma más simple para instalarla en el dispositivo es usar un cable de datos, o transmisión inalámbrica (IR o bluetooth). Como recomendación final verifique las versiones de CLDC y MIDP de su teléfono para que pueda correr en su teléfono.</p><p>El listado final del código queda de la siguiente manera:</p><script type="text/javascript" src="https://gist.github.com/pedrogk/590c125f02da48dc115055a7f209658f.js"></script><p>&nbsp;</p><h3><span class="subtitulo2">Conclusión</span></h3><p>¿Por qué usar J2ME? Algunas ventajas reportadas:</p><ul><li>Es un estándar actual de la industria respaldado por Sun Microsystems.</li><li>Puede correr en el escritorio y en dispositivos móviles.</li><li>Continuas versiones de actualización a través de un comité JCP (Java Community Process).</li><li>APIs de desarrollo de terceros para nuevas características en los equipos de nueva generación.</li></ul><p>Sin embargo, J2ME también puede tener algunas desventajas, entre las cuales están:</p><ul><li>Es un lenguaje interpretado, una aplicación Midlet mal planeada puede ser lenta.</li><li>La memoria libre de cada teléfono y el tamaño máximo del archivo JAR/JAD.</li><li>Aritmética de punto flotante no implementada en versiones anteriores.</li></ul><p>Los Midlets han dejado de ser aplicaciones sólo para juegos, pasando por aplicaciones personales y ahora llegan al ambiente corporativo con acceso a bases de datos. J2ME es una tecnología madura. Lleva seis años de vida y se dice que lo mejor está por venir. ¿Usted qué opina?</p><p><strong>Referencias</strong></p><ol><li>“J2ME Building Blocks for Mobile Devices”. KVM and the CLDC. SUN. USA. 2000</li><li>“J2ME technology turns 5!”. http://developers.sun.com</li><li>Sun Java Wireless Toolkit http://java.sun.com/products/sjwtoolkit/</li><li>“Gartner Says Mobile Phone Sales Rose 17 percent ...”. http://www.gartner.com/press_releases/asset_127760_11.html</li><li>J2ME Polish: Device Database. http://www.j2mepolish.org/devices-overview.html</li></ol></div> <div class="text-formatted field field--name-field-autor-bio field--type-text-long field--label-above"> <div class="field__label">Bio</div> <div class="field__item"><p>Víctor Manuel Quijano Abán es candidato al grado en la maestría en sistemas computacionales, egresado del Instituto Tecnológico de Mérida. Actualmente trabaja en un corporativo de medios de comunicación y ha trabajado en centros de investigación, gobierno federal y conservación en medio ambiente. Empezó a programar antes de que aparecieran las primeras PCs y es aficionado a los lenguajes scripts y código multiplataforma.</p></div> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> </section> Wed, 21 Nov 2007 23:17:23 +0000 Anonymous 498 at https://sg.com.mx https://sg.com.mx/revista/05/j2me-desarrollo-aplicaciones-para-tel-fonos-celulares#comments El componente X. Generación de código con templates. https://sg.com.mx/articulos/el-componente-x-generacion-de-codigo-con-templates <span class="field field--name-title field--type-string field--label-hidden">El componente X. Generación de código con templates.</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous</span></span> <span class="field field--name-created field--type-created field--label-hidden">Thu, 11/15/2007 - 11:19</span> <div class="field field--name-field-numrevista field--type-entity-reference field--label-inline field--entity-reference-target-type-taxonomy-term clearfix"> <h3 class="field__label inline">Publicado en</h3> <ul class='links field__items'> <li><a href="/revista/03" hreflang="und">SG #03</a></li> </ul> </div> <div class="field field--name-field-seccion field--type-entity-reference field--label-hidden field--entity-reference-target-type-taxonomy-term clearfix"> <ul class='links field__items'> <li><a href="/revista/secciones/programacion" hreflang="und">Programación</a></li> </ul> </div> <div class="field field--name-field-autor field--type-entity-reference field--label-inline field--entity-reference-target-type-taxonomy-term clearfix"> <h3 class="field__label inline">Autor</h3> <ul class='links field__items'> <li><a href="/buzz/autores/victor-quijano" hreflang="und">Víctor Quijano</a></li> </ul> </div> <div class="text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>El siguiente trabajo es una introducción a la generación de código basado en la transformación de documentos XML con templates. Vamos a construir un generador de código de componentes para PHP como ejemplo. Se utilizan herramientas de código libre y pocos recursos de cómputo. Además se invita al lector a conocer un poco más sobre este tema, que ha cobrado actualidad aplicando nuevas técnicas de ingeniería de software.</p> <p>“Un generador de código es una técnica para escribir programas que escriben código fuente”. ¿Le recuerda algo lex y yacc?; éstos son ejemplos de generadores de código, pero antes que deje de leer por malos recuerdos (sí nunca terminó su compilador); le adelanto que ésta técnica difiere de la teória de compiladores, ya que no se requiere obtener código objeto, menos ensamblado.</p> <p>Un generador de código NO es un asistente de un editor de código tipo IDE; menos una solución mágica, no genera código listo para entregar al cliente. La idea es identificar qué parte del código es posible compartir (componentes), implementar una solución a problemas recurrentes (léase patrones de diseño), modelos de datos, interfases gráficas de usuario (GUI) y su comportamiento, entre otros ejemplos.</p> <p>Vamos a desarrollar un ejemplo sencillo, paso a paso, utilizando XML y transformación por templates.</p> <h3><span class="subtitulo2">XML y Familia</span></h3> <p>XML (eXtensible Markup Language) es un metalenguaje (un lenguaje para describir lenguajes) para definir tus propios elementos o partes de un documento. Ej. &lt;lenguaje = "natural"&gt;<lenguaje> </lenguaje></p> <p>XML fue creado por el World Wide Web Consortium (W3C) en 1998 para suplir deficiencias de HTML. En XML los elementos son definidos por el usuario con una especificación DTD (Document Type Definition). Actualmente XML es una familia de lenguajes y especificaciones adoptadas por la industria del software como un estándar abierto . Ver Fig. 1.</p> <p><img alt="" src="http://www.sg.com.mx/images/stories/200503/practicas_procesos_1.jpg" /><br /> <span class="pie_foto">Fig 1. Familia XML</span></p> <h3><span class="subtitulo2">Componentes y Lenguajes Script</span></h3> <p>Empezamos por definir un documento DTD. Éste contiene un conjunto de reglas para organizar los datos, en nuestro caso le llamaremos componentX, que tiene una estructura jerárquica. Ver Fig. 2</p> <p><img alt="" src="http://www.sg.com.mx/images/stories/200503/practicas_procesos_2.jpg" /> <span class="subtitulo2">Fig.2 ComponenteX</span></p> <p>Un DTD se escribe con sintaxis de XML y está compuesto por tags, elementos, atributos y texto. Todo documento XML tiene un elemento raíz (componentx en el ejemplo).</p> <p><code>&lt;!ELEMENT componentx (registration, implements, script)&gt;</code></p> <p>Cada ComponentX, a su vez, está formado por tres elementos: registration, implements y script.</p> <p><code>&lt;!ELEMENT registration (description, progid, version)&gt;</code></p> <p>El elemento registration tiene una descripción, un id de programa y una versión del componente.</p> </div> <section class="field field--name-comment field--type-comment field--label-above comment-wrapper"> </section> Thu, 15 Nov 2007 17:19:43 +0000 Anonymous 456 at https://sg.com.mx https://sg.com.mx/articulos/el-componente-x-generacion-de-codigo-con-templates#comments