Expresando la intención del sistema

Introducción: Como buen seguidor del blog del Maldo, leo sus posts en cuanto salen… los cuatro que hace en el año… y aunque en la encuesta contesté que tenía que dejar de escribir, no me hizo caso y algunos incluso le pidieron que siguiera escribiendo… Bueno, en cuestión de gustos no hay nada escrito… Para aminorar el daño, en una de las chácharas telefónicas rutinarias, le empecé a pelar el cable con la intencionalidad del sistema y la arquitectura, para que escribiera de cosas más apasionantes y le pusiera un poco más de color, pero como respuesta categórica solo obtuve un “escribelo vo po”. Oh drat! Tenía razón. Así que sin más preámbulo les dejo mi primer post para colaborar con el blog. Espero les guste.

Si consideramos que la arquitectura de software se define típicamente como la organización mayor de los elementos que componen un sistema, muchas veces sucede que el foco se centra en los detalles de implementación, los frameworks a utilizar, el stack de tecnología, entre otras. Se centra en cómo se presentará la aplicación, como se almacenarán los datos, incluso la elección del lenguaje de programación se convierte en un aspecto central. No cabe la menor duda de que todos estos detalles son importantes, pero, ¿que hay de la intención del sistema?

Robert Martin, mejor conocido como Uncle Bob hace un paseo muy interesante por el concepto que denomina Screaming Architecture, haciendo una analogía: imaginemos el plano de unas habitaciones, una cocina, un baño y un living comedor. La arquitectura grita “soy una casa”. Estoy de acuerdo de que con el diseño de un sistema debería suceder lo mismo. Sin embargo, no dejo de ver sistemas que lo que te muestran son Controllers, Views y Models; o DTO’s everywhere, o Data Layer, Business Layer, y Presentation Layer, etc. Todas estas cosas no te dicen nada en absoluto en cuanto a que diablos se trata de resolver. Es raro ver un sistema que con tan solo un vistazo puedes decir “esto es un sistema de inventario, o este es un sistema de venta de tickets. O este es un sistema para calcular que se yo… El diseño de un sistema debería hablar por sí mismo, expresando la intención del sistema, la solución de la problemática cual sea su razón de existir. El foco en el stack de tecnología o la organización del código no hace mas que desviar la atención del desarrollo en los detalles, introduciendo restricciones impuestas por estos mismos detalles de implementación.

Ahora bien, aún cuando nos concentremos en diferir al último momento responsable la decisión de aquellas variables arquitectónicas de mayor impacto, como una base de datos relacional, o un ORM específico, o un mecanismo de presentación tal o cual, concentrarse en el diseño del núcleo de la aplicación y capturar la mayor cantidad de conocimiento acerca del dominio del problema que se debe solucionar sigue siendo, en mi opinión, la parte más desafiante a la hora de desarrollar software. Hacer un cliente web, o una API REST, escribir un modelo de datos y un mecanismo de persistencia, es relativamente directo de realizar. Pero capturar la intención del sistema desacoplado de todos los detalles y dependencias que se situan en la periferia del sistema, y que solo prestan funciones específicas, es el verdadero desafío.

Conclusión: Una arquitectura exitosa es aquella que permite capturar, expresar, extender y ser flexible de cambiar la intención central del sistema, el denominado Dominio del problema, ganar conocimiento y aprender de este mismo (conocer mejor el negocio) y que permita diferir la decisión de aquellas variables arquitectónicas de mayor impacto hasta el último momento responsable. Cómo capturar esta intención es algo que me gustaría ir tratando en posts futuros.

Manténgase en línea. Cambio y fuera.

Disclaimer: Si disparé muchos balazos técnicos antes de explicarlos, ¡no desesperen!. La idea es no tirar toda la carne a la parrilla, para que tengamos más asados; tendremos mas posts para ir en breve por cada concepto. Y así, superamos los 4 posts al año del Maldo… ojalá sean 8

La Máquina Abstracta

Ya señores, a partir de la encuesta del post anterior, podemos obtener las siguientes conclusiones, por lo menos siete personas leen el blog, lo que me parece una audiencia más que amplia pensando que escribo poco y siempre escribo lo primero que se me ocurre, de esas siete personas solo una lee el blog atentamente, ya que solo una me pide que deje de escribir, y cuatro personas indican que quieren seguir con el tema de lenguajes de programación… no se por que … pero bueno… como resultado de eso otro post más con el apasionante tema de los lenguajes de programación.

Bueno antes de los lenguajes propiamente tal, definiremos la máquina abstracta, que nos va a servir para entender como funcionan o trabajan los lenguajes de programación en general. ¿Qué es la máquina abstracta?, es una máquina que sirve como simplificación de un computador real, se le llama máquina abstracta porque no necesariamente tiene que ser electrónica ni ser una computadora, podría ser completamente mecánica (lo que sería muy cool y muy steam punk… yo me compraría una), y tiene las separaciones de los diferentes niveles de abstracción que debe tener una máquina, en el diagrama que sigue se muestra una máquina abstracta básica.

Máquina Abstracta

Como vemos la máquina está separada en tres grandes grupos, el grupo de la memoria, el grupo del interprete y el grupo de las operaciones, cada uno de estos grupos cumple una función diferente.

El grupo de la memoria, en una máquina real se puede asociar con la memoria RAM, pero es una simplificación de una cadena de tecnologías, ya que en la realidad se implementan dentro de la CPU niveles de cache para hacer más rápida esta extracción de datos y espacios en la memoria RAM reservados especiales, pese a que es una simplificación, se puede separar conceptualmente en dos, Datos y Programas, en los datos, se almacenan los elementos que se usan en el programa, variables primitivas que se están usando para alguna operatoria, clases, variables encoladas, etc. en los programas se guardan las instrucciones mismas a ser ejecutadas, los programas, esto es porque debe quedar almacenado en algún lugar ya que no se pueden ejecutar todas las instrucciones al mismo tiempo.

El grupo del Interprete es el corazón de la máquina abstracta, en un hardware real sería la CPU, igual que en lo anterior es una simplificación de una cadena de tecnologías ya que en general las CPU modernas implementan pipeline y más de un core para realizar este conjunto de acciones, nuevamente pese a que se simplifica podemos separarlo esta vez en tres partes, el controlador de secuencia corresponde a la pieza que se dedica a controlar y manejar la secuencia en la que se ejecuta un programa dentro de la máquina abstracta, decide en base a las variables del programa mismo como se ejecutan las secuencias y los loops del programa, esta pieza hace uso del Controlador de Datos, que es un elemento especial que se dedica a representar en formato binario los datos usados en un programa, como por ejemplo la representación de una variable entera, una variable string o incluso una instrucción del programa mismo a ser ejecutada posteriormente, además de esto esta pieza trabaja en conjunto con el Manejador de memoria, que es el que se dedica a utilizar la memoria, tanto utilizando espacio como dejándolo disponible, es la pieza que trabaja directamente con la memoria, tanto para los datos guardados como para las instrucciones del programa, extrayendo y guardando en memoria esta información.

Por último el grupo de las operaciones, en CPU real debería corresponder a una ALU, que es el lugar donde se realizan las instrucciones básicas que deben ser realizadas a nivel de máquina.

En un programa completo que suma dos números (de manera muy simplificada y solo para ver como interactuan) las variables que se van a sumar están en la memoria, en la parte de datos, la instrucción de suma en la memoria de igual modo pero en la parte de programas, el controlador de flujo le pide al manejador de memoria la próxima instrucción, el manejador de memoria entrega la instrucción se interpreta por el controlador de datos el control de flujo (luego de un milagro), le pide las variables para ser sumadas al manejador de memoria, luego de ser interpretadas por el controlador de datos este le entrega las variables al controlador de programas (no es tan así … pero bueno…) y este le entrega la información al grupo de operaciones para efectivamente realizar la suma.

Eso es básicamente una máquina abstracta, y si cree que es complicada y engorrosa… la verdad no sabe nada porque no puse ni la mitad de los pasos lógicos que se utilizan realmente para realizar la suma de dos números.

Eso, espero que les guste y que se entienda como trabaja por detrás un lenguaje de programación… a groso modo.

 

Lenguajes y paradigmas de programación para la Arquitectura de software

He estado mirando cual es el conocimiento básico que realmente se necesita como arquitecto de software, y pese a saber que puede ser empezar muy básico, creo que es absolutamente necesario partir revisando los lenguajes y paradigmas de programación, ¿como lo justifico?, creo que un buen arquitecto de software debe ser capaz de conocer el o los lenguajes con los cuales trabaja y algunos adicionales, ya que cada problema se puede abordar de diferente forma con una herramienta diferente, y por ende, se pueden elaborar soluciones con una aproximación diferente, por lo cual, debe ser capaz de decidir, de manera justificada, cual o cuales de las herramientas serán utilizadas de acuerdo al problema que se está resolviendo, la realidad del equipo y los objetivos de la empresa.

En uno de mis post anteriores (acá), definí someramente que es un paradigma de programación y que es un lenguaje de programación, pese a que en la práctica no se necesita tener un conocimiento mucho mayor que la idea de lo que significa en términos generales cada uno de esos conceptos creo que un arquitecto debiese tener un conocimiento más acabado de la forma en como trabajan los lenguajes de programación, la forma como trabaja la máquina o el intérprete dependiendo del tipo de lenguaje, cómo se estructura la resolución de variables y de instrucciones en la máquina, como las sintaxis están compuestas como se resuelven y en qué orden, cuales son las características de los diferentes paradigmas a nivel de implementaciones en la máquina (como trabajan los dispacher y esas cosas), que característica tienen los paradigmas y como se implementan dependiendo del lenguaje, la claridad de estos conceptos es muy importante y ayuda a tomar decisiones de implementación.

El mejor libro en el tema que he encontrado es Programming Languages: Principles and Paradigms que se puede encontrar acá en amazon, es un libro muy detallado que explica todo lo que he mencionado, aunque es un poco técnico y abstracto, explica muy bien todo lo mencionado.

Ok, hoy voy a pedir feedback, como vuelvo a insistir yo creo que un buen arquitecto debería saber del tema, pero no se si hacer algunos post hablando de lenguajes y paradigmas explicando lo que yo creo importante o con solo indicar que cosa leer basta… no lo se… además me di cuenta que a esto se le pueden ingresar encuestas, así que como estoy tentado de probarlas acá va la primera XD.

Sobre la arquitectura de software, ¿qué se necesita?

Un colega hace unos días me preguntó que podía leer para poder mejorar su conocimiento, básicamente pidiendo consejo sobre cómo partir ya que tiene muy poca experiencia programando, lleva solo unos meses trabajando y aún está terminando su carrera. Bueno luego de conversar con él para saber que esperaba, que estaba interesado en aprender y cual era el foco de la pregunta, me confesó que le gustaría llegar algún día a ser arquitecto de software, por eso se acercó a hablar conmigo, porque pese a tener un cargo de arquitecto si no más de gestión, a falta de un arquitecto he estado supliendo el rol en la empresa donde trabajo.

La verdad es que no le quise contestar de inmediato, pese a que lo primero que se me vino a la cabeza fue el libro de patrones de diseño del GOF, o los videos de clean code de Martin Fowler, no me pareció sensato que partiera por ahí, puede ser mucho digerir para cuando uno recién está partiendo, y no me malinterpreten, no tiene que ver con capacidad, ya que creo que aprende muy rápido y está alcanzando el paso del resto de los programadores de la oficina, sin embargo es empezar por el lugar incorrecto, pese a este ser conocimiento crucial para un arquitecto, siempre es mejor partir por la base, poner los cimientos firmes y duraderos para que el resto de las cosas encaje de manera coherente y no se tengan que dejar espacios. Además por otro lado en una pelada de cable vía chat con mi amigo Gómez (que últimamente es la única forma de comunicación que estoy teniendo con él) le dije que me hacía falta y que yo no conocía un manual de referencia de arquitectura de software, donde se tocaran no sólo las técnicas de arquitectura de software, sino además las herramientas y los conocimientos necesarios, para que uno pueda consultarlo y repasar cuando haga falta, quedamos de tomarnos un café y pelar el cable para ordenar la idea y hacer una especie de investigación si encontrábamos material adecuado para ello. Cuento corto juntando las dos cosas voy a escribir algunas entradas adicionales a mi blog que trate temas de arquitectura y conocimiento sobre arquitectura de software, la idea es que sea una guía de referencia y no un lugar donde se describe y define a cabalidad cada uno de los conocimientos, por lo que puede ser que falte posteriormente una investigación sobre el tema tratado, o incluso se puede solicitar que ahonde en el tema en caso que algo no halla quedado claro.

Bueno dejándose de rodeos, partiremos por lo temas más básicos, ¿que es la arquitectura de software? y ¿que se necesita para ser arquitecto?, primero, se confunde generalmente la arquitectura de software con la ingeniería de software, yo creo que la arquitectura de software forma parte de uno de los procesos de la ingeniería de software, mientras la ingeniería de software se preocupa del proceso de creación software completo, con una visión sistemática y completa, la arquitectura de software se enfoca sólo al proceso de diseño de un producto o sistema, donde no solo se tiene que preocupar del diseño de los algoritmos involucrados en el desarrollo, sino tener una visión general mucho más amplia teniendo clara las interacciones del software y enfocándose en los diferentes puntos que implican calidad del mismo, Philippe Kruchten lo explica mucho mejor que yo, dice:

”La arquitectura de software, tiene que ver con el diseño y la implementación de estructuras de software de alto nivel. Es el resultado de ensamblar un cierto número de elementos arquitectónicos de forma adecuada para satisfacer la mayor funcionalidad y requerimientos de desempeño de un sistema, así como requerimientos no funcionales, como la confiabilidad, escalabilidad, portabilidad, y disponibilidad.”

Pese a no estar de acuerdo con Philippe Kruchten en aspectos metodológicos, que tienen que ver con la ingeniería del software más que con la arquitectura, creo que su definición es bastante acertada y me quedo con ella.

Y ahora ¿que se necesita para ser arquitecto?, me parece que es una lista de características que puede llegara ser infinita, por lo que sólo resumiré algunas de las que encuentro más importantes.

  • Conocimiento: Claramente una característica de un arquitecto de software es el conocimiento, de la plataforma, de la forma de trabajar, del negocio, de la tecnología y del equipo, no es necesario que lo sepa todo a la perfección, ya que para eso son los especialistas, pero sí debe tener el conocimiento suficiente para poder tomar decisiones que ayuden a mejorar la sinergia de todos los aspectos mencionados, ya que todas esas son las aristas de conocimiento que se deben tomar en cuenta, que se saca con impulsar una iniciativa de tecnología si nadie puede trabajar en ella, o hace que el negocio responda lento y sea inviable, o que no se tengan los medios económicos necesarios para soportarla.
  • Experiencia: No solo el conocimiento teórico es necesario, entre las funciones del arquitecto está lidiar con personas y problemas de la tecnología, y problemas que en teoría no ocurren y problemas que en la teoría ocurren y están bien documentados, pero en la práctica no son importantes o que el modelo de negocio está construido de tal forma que tales condiciones no se dan, para esos casos la experiencia es necesaria y absolutamente importante.
  • Liderazgo y negociación: No vivimos en un mundo ideal donde todo el mundo nos espera y podemos escribir un código muchas veces hasta que estemos orgullosos de ellos, estamos supeditados a tiempos, plazos, expectativa y factores humanos, es por eso que un buen arquitecto debe saber qué hacer, cómo lidiar con las circunstancias y que sacrificios hacer para poder cumplir con las expectativas y plazos, sin dejar de lado la motivación al equipo, la capacitación constante al mismo y trabajar como facilitador para eliminar problemas y prácticas que entorpecen el desempeño normal y correcto del equipo.
  • Visión del negocio: Una de las cosas más importantes bajo mi punto de vista, la informática es una ciencia de apoyo, y, amenos que sea en un contexto de investigación, no se hace arquitectura de software por arquitectura de software, si no para resolver problemas en función del negocio, no hay que perder de vista el negocio, el arquitecto es la pieza clave que debe tener la capacidad de alinear los proyectos con la realidad tecnológica y hacerlos coexistir en función del negocio y las metas de negocio.

 

Tipo de Dato Bag

Nuevamente hace un rato que no escribía, ya se me había incluso quitado la costumbre, sobre todo porque el público objetivo del tutorial no lo leyó nunca ¬¬, pero bueno, mejor volver a la modalidad ecléctica donde escribo lo que se me ocurre y no me preocupo de mucho más, es más sano, que sea solo una catarsis  y una forma de dejar registro de las cosas que sean interesantes e importantes para mí. Luego del preámbulo aburrido y culposo clásico de cada periodo sin escribir ataquemos el punto, estructuras de datos.

Últimamente he estado leyendo el libre Algorithms, de Robert Sedgewick y Kevin Wayne, para refrescar conocimientos y repasar las materias ya añejadas en el inconsciente (esas cosas que siempre usas de una u otra forma pero no recuerdas al pie de la letra) y en la parte de las estructuras de datos me encontré con una que no conocía, así que para que no se me olvide la voy a escribir por acá, les presento el tipo de dato Bag (bolsa o bolsón sería en español).

Bag es un tipo de dato de colecciones de ítems cuya particularidad es que no soporta la eliminación de elementos, se puede instanciar un nuevo Bag, tiene un método para añadir un ítem al Bag, un método que pregunta si está vacío, uno que entrega el tamaño, y la posibilidad de iterar sobre todos los ítems, solo eso, no está ordenado, no deben los objetos ser iguales, no exige nada de eso. Por lo que una interfaz para este tipo de dato sería como la siguiente:

Este tipo de dato es muy útil para impedir que se eliminen ítems, ya que no implementa esta función y que no importe el orden en el cual se guardan los ítems en la estructura de datos. Un ejemplo de utilización puede ser por ejemplo cuando se quieren sacar datos estadísticos de un conjunto, con el conjunto definido no se quiere que se eliminen datos de este porque modifica los cálculos de la estadística y el orden en que ingresa no es importante ya que lo interesante es el resultado estadístico.

Eso, interesante, un tanto específico pero muy útil bien implementado.

Página MVC Embebida en dll

Ya, ayer fue básico hoy será un tópico avanzado para compensar, vamos a ver como con .Net MVC 4 se puede dejar una página web embebida, es decir vamos a crear un .dll con un controlador adentro y sus páginas web para poder posteriormente distribuirla solo como .dll e inyectarla de ser necesario.

No me voy a llevar el crédito solo, este ejemplo lo cree tomando como base el siguiente grupo de post en Los Techies

Code Chef

He estado un poco flojo este último tiempo y no he posteado nada de nada en los últimos días, como este blog no lo lee nadie la verdad como que da un poco lo mismo XD, pero lo importante es que me propuse escribir todos los días y no lo he echo, aunque la falta fue justificada igual no viene al caso y estoy en deuda, me pongo al día si o si esta semana, pero como no comenta nadie a veces a uno le da un poco de lata, bueno… comenten y me animaré mas.. si alguien lee esto :(

Bueno enfoquemos, hoy es martes, el día del link interesante, la semana pasada postie pex for fun, que es un enlace donde en línea se resuelve un problema, es tan bueno que un amigo lo usa como examen para las personas que entrevista cuando recluta personal, esta semana voy a poner otra opción de preguntas con un grado mayor de dificultad.

Code Chef, es una comunidad en línea que hace concursos de programación constantemente, en este caso se compite contra las demás personas de la comunidad y no contra una solución secreta, tiene el formato de las competencias de la ACM ICPC, con una entrada por la entrada estándar, que es básicamente leer por consola los datos de entrada, una salida con un formato por defecto, el programa se prueba contra muchas entradas y se ranquea si soluciona el problema en el tiempo determinado, los problemas como entrenamiento están clasificados y constantemente hay concursos, se están buscando una base de problemas para dar a personas que recién aprenden a programar o problemas complejos que se pueden solucionar con algoritmos avanzados, este es el lugar para encontrarlos, es muy bueno muy completo y no solo miden si la solución resuelve el set de problemas completo, si no si lo resuelve rápido y quien lo resuelve más rápido.

Eso, si quieren una base de problemas más complejo que se corrija en tiempo real, acá es su lugar, hay de todos los grados de complejidad, ojalá les guste.

 

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 981 seguidores