lunes, mayo 31, 2010
Arquitectura de software, rol e integracion de aplicaciones
http://bit.ly/bfSKOR
El resumen de este documento fue posteado en
My Software Architecture Presentation
miércoles, marzo 10, 2010
Buenas prácticas de programación en C
El siguiente documento describe las buenas prácticas de programación a nivel general de lenguajes de programación orientados a procedimientos y en particular para el lenguaje de programación C.
Estas buenas prácticas las clasificaremos en diferentes grupos.
Nomenclaturas: Se refiere a las reglas aplicables a la denominación de nombres de variables, constantes, funciones, estructuras etc. Estas reglas tiene como objetivo definir un lenguaje común para facilitar la lectura y mantenimiento de un código. Son reglas generales de muchos lenguajes de programación, que son aplicables perfectamente al lenguaje C.
Sintaxis: Se refiere a reglas de la sintaxis en si del lenguaje de programación, y recomendaciones para hacer mas legible el código generado.
Patrones: Los patrones son diseños y recomendaciones generales que solucionan problemas comunes de determinados contextos. Existen patrones de diseño aplicados a diferentes tipos de lenguajes de programación (orientados a procedimientos, objetos, eventos, web etc), para diferentes contextos de ejecución (multitareas, tiempo real, distribuidos, ejecución batch etc), para diseñor en diferentes nivels de abstracción de un sistema, para integración entre sistemas que corren en la misma o diferente plataforma etc.
En nuestro caso nos dedicaremos a los aplicables a lenguajes de programación orientada a procedimientos (como el C).
Documento completo
My Software Architecture Presentation
En la actualidad no se concibe empresa grande sin soporte a sus negocios mediante el uso de las tecnologías de sistemas de información implementados dentro de la misma. Estos sistemas ayudan a manejar áreas tales como recursos humanos, ventas, compras, gestiones de procesos específicos del rubro, administración financiera, económica, tableros de comandos para la ayuda a la decisión de la gerencia etc.
Dada la criticidad de esos sistemas para el funcionamiento del negocio es imprescindible que sean construidos, implementados y mantenidos siguiendo estándares de calidad.
En este contexto se necesita un especialista que tenga una visión de negocio, habilidades técnicas y buena comunicación a los diferentes miembros del área de IT.
Estos sistemas muchas veces deben ser interconectados, es facultad del arquitecto garantizar la calidad del software desde el inicio hasta su implementación y mantenimiento.
En la siguiente presentación se resume el trabajo que analiza los aspectos relacionados con la arquitectura de software, su clasificación, el rol del arquitecto y metodologías recomendadas en pos de optimizar la integración entre sistemas.
Software Architecture Presentation
La documentación completa de esta presentación esta en el siguiente post.
Arquitectura de software, rol e integracion de aplicaciones
martes, noviembre 03, 2009
SOA anti-patterns
La intención es describir algunos de los anti patrones SOA más comunes con el fin de indicar como no se debe diseñar una solución SOA.
Interfaces CRUD
CRUD en la sigla en inglés que representa las operaciones de creación, lectura, actualización y borrado. Es muy común utilizar estas operaciones en relación a las bases de datos, pero en el caso de un sistema orientado a servicios especificar las operaciones de los servicios como CRUD es una mala práctica.
Por ejemplo en un servicio de manejo de ordenes diseñar en servicio en base a CRUD implica tener operaciones del este tipo
FindOrderByIDResponse FindOrderByID(FindOrderByIDRequest request);
CreateOrderResponse CreateOrder(CreateOrderRequest request);
UpdateOrderResponse UpdateOrderByID(FindOrderByIDRequest request);
DeleteOrderResponse DeleteOrder(DeleteOrderRequest request);
Si en los casos de uso se necesita crear, actualizar y borrar ordenes esta especificación de servicios es válida, pero si la creación de una orden implica varias operaciones previas (por ej verificar la disponibilidad del producto, verificar el estado de crédito del cliente y crear la orden), la operación CreateOrder debe invocar internamente todas las operaciones necesarias para crearlo pues en caso de exponer solo la creación de la orden el consumidor debe hacer las operaciones previas. Este diseño violaría el TNet 3 pues no estaríamos compartiendo solo contratos.
En resumen lo incorrecto no es el uso de CRUD para la especificación de un servicio sino un mal diseño.
Interfaces Chatty
Este anti patrón se refiere a cuando se diseña un sistema orientado a servicios con operaciones que implican un alto nivel de granularidad. En este tipo de interfaces el consumidor es el encargado de llamar a las diferentes operaciones siguientes una lógica específica para que juntos hagan una determinada acción de negocio. Lo correcto es que todas las operaciones para hacer una determina acción de negocio se ejecuten internamente en el servicio.
Por ejemplos la siguientes operaciones se basan en un diseño que aplica este anti patrón
bool ChekGoodAvailability(Ordr order);
bool CheckCreditStatus(Order order);
bool PlaceOrder(Order order);
Estos dos anti patrones están asociados pues un mal diseño de una interfaz CRUD se convierte en una interfaz chatty.
En conclusión el formato de los servicios expuestos depende fundamentalmente de la especificación de casos de uso que estos deben implementar. Por lo tanto en ciertos casos se van a requerir operaciones tipo CRUD pero en muchas otras no. Un adecuando análisis de las especificaciones funcionales seguido de un buen diseño es importante para no terminar utilizando anti patrones.
miércoles, agosto 05, 2009
Integration Patterns
El libro se lo puede bajar en formato pdf en el sitio de P&P.
http://msdn.microsoft.com/en-us/library/ms978729.aspx
En la siguiente presentación hice un resumen de este libro.
Resumen Integration Patterns
Otra importante fuente de información sobre el tema es el sitio de Patterns and Best Practices for Enterprise Integration (http://www.eaipatterns.com/) que tambien tiene su libro.
Este sitio es muy interesante porque tiene los patrones clasificados en varias categorias y stencils de visio con esquema sobre este tipo de patrones.
viernes, julio 31, 2009
Plugin Pattern II
En la practica cotidiana existen muchas oportunidades en la que se desea extender la funcionalidad de un sistema, tal sea para implementar de otra forma un funcionalidad existente como agregar una que no exista.
Una alternativa de solución
Usando herencia se puede implementar de otra forma una funcionalidad existente respecto a una clase original.
Por ejemplo en un sistema simple de validación de datos de entrada en donde tenemos que validar los campos tipo string, valores requeridos y uno alfanumérico con un formato predefinido, se podría implementar de la siguiente forma
La clase ValidateEngine permite validar todos los datos de entrada, obviamente esta implementación está muy simplificada pues se debería agrega toda la lógica de validación de datos de entrada de un determinado formulario del front end de la aplicación.
Esto trae como problema que se deba implementar lógica para validar tipo de datos, longitud, expresiones regulares (por ej para un ISBN) y valores requeridos, es decir una implementación con una muy baja cohesión.
Una mejora sería que la clase ValidateEngine sea una clase abstracta del cual se deba heredar para implementar cada tipo de validación.
De esta forma tenemos diferentes validaciones implementadas en clases separadas, lo que permite que cada una de ellas tenga alta cohesión.
Para utilizar este modelo podríamos aplicar el patrón estrategia [3] tal como muestra la figura.
Aplicando este patrón tendríamos un sistema más flexible, por ejemplo en C# se podría implementar de la siguiente manera:
Como resultado de la ejecución de este ejemplo obtenemos la siguiente respuesta
Si deseamos agregar una nueva forma de implementar una validación deberíamos heredar otra clase y configurarla en la clase de contexto.
Esta solución es mucho mejor que utilizar una sola clase para todo pero tiene el gran inconveniente que para agregar nuevas funcionalidades se debe crear una clase heredada lo que hace el sistema poco flexible.
¿Cómo mejoramos está solución?
Supongamos que deseamos crear un sistema en donde se pueda expandir su funcionalidad pero en forma dinámica, configurable y en tiempo de ejecución, la solución mencionada ya no satisface ese requerimiento.
La implementación del patrón Plugin permite agregar funcionalidad a nuestro sistema en forma dinámica utilizando configuración o un estándar de implementación predefinidos. Los módulos que agregan funcionalidad al sistema se denominan plugins.
Ejemplos de la vida real
Este patrón es muy utilizado en múltiples sistemas como sistemas multimedia que permiten agregar en forma muy simple nuevos módulos para edición de audio, transformación entre formatos, skins, analizadores de espectro etc.
En el mundo del desarrollo este patrón se aplica mucho, el más claro ejemplo es el IDE Eclipse,
la arquitectura de este entorno de desarrollo está exclusivamente basada en plugins, pues por si solo no tiene funcionalidad significativa más que proveer un entorno que permite agregarlos [4].
En sus orígenes fue creado como un entorno de desarrollo para Java, pero actualmente se puede usar para muchos otros lenguajes (C++, Python, PHP, Perl, Intel C++ para Linux, Cobol, ABAP , Google apis etc.), también se puede usar para modelado (UML, Base de datos, Data Warehouse etc.), herramientas de soporte al desarrollo como gran cantidad de editores diferentes, clientes Subversion, para soporte de programación en pares distribuida (Distributed XP) , comerciales como herramientas para el BPM de Tibco, generación de interfases para el broker de Software AG etc , al día de la fecha existen más de 1200 plugins publicados.
Visual Studio .Net tiene una api que permite crear plugins (addons), esta api esta implementada en System.Addin. La versión para desarrolladores del Visual Studio Team System posee plugins para revisión de código (basado en el FXCop) para pruebas unitarias, para análisis de performance, cobertura de código, control de fuentes, implementación etc.
Se pueden utilizar plugins comerciales o bien integrarlos al Visual Studio mediante un desarrollo especial.
Veamos una aplicación práctica
En el siguiente ejemplo vamos a extender el sistema de validación para aplicar el patrón Plugin, en este caso se va a utilizar configuración xml y reflection para poder agregar en forma dinámica nuevos mecanismos de validación.
Las nuevas validación estarán implementadas en assemblies separados y usarán el patrón Separate Interfase [5] para implementar la interfase IValidate que está en el assembly Context.
Cada implementación de una validación diferente se implementa en assemblies separados y mediante configuración se agregan como plugin al sistema original.
En este ejemplo usamos el siguiente archivo de configuración.
<ValidatePluginsConfigFile>
<plugins>
<plugin>
<name>ValidateRegularExpresions
name>
<fullName>ValidationExample.ValidateRegularExpresions,Version=1.0.0.0,Culture=neutral,
PublicKeyToken=3d10efd7d0a5d829fullName>
<type>ValidationExample.ValidateRegularExpresions.ValidateRegularExpresionstype>
<active>trueactive>
plugin>
<plugin>
<name>ValidateStringsname>
………………………...
plugin>
………………………...
plugins>
ValidatePluginsConfigFile>
Por lo tanto podemos agregar nuevos nodos plugin por cada componente de validación y el programa automáticamente los invocará.
Un poco más de código
En el siguiente fragmento de código se muestra como se puede ejecutar en forma dinámica un método de un assembly externo usando reflection y un poco de lógica para leer la configuración
Considerando que para que funcione correctamente los plugins deben estar en la GAC el resultado de la ejecución de este programa es idéntico al caso anterior.
Código
El código de ejemplo mostrado es parcial , de este link pueden bajar el proyecto completo para probar en sus maquinas, fue creado con el Visual Studio 2005 SP1.Conclusión
El patrón plugin es muy útil para extender la funcionalidad de un sistema de forma tal que podemos construir una sistema base que permita agregar plugins y luego esos plugins pueden ser construidos por terceros, esta filosofía la usa el IDE Eclipse ya mencionado y también es muy utilizada en el navegador Firefox (Firefox extensions) y el Chrome de Google.
También se usa en sistemas comerciales cuyos plugins requieren el pago de licencias adicionales al sistema principal.
Como desventaja se debe considerar el aumento del complejidad para permitir el agrego de los plugins en forma simple por un usuario que no tiene porque conocer los detalles del sistema principal.
Como en muchos casos para hacer un sistema que permita utilizar este patrón se debe considerar en el diseño original de la arquitectura del mismo.
Bibliografía
[1] Pattern to Enterprise Applications Architecture - Plugin Pattern ,http://martinfowler.com/eaaCatalog/plugin.html
[2] Log4Net Framework , http://logging.apache.org/log4net/index.html
[3] Erich Gamma et at, “Design Patterns: Elements of Reusable Object-Oriented Software” (Addison-Wesley Professional Computing Series) , pag
[4] Eclipse plugin central web site, http://www.eclipseplugincentral.com/
[5] Erich Gamma et at, “Design Patterns: Elements of Reusable Object-Oriented Software” (Addison-Wesley Professional Computing Series) , pag
[6] Pattern to Enterprise Applications Architecture - Separate Interface pattern, http://martinfowler.com/eaaCatalog/separatedInterface.html
martes, julio 21, 2009
Plugin pattern
Patron Plugin.
“Links classes during configuration rather than compilation.” (Fowler, POEAA, p.4990)[1]
El patrón Plugin permite agregar funcionalidad a nuestro sistema en forma dinámica utilizando configuración, por lo general se usan en frameworks que permitan agregar nuevas formas de implementar funcionalidades ya existente, por ejemplo el log4net [2] permite agregar nuevas implementaciones para los adaptadores a los repositorio donde registrar los mensajes de Log (IAdapter) o formato de los mensajes (IFormater).
Otro sistema que usaba el patrón plugin fue el EDRA de P&P, este framework implementaba el patrón Pipes & filters [3] en donde se podían agregar handlers que ejecuten determinada funcionalidad antes de ejecutar una acción personalizada, después o en ambos casos, ejemplo de un handler de “antes” sería un handler de autenticación, de “después” un handler de validación del formato de respuesta y para ambos casos un handlers que agregue información adicional al mensaje de entrada y al de salida a la acción, por ejemplo para medir tiempo transcurrido entre le ejecución de la llamada a la acción y la recepción del mensaje de respuesta.
Otro ejemplo de implementación del patrón plugin es cuando se usa en la implementación del patrón Chain and Responsability [4], básicamente en este patrón participan un conjunto de objetos de comandos y una serie de objetos de procesamiento, mediante configuración se pueden agregar en forma dinámica nuevos objetos de comandos.
Para implementar este patrón el sistema a extender debe disponer de un mecanismo de configuración donde se puedan agregar los nuevos componentes que implementan interfases definidas para determinadas funcionalidades del sistema.
Siguiendo con el ejemplo de log4net el archivo de configuración de la figura se indica el mecanismo que utiliza este Framework para aplicar el patrón plugin.
En este ejemplo se tienen 3 appenders, uno que envía los registro de Log a la consola, el segundo a un archivo que puede llegar a un máximo de 100kb (y luego se genera otro) y un aprender personalizado que envía los logs a otro repositorio no contemplado en la configuración estándar de log4Net (por ej MSMQ o WCF).
Mas info
[1] Pattern to Enterprise Applications Architecture - Pluging Pattern ,http://martinfowler.com/eaaCatalog/plugin.html
[2] Log4Net Framework , http://logging.apache.org/log4net/index.html
[3] Enterprise Integration Patterns – Pipes & Filters , http://www.enterpriseintegrationpatterns.com/PipesAndFilters.html
[4] Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley Professional Computing Series)
lunes, julio 13, 2009
Logging and trace.
Objetivo:
Registrar eventos de relevancia para utilizarlos en procesos de auditoria o troubleshuting post mortem.
Es una herramienta muy útil en ambientes productivos donde es imposible depurar con herramientas de desarrollo.
Los eventos pueden ser información de depuración o errores ocurridos en la aplicación.
Características deseables de un sistema de logging:
Configuración de niveles de log
Formateo de eventos
Agregado de información adicional en publicación de eventos
Logging asincrónico
Logging confiable
Logging centralizado
Configuración jerárquica y dinámica
Publicación a múltiples destinos
Aplicación para visualizar y analizar los eventos.
Anti patrones:
Todo en un mismo mensaje: Todo junto en un mismo archivo es muy dificil de analizar.
Registro de datos incompletos:Registrar lo que sirva para, ni más ni menos.
Log sin formato o formato no consistente: Si el log no está estructurado, su analisis se hace muy dificil.
Entradas multi línea: Complica el procesamiento de log para pasarlo a una DB o aplicación que muestre la información en forma amigable.
Registrar mensajes relacionados a un mismo contexto en varias líneas: Muy dificil de analizar lo que pasó en un determinado contextode ejecución.
Buenas prácticas:
Registrar los logs en repositorio con formato, esto facilita en análisis de los logs registrados.
Separar los mensajes en diferentes destinos dependientes de la audiencia que los usa, por un log de auditoria puede tener muchas más información de la necesario para resolver un problema que ocurrió en la aplicación.
Registrar las acciones antes de que ocurran
Evitar que los archivos de logs sean muy grandes, se recomienda archivarlos y crear uno nuevo.
Registrar los eventos en una sola línea, es más fácil de analizar y filtrar. Si la información tiene formato complejo se recomienda usar xml.
Usar formato consistente en un mismo archivo.
Patrones utilizados
Estrategia:
Se puede usar para seleccionar la forma en que el sistema de log registra los eventos y errores.
Pipes and filters:
Se usa para tener un mecanismo extensible y de bajo acoplamiento para agregar información contextual y codificación a los mensajes antes de enviarlo al repositorio de logging.
Consideraciones de implementación:
Por lo general son frameworks muy flexibles, que soporta multiples fuentes y destinos, por lo tanto para implementarlo adecuadamente se requiere un buen análisis de que funcionalidades usar y cual es su mejor forma de implementar.
Otros frameworks de logging e instrumentación.
Java: log4J y de este log4Net, log4PHP, log4JavaScript, log4C, log4VB, log4SQL, log4PLSQL etc
AJAX: log4javascript, JSLog, Lumberjack, log4Js, jsTracer
Unix like: syslogd (nativo).
Bibliografía
Carácteristicas
http://gojko.net/2006/12/09/logging-anti-patterns/
Frameworks
Pattern & Practices Logging Application Block
Apache Log4Net
Patrones
http://www.dofactory.com/Patterns/PatternStrategy.aspx
http://msdn.microsoft.com/en-us/library/ms978599.aspx
martes, mayo 19, 2009
¿Por qué es necesario un arquitecto de software?
“Architecture in an over used term and therefore doen’t mean anything anyway”
“Oh we don’t need training, we are Enterprise Architecture”,
“Help I need to hire architects but cannot define the role”, HR manager
“Why should I hire architects?, No one has ever made the case to me ”, CEO
“Architects just vision jockeys right?, We need coders no talkers”, developer manager
Estas frases fueron recolectadas de varias conferencias sobre arquitectura de software, encuestas y otros eventos de IT [Preiss Paul T, 2006, “Magician apprentice”] e indican en grado de confusión que existe respecto a la arquitectura de software, entonces como arquitectos es importante tener una buena respuesta a la siguiente pregunta: ¿Por qué es necesario un arquitecto de software?
Los sistemas de información soportados por aplicaciones informáticas son cada vez más comunes y en muchos casos imprescindibles para el funcionamiento del negocio de la empresa. En estas últimas dos décadas la evolución de esos sistemas fue exponencial y además los procesos son más complejos y la tecnología permite hacer más cosas en forma más sencilla y más rápida. Este aspecto tiene el riesgo de crear grandes sistemas en forma relativamente simple y rápida sin tener el adecuado control en la calidad, el costo de esto es grande a la hora de mantener el sistema, de solucionar errores y fallas y de evolucionarlo para agregar nuevas funcionalidades.
Standish Group en su “Chaos Report” describe un estudio realizado sobre mas de 175000 proyectos en donde los resultados no fueron nada alentadores. La siguiente tabla indica los valores promedios de sobre costo, exceso en tiempo y baja satisfacción de la funcionalidad del producto con los deseado.
Parámetro (exceso sobre los estimado) | % promedio |
Costo | 189% |
Tiempo | 222% |
Deficiencias en el producto final | 60% |
De los proyectos relevados solo el 12% terminó en tiempo y dentro del presupuesto asignado.
La investigación mencionada incluye el resultado de un encuesta entre algunos de los CIOs de esas empresas preguntando cuales serían los aspectos que se deberían mejorar para reducir estos indicadores en los proyectos. De esa encuesta surgió que los tres principales factores a mejorar fueron un mejor involucramiento del usuario, mejora en la administración del proyecto y tener requerimientos claros y bien documentados.
En cambio si consideraban que aspectos perjudicaban el éxito del proyecto se consideraron como prioritarios aspectos tales como malas de comunicación con el usuario, requisitos y especificaciones incompletas y cambios constantes en especificaciones y requerimientos.
De este análisis se describe que es muy importante tener una buena planificación, documentación de requisitos y especificaciones y fluída comunicación con el usuario para tener éxito en el desarrollo del software. Los cambios en las especificaciones y requisitos son imposibles de detener pues muchas veces son causa de cambios en el contexto del negocio que las crearon, por eso una buena planificación y requisitos bien documentados mitigan este riesgo, además si se trabaja con un entorno de trabajo estable, bien documentado que resuelva las tareas rutinarias, de mayor complejidad y administradas por la menor cantidad de roles posibles se mitiga en gran medida los riesgos en todas las etapas del desarrollo del software.
Por este último aspecto es que se necesito un grupo de arquitectura, pues interviene en como un grupo staff en todo el ciclo de vida del desarrollo, definiendo estándares, buenas prácticas, ofreciendo soporte, coaching al desarrollo y diseño, metodologías, frameworks (conceptúales y ejecutables): Participan también en definiciones o adopción de metodologías de desarrollo de administración de cambios que faciliten la tarea de los de más integrantes del equipo de desarrollo y de los stakeholder .
Por lo tanto necesitamos arquitectos para afrontar la complejidad de los sistemas, para ofrecer agilidad en los negocios, para reducir los costos en IT, para mejorar la alineación del área de IT en los negocios etc .
Como se habia mencionado las soluciones de software distribuidas sueles tener una alta complejidad, esa complejidad puede ser inherente a la tecnología y la especificación funcional del negocio o bien puede ser accidental. Muchos procesos de negocio presentados como complejos luego de una buen análisis se pueden simplificar, es importante recordar que los sistemas se basan en los procesos y no lo procesos a los sistemas, por lo tanto dedicarle tiempo a optimizar los procesos de negocios a ejecutar es fundamental en la etapa de inicio pues la construcción de los sistemas se basarán en esos procesos. El arquitecto debe tener la habilidad necesaria para entender el proceso, el problema y crear un modelo que se ajuste al mismo.
En cambio, la complejidad accidental está muy relacionado con las tecnologías y estilos de las arquitecturas elegidos. Una tarea muy importante que debe cumplir el arquitecto es la determinación de aspectos no funcionales de la arquitectura, tales como flexibilidad al cambio, mantenimiento, escalabilidad, reusabilidad, usabilidad, monitores, performance , seguridad etc.
Cuando se tienen definidos estándares de calidad no funcionales y restricciones tecnológicas impuestas por políticas de la compañía muchas veces la arquitectura puede ser más compleja porque se debe alinear a las mismas.
Además tiene que considerar políticas tales como restricciones debido a estándares externos, como por ejemplo SOX , internos de negocios , regulaciones gubernamentales etc.
El cumplimiento de estos conceptos permite reducir costos de IT, mejorar la satifacción del cliente interno proveyendo para el primer caso mejores herramientas que faciliten las tareas del personal de la empresa dedicada a la operatoria diaria del negocio y áreas relacionadas. Estas mejoras también benefician a los clientes externos puer les permite disponer de mayor control en sus pedidos, despachos de los productos adquiridos.




