sábado, 13 de octubre de 2012

CUANDO LOS ERRORES NO ESTAN EN EL CÓDIGO


La mayoría de las veces estamos buscando los orígenes de los problemas en nuestro código fuente y puede que encontremos muchos o pocos, quien sabe, pero en otras ocasiones el código fuente solamente es el reflejo de otros aspectos de las organizaciones. A este tipo de situaciones es a la que nos vamos a referir en esta ocasión.

Una aspecto fundamental que hay que entender es que los desarrolladores son seres humanos aunque aveces no lo parezcan, la consecuencia lógica es que sus acciones afecten los resultados y el ambiente de trabajo, a continuación presento una serie de conductas y efectos producidos por las mismas dentro del código. Como es de esperarse solamente se presentan aspectos negativos ya que los positivos no generan problemas, adicionalmente pueden establecerse combinaciones y de hecho considero que cada uno tiene un poco de todos por lo que se deben analizar los comportamientos presentados desde una óptica de extremos para ser comprendidos.

El paranoico laboral.

Este es personaje que pocos identifican y que mantiene oculto sus pensamientos reales, se concentra permanentemente en la idea de que lo pueden despedir en cualquier momento, hace chistes en casi cualquier situación relacionados con el despido, se siente inseguro sobre su trabajo y actúa de acuerdo a su paranoia. Es el tipo de persona que nunca revela información sobre lo que hace porque su inseguridad es tan grande que piensa que si los compañeros entienden como funcionan sus desarrollos ya no será necesario para la organización o podrá ser sustituido. Esta persona suele escribir un código prácticamente cifrado e incomprensible para garantizar su subsistencia, como consecuencia le hace miserable la vida a todo el equipo de trabajo y sacrifica su propia tranquilidad con tal de mantener custodiado esos algoritmos que después de un tiempo ni el mismo entiende. La productividad general se ve afectada en gran medida si este individuo trabaja los aspectos principales de los productos.

El inmediatista

Otro tipo de desarrolladores que a menudo nos encontramos son aquellos que nunca se preocupan por entender las dimensiones de lo que hacen. Esto es, frente a un bug o nuevo desarrollo solo visualizan el resultado inmediato de lo que están tratando y pierden el punto de vista general. El inmediatista por lo general toma decisiones de la forma 'Si x vale 2 entonces funciona...como x vale 1 cuando no funciona entonces le sumo uno', todo esto sin preocuparse que se supone que representa x, donde se usa, en que parte del código está parado... es el que coloca la mayoría de los try..catch sin sentido, es una persona que simplemente hace lo que se le pide, no va mas allá, solo piensa en que no se le acumule el trabajo. La consecuencia lógica de esta conducta es que por cada cosa que este personaje arregle daña 5 creando una inestabilidad en el código producto de una codificación al azar.

El revolucionario

Este personaje siempre se encuentra en desacuerdo con la forma en la que se realizan las actividades de trabajo, anda en una búsqueda permanente de una solución mágica que hace que todos los problemas desaparezcan, la raíz de todos los males, el código que nos va a sacar del hueco. Este tipo de desarrolladores se siente a cada momento entre la espada y la pared, porque sus desarrollos nunca han funcionado y nunca es su culpa, está aburrido de que cada nueva solución traiga mas problemas y siempre busca nuevas tecnologías que solucionarán todo. Estos desarrolladores por lo general no viven alineados con los objetivos y dificultan la comunicación que es vital en este tipo de trabajo y hace que fluya todo en la dirección correcta.

El hombre código

Es admirado por su capacidad analítica y por ser capaz de enfrentarse a situaciones desconocidas, sabe de todo y no se especializa en nada, pero por encima de estas características es admirado por su gran capacidad de producir toneladas y toneladas de código, a veces no tan bueno, pero, a quien le importa, ES MUCHO CÓDIGO!!!. Es tan bueno programando que no necesita diseñar nada, sus diseños (cuando le toca diseñar) son extremadamente complejos. Para este individuo todos los problemas se arreglan depurando el código y los conceptos pasan a un segundo plano, lo importante es el código y piensa en forma algorítmica hasta en su vida cotidiana. Como este personaje abarca gran parte de la "producción" es uno de los elementos que mas bugs inyecta en los fuentes, crea esquemas incomprensibles para el resto de los mortales dentro del equipo.

El evasor de trabajo

De estos hay muchos, es ese tipo de persona que nunca se hace responsable de lo que hace siempre anda pensando que todos quieren ponerle mas trabajo a el, no es consiente de que el resto de las personas trabajan igual o quizás mas duro que el. Esta situación hace que siempre esté postergando sus tareas, y cuando se le pregunta sobre algo que desarrolló, siempre depende de otra cosa que el no hizo y por eso "NO SABE". Cuando el problema es generalizado dentro del equipo de desarrollo los tiempos de entrega se ven afectados por un carrusel del que es casi imposible salir, preguntando aquí y allá para saber quien conoce el estado actual del tema.

El "buena gente"

Esta persona no le dice que NO a nada, es amable con todos y siempre anda colgado con el trabajo, pero sigue aceptando mas trabajo, consecuentemente acapara gran parte de las funcionalidades y hace que todo tenga que ver con el. Sus compañeros evasores se aprovechan de esta situación para transferir su carga laboral a esta persona que en ultimas no termina siendo mas que una víctima de sus propias acciones.

El personalizado

Este ser se lo toma todo de manera personal, su código no puede ser cuestionado porque eso representa una ofensa a su intelecto, los problemas para este individuo nunca son académicos, siempre están relacionados con la manera de ser de los demás miembros del equipo y consecuentemente dificulta la comunicación creando fricciones innecesarias. Por lo general es una persona que trabaja muy bien solo y muy mal en equipo.

El superproductivo

Esta persona siempre hace mas cosas de las necesarias, si le piden que haga un informe desarrolla un sistema de información para la generación automática de informes, por lo general entrega lo que se le pide, sin embargo, terminará dando mas soporte a todas las cosas que se inventó y que no tenia que hacer. La consecuencia de esta conducta es que se desperdicia el tiempo realizando las tareas innecesarias, tiempo que podría reducir los plazos de entregas de características o desarrollos de mayor valor.

Super-EGO

Esta persona es difícil de tratar, siempre esta proyectando una imagen de saberlo todo, de ser incuestionable, nadie sabe mas que el en ningún tema. Sus actitudes crean malestar en los demás miembros del equipo y maximiza sus logros y minimiza los de los demás. Este tipo de personas no trabajan bien en equipo y vuelven lento los procesos de diseño y construcción.

Otros factores

Otro tipo de situaciones que pueden afectar los procesos de desarrollo de nuestros productos está dado por el uso apropiado de las habilidades de los miembros del equipo. Si no conocemos dichas habilidades es muy probable que estemos distribuyendo el trabajo de una manera poco inteligente, de esta forma, las características y las habilidades pueden terminar cruzándose de maneras catastróficas. En otras ocasiones problemas como la extrema presión de tiempo, la presión por los costos de proyectos o la presión por la competencias hace que la calidad con la que se liberan las características no sea la esperada, estos son otros tipos de problemas que afectan el código sin estar inmerso en el, de los cuales hablaremos en otra ocasión.

Una vez visto a grandes rasgos ejemplos de formas en las que las conductas humanas pueden influir en la calidad de los desarrollos, deberíamos ser mas autocríticos con nuestras acciones y detectar las oportunidades de mejora sobre las mismas, teniendo en cuenta que en muchas ocasiones aspectos relacionados con el desorden y los intereses personales también pueden afectar los resultados. Espero les haya gustado el articulo y también espero sus comentarios.

MODELOS DE OBJETOS


Los lenguajes orientados a objetos trajeron consigo un número de ventajas relativas a conceptos significativos de la programación, sin embargo, en muchos aspectos la disponibilidad de las ventajas no implica su comprensión y aplicación, de esta manera, se puede tener un arma muy poderosa para el desarrollo de la cual solo se utilizan las partes básicas. Teniendo en cuenta lo anterior, los miembros de un equipo de trabajo no solamente deben tener conocimientos específicos de los lenguajes de programación y de las herramientas, deben además, desarrollar en sí mismos una capacidad analítica que les permita identificar de manera clara y objetiva cuales son los elementos de un problema que brindan soluciones particulares a otros problemas. De esta forma, un pensamiento lo suficientemente analítico le permitirá a los miembros del equipo de desarrollo trabajar en términos de funcionalidades, responsabilidades, reutilización y composición de soluciones. Una forma sencilla de combatir estos problemas es utilizar diagramas que nos permitan visualizar y desacoplar la lógica de los diferentes modelos que componen la solución de la lógica de otro tipo de tareas comunes como lo son la presentación y la interacción con el usuario.

Los modelos nos permiten identificar soluciones parciales a problemas específicos y genericos que en conjunto crean una capacidad de solución a los problemas objetivo, esto simplifica el entendimiento del problema y define los límites de funcionalidades en la implementación, de otra manera se puede implementar aspectos que no serán utilizados al final del desarrollo. Los modelos de objetos suelen brindar un conjunto de soluciones que se encuentran cerradas en un grupo de componentes que usualmente son determinados por los espacios de nombres en la programación orientada a objetos.

Se puede construir un conjunto de objetos que implementen muchas funcionalidades y no ser un modelo de objetos coherente, hay que tener mucho cuidado si no se termina implementando soluciones poco claras y difíciles de comprender desde el punto de vista del desarrollador. Al momento de diseñar un modelo de objetos tenga en cuenta los siguientes aspectos:

Generalidad: El diseño debe contar con un nivel de generalidad suficiente para resolver el o los subproblemas y al mismo tiempo estar preparado para el cambio, esto debe ocurrir en cada grupo de objetos que componen el modelo que da solución al problema planteado.

Capacidad de crecimiento: El modelo debe poder crecer en el tiempo y este crecimiento debe poder realizarse de manera incremental conservando el origen del diseño.

Agrupamiento de Componentes: Agrupar los tipos de objetos suele tener ventajas al momento de mantener la solución, se debe tratar de agrupar las funcionalidades comunes.

Independencia: En casi todos los casos los problemas suelen tener conceptos relacionados y teniendo en cuenta que estos conceptos se traducen en tipos de datos se deben identificar previamente las dependencias entre ellos para eliminar o reducir el impacto frente a los posibles cambios futuros.

Composición: La solución de un problema suele estar compuesta de soluciones específicas que usualmente son más pequeñas y que no necesariamente están dentro del mismo grupo que los tipos de datos de la solución total.

Unidades de datos: Se espera que los datos estén relacionados entre sí, de esta manera no se deberían tratar los datos de manera independiente sino como una entidad o unidad que encapsula la información, que debe corresponder a un concepto claramente identificado dentro del dominio del problema. Quien no ha vivido la tortura de mantener código en el cual todos los datos estan dispersos y en aumento? Analizar la información desde esta perspectiva nos da la posibilidad de crecer en la información de cada entidad o unidad de datos sin tener que alterar el comportamiento de la aplicación.

Tener en cuenta estos pequeños ítems puede complicarnos un poco el diseño, pero posteriormente puede evitarnos muchos problemas por lo vale la pena pensar en ellos.

Importancia del Reúso


Si los elementos de nuestro modelo tienen responsabilidades específicas y tienen una buena definición sobre sus dependencias se logra un buen balance en términos del reúso. Es posible que si un modelo de objetos se diseña sin tener en cuenta las características anteriormente mencionadas, se encuentre incompleto, es decir que frente a nuevas situaciones no se cuenten con funcionalidades previamente implementadas para resolver los nuevos problemas. Es por esto que debemos tener un grado de confianza frente a las funcionalidades existentes, preferiblemente inventariadas, de esta manera podremos saber con exactitud que funcionalidades se encuentran lo suficientemente completas para ser reutilizadas, de otra manera, se inicia el desastre ya que al no estar completo o acotado el modelo reutilizado puede sufrir modificaciones en el futuro y consecuentemente impactar las soluciones que dependen de dicho modelo.

El reúso es más que sólo utilizar componentes ya existentes en nuevas soluciones, se debe diseñar pensando en el reúso para poder crear las oportunidades a futuro, la idea aquí es muy clara, si se construyen soluciones específicas para un problema sin determinar las tareas comunes entre los diferentes problemas que lo componen, es probable que nunca podamos reutilizar un componente más allá de la simple casualidad.

Para incrementar el reúso en las aplicaciones se podría sacar partido de las jerarquías de objetos basadas en la herencia ya que estas nos permiten visualizar instancias de diferentes formas y de manera adicional proporcionan niveles de abstracción para la extensibilidad o el crecimiento. Como siempre todo en exceso es malo y estas jerarquías no son la excepción, pueden desencadenar problemas de rendimiento o si están definidas a la ligera se termina con muchas implementaciones vacías o con clases abstractas que lo resuelven todo por si solas y son difíciles de mantener. El reuso descontextualizado, aquel que se hace porque en alguna otra parte tambien se hace lo mismo, aquel que no define límites sobre las responsabilidades de los componentes suele terminar una desestabilidación continua de nuestros desarrollos en los que se corrige una funcionalidad y se dañan otras.

Concentrando responsabilidades


Es importante que existan en nuestras soluciones entes u objetos especializados en el procesamiento de cada tipo de información esto hace más fácil el mantenimiento de las aplicaciones ya que crea puntos específicos para la actualización de las características. Se debe evitar tener múltiples objetos que efectúan operaciones de la misma naturaleza, por ejemplo tener varias clases de acceso a datos tiene como consecuencia que frente a un requerimiento de un cambio específico en la forma de acceder a los datos abarcará múltiples elementos de la aplicación, creando la necesidad de modificar el desarrollo en varios puntos aumentando la posibilidad de agregar errores adicionales.

TEMAS DE PRESENTACIÓN


Diseñar la forma en la que una aplicación se verá es una tarea más compleja de lo que a primera vista podría apreciarse. Esta actividad se puede realizar de diversas maneras, algunas fábricas utilizan criterios puramente estéticos y aunque el aspecto es algo fundamental para que una aplicación sea atractiva a los usuarios y comercialmente atractiva es solo una parte del diseño. En esta página no se pretende realizar un análisis exhaustivo ni académico sobre la usabilidad de las aplicaciones pero si pretende exponer algunos temas que algunas veces pasamos por alto en el diseño y desarrollo de nuestras aplicaciones.

Muchas veces vemos aplicaciones que se ven muy bien y consecuente nos resultan impactantes en principio, sin embargo, al comenzar a utilizar el software encontramos aspectos confusos debido a lo heterogéneo de la presentación. Muchas veces encontramos aplicaciones con sofisticadas gráficas y animaciones que crean una barrera al momento de utilizarlas de manera intuitiva. También existen aplicaciones con elementos de presentación que suelen ser muy sencillos pero que tienen una fuerte simbología que nos permite identificar las tareas disponibles de una manera rápida. En esta sección se presentarán aspectos importantes relacionados con la presentación que usualmente pasamos por alto.

Trabajando con Imágenes


Como se suele decir, una imagen vale más que mil palabras y esto en la construcción de aplicaciones sí que es cierto. Las imágenes en las aplicaciones están por doquier y hay una justificación en ello, una imagen puede identificar un concepto relacionado con la aplicación y elimina el esfuerzo de tener que leer por ejemplo una descripción de dicho concepto. Las imágenes suelen utilizarse para aprovechar el conocimiento previo que un usuario pueda tener del software que está utilizando, simplemente el usuario experimentado visualiza la imagen, identifica el concepto relacionado y usa dicho concepto, no tiene que leer de que se trata cada vez que lo va a utilizar. A pesar de brindar ventajas en este sentido, una aplicación debe tener en cuenta que no todos los usuarios son experimentados y que algunos se enfrentan a la herramienta simplemente utilizando su intuición. Teniendo en cuenta esto último, podríamos concluir que una aplicación bien definida debe proporcionar las dos opciones, las imágenes para los experimentados y algún mecanismo de orientación en caso de que no se tenga un conocimiento previo de las funcionalidades, entre estos mecanismos encontramos por ejemplo las barras de estado y los mensajes emergentes y muchos otros.

Las imágenes al igual que cualquiera de los elementos del producto deben ser diseñadas, usualmente por un diseñador gráfico, no debería ser trabajo del desarrollador crear o seleccionar las imágenes de una aplicación. Dicho diseño debe garantizar que existe una coherencia y uniformidad en la simbología utilizada y una clara diferenciación en los elementos visuales y su semántica  Como mínimo se podría esperar que las imágenes de un mismo grupo visual tengan el mismo tamaño, muchas veces las imágenes se construyen con un tamaño diferente al utilizado en la aplicación y luego al ser escaladas se producen distorsiones en las mismas y suelen crear diferencias sutiles que le restan profesionalismo a la construcción. Es necesario considerar que los usuarios no están pensando en imágenes cuando utilizan las aplicaciones, por el contrario su mente que identifica los conceptos de la aplicación espera que dichos elementos estén integrados con la aplicación y esto nos lleva a concluir que las imágenes con colores de fondo no deberían utilizarse en formularios de la aplicación, aunque en algunos casos podrían ser útiles como decoración para elementos emergentes. El color suele ser otro factor importante al momento de diseñar las imágenes ya que colores muy claros tienden a cansar la vista del usuario, en algunas ocasiones pueden relacionarse colores con aspectos como la peligrosidad de una acción, o acciones específicas sobre diversos elementos. Se debe tener en cuenta durante el diseño que si las imágenes utilizadas son muy parecidas el usuario deberá realizar un esfuerzo adicional al identificar la operación que requiere realizar, de manera similar no deberían existir dos elementos iguales con diferentes significados ni un mismo significado con diferentes imágenes ya que esto desorienta al usuario.

Trabajando con Mensajes y descripciones


Una parte importante de la presentación de una aplicación involucra una definición clara de los títulos, etiquetas y descripciones de los elementos de interacción presentados. Títulos poco precisos o ambiguos suelen confundir al usuario respecto a la ubicación u operaciones que desea realizar. Es importante que se examinen los títulos teniendo en cuenta algunos criterios sencillos:

Minimalidad y Simplicidad


Los mensajes presentados deben decir de la manera más simple lo que desean expresar, de igual manera se espera que un mensaje comunique de manera directa su contenido, esto es, las palabras mínimas requeridas para expresarlo. Mensajes muy largos o con más de una idea pueden confundir al Usuario novato y aburrir al usuario experimentado hasta el punto de obviar la advertencia realizada. Respecto a este punto un mensaje similar al presentado a continuación

“Confirma que desea eliminar permanentemente estos elementos?”,

Es preferible a otro como el siguiente:

“La lista de los elementos seleccionados en la aplicación será removida indefinidamente como consecuencia de la ejecución de de la operación en curso. Está seguro que desea realizar la operación solicitada?”.

Coherencia del lenguaje


Se debe tener en cuenta que un usuario normalmente utiliza software como herramienta para realizar de una manera más fácil y rápida un oficio que muy probablemente pertenezca o otra área del conocimiento distinta a los sistemas de información. Por este motivo, los mensajes y las advertencias deben estar en el lenguaje de área de conocimiento del usuario, para ilustrar un poco esto consideremos los siguientes mensajes utilizados para describir la misma situación y evalúe cual se encuentra en el lenguaje apropiado para un cajero de una pequeña tienda o almacén.

“Se ha detectado una inconsistencia de accesibilidad entre los elementos seleccionados para procesar la transacción solicitada. La cardinalidad entre los productos suministrados y sus descripciones debe ser equivalente (Uno a uno)”

“Tenga en cuenta que cada producto debe tener una y solo una descripción”

Contextualización


Los mensajes deben estar en contexto con las tareas realizadas por el usuario aunque deben ser lo suficientemente explicitos (dentro del contexto) para entender la situación. Evalúe los siguientes mensajes e identifique cual está en el contexto indicado para un usuario que se encuentra guardando un archivo.

“Seleccione la ubicación para guardar el archivo”

“Guardar”

Claridad


Por último los mensajes claros son claves para que el usuario se sienta cómodo utilizando nuestra aplicación, un problema en la claridad de un mensaje puede ser una consecuencia de una falla en los conceptos anteriormente descritos ya que un mensaje se puede hacer tan complicado o elaborado como se quiera. Por ejemplo:

“El protocolo de transferencia de archivos ha arrojado una excepción en tiempo de ejecución (0x12345) debido a un desbordamiento de la pila. Si los archivos no se han transferido, entonces se enviarán la próxima ocasión que el mecanismo de conexión se restablezca. En caso de que los dispositivos de red se encuentren disponibles”


“No se pudo establecer la comunicación para enviar los datos, se intentará reenviarlos cuando la comunicación se restablezca.”


Trabajando con opciones


Se pueden definir diferentes estrategias en la presentación de opciones al usuario, por un lado podemos optar por presentar las opciones de manera contextual, es decir en este modelo el usuario descubre las opciones dependiendo de las funciones, el área de trabajo o el contexto en el que se desenvuelve, aunque esta estrategia suele ser muy cómoda para el usuario representa un esfuerzo adicional en la construcción y un exceso de contextualización puede confundir al usuario sobre la localización de las opciones. Por otro lado se pueden agrupar según los tipos de características ofrecidas y visualizar los grupos de manera estática, por ejemplo, podemos colocar todo lo relacionado con la configuración en un grupo de “Opciones” y todo lo relacionado con el manejo de archivos en “Archivo”. Pueden mezclarse los métodos mencionados anteriormente para lograr una eficiencia en la presentación de opciones, esto debe hacerse con cuidado para no saturar al usuario con la redundancia introducida y consecuentemente las opciones definidas en las diferentes formas deben ser representadas visualmente de manera única para evitar confusiones.

Diseñando la usabilidad


Diseñar la usabilidad de una aplicación puede ser todo un reto, a pesar de no tener un impacto en los resultados de la construcción, la usabilidad brinda confort a los usuarios. A medida que simplificamos más los elementos de interfaz de usuario, es decir a medida que hacemos más sencillas de usar a nuestras aplicaciones, la complejidad interna puede aumentar para soportar estos aspectos. Algunas características son claves para incrementar la usabilidad de una aplicación, por ejemplo el número de clics que un usuario debe efectuar para realizar una tarea específica es clave para la usabilidad. Por otro lado hacer que nuestra aplicación tenga la mayor cantidad de información disponible para su uso suele ser otro factor determinante para la comodidad de los usuarios sin incurrir en excesos. La distribución del espacio, la distancia entre los elementos visuales y su agrupación también aportan un gran valor al momento de operar un sistema de información.

Importancia de la Usabilidad


En muchos casos la usabilidad de una aplicación se ve reflejada y dirigida en el rendimiento operativo de los usuarios y es por esto que las características de usabilidad pueden impactar en gran medida la productividad del sistema de información. Para entender un poco más de que hablamos podríamos considerar como ejemplo un centro de atención telefónica que cumple con las siguientes condiciones:

· Los clientes se contactan con asesores por ejemplo para efectuar un proceso de actualización de datos.

· Los clientes suelen ser impacientes y es muy probable que éstos tengan un umbral o límite en el tiempo de espera que asumen es necesario para procesar su solicitud, si esperan demasiado, se aburren y simplemente declinan la operación.

· Considere entonces que un asesor puede recibir muchas llamadas y que utiliza una aplicación para registrar los datos proporcionados por el cliente, mientras más se demore en procesar los datos de un cliente menos clientes podrá atender en un tiempo determinado por ejemplo de una hora.

· Asuma que de manera adicional la compañía de asistencia telefónica realiza su facturación dependiendo del número de clientes satisfechos atendidos o del número de registros actualizados.

· Probablemente la empresa no se haya dado cuenta, pero existe un problema de usabilidad de la aplicación utilizada para ingresar la información en la base de datos.

· El problema consiste en que el usuario debe realizar un clic sobre cada campo cada vez que desea ingresar información para dicho campo y no dispone de una forma directa para llenar la información y continuar con el siguiente.

Teniendo en cuenta las condiciones mencionadas anteriormente podríamos efectuar la siguiente reflexión sobre el funcionamiento de la empresa:

Si para llenar cada valor el usuario gasta un segundo (1) adicional al tiempo de escritura para abandonar el teclado, tomar el ratón y regresar al teclado, y los datos del usuario son por ejemplo veinte campos, el usuario perderá 20 segundos por cada actualización, si la actualización de los datos se estima en promedio en un minuto (60s) el usuario estaría perdiendo la tercera parte del tiempo. Esto nos indica que realizar una simple corrección en la usabilidad de la aplicación nos permitiría triplicar el volumen de clientes atendidos en un minuto. Si la empresa pierde este tiempo en un asesor pasaría inadvertido, sin embargo si el centro de soporte cuenta con un equipo de 40 personas y todas tienen el mismo comportamiento en el uso ya que todos los individuos operan la misma aplicación, la empresa podría estar perdiendo una suma significativa de dinero al momento de realizar la facturación.

En algunos casos la usabilidad puede impactar en el confort de los usuarios y aun así no tener un impacto de esta magnitud, sin embargo un usuario que encuentra difícil de utilizar un producto eventualmente lo abandonará para adquirir otro que le haga las cosas más fáciles.

Definiendo parámetros de usabilidad


Teniendo claro los factores mencionados anteriormente, se debe tener una clara expectativa en términos de usabilidad. Se deben definir al menos los siguientes aspectos respecto a la funcionalidad construida:

¿La productividad del negocio se puede ver directamente asociada con la facilidad de uso de nuestra aplicación? Aunque en muchos casos esta situación puede presentarse, en muchos otros casos la productividad puede estar acotada por los tiempos del proceso del negocio y consecuentemente pasar a un segundo plano, de todas maneras es muy importante que se tenga claro el impacto de la usabilidad de un sistema de información en las operaciones del negocio.

¿Se han identificado las tareas más comunes a realizar por los usuarios? De una aplicación suele esperarse que las tareas más comunes se realicen con mayor rapidez que aquellas que se producen de manera eventual. Si no se han identificado cuales son las operaciones más comunes la construcción de la aplicación puede terminar siendo muy usable en las cosas que no se utilizan con frecuencia por lo que los usuarios tendrán las mismas dificultades que si no se hubiera diseñado el uso.

¿Las funciones más utilizadas están disponibles en localizaciones cercanas al área de trabajo relacionada? La cercanía de las operaciones ayuda al usuario a concentrarse en el trabajo y no a buscar donde se encuentra la función que desea utilizar. Un ejemplo clásico de esto es un editor de texto en el que no se puede obtener un menú de opciones comunes mientras se encuentra ubicado en el área de edición.

¿Existe un comportamiento común para la funcionalidad implementada en otras aplicaciones? En algunos casos los usuarios perciben dificultades al momento de utilizar cierta característica debido a que poseen costumbres asociadas a otras aplicaciones, por ejemplo, un editor de texto en el que no se pueda copiar texto seleccionado realizando clic derecho o presionando CTRL-C, es probable que un usuario lo encuentre difícil de utilizar ya que casi todos brindan esta característica.

¿Se han identificado las preferencias de dispositivos de interacción?Al momento de diseñar la usabilidad de nuestra aplicación debe tenerse en cuenta que no todos los usuarios tienen las mismas preferencias sobre los periféricos de entrada, algunos utilizan en exceso el ratón otros prefieren realizar la mayoría de las operaciones con el teclado, otros lo harán por smartphones o tablets. Tenga en cuenta que abarcar la mayoría de opciones no solamente le ayudará a la aplicación a adaptarse a las costumbres del usuario sino que también brindará opciones importantes al momento de faltar uno de ellos en caso por ejemplo de que se haya dañado el ratón a media noche y se tenga que entregar un informe a la mañana siguiente.

¿Los elementos de interacción con el usuario que se han seleccionado permitirán un mínimo de esfuerzo para su utilización? Muchas veces encontramos aplicaciones que presentan opciones de maneras equivocadas, por ejemplo una lista desplegable que solo tiene dos opciones, si y no lo único que logra además de la reducción del espacio es agregarle trabajo adicional a un usuario de descubrir cuáles son los elementos de la lista, mientras que sería más apropiado tener una casilla de chequeo que presente una sola opción activada o desactivada. Si los valores pueden ser escogidos de una lista, entonces poner a escribir la información al usuario únicamente le agrega más trabajo y si la lista es estática y no supera el número de 5 items entonces es mejor presentar las cinco opciones con una selección excluyente así al usuario no le toca realizar un clic adicional para descubrir el contenido de la lista. Existen muchas formas de equivocarse en la selección de los elementos, y en muchas ocasiones estos ocurren debido a la facilidad de integración de algunos componentes que es atractiva para reducir tiempos en la construcción por parte de los desarrolladores, sin embargo lo que es bueno para los desarrolladores no necesariamente es bueno para los usuarios.

¿Se han considerado los distintos tipos de usuario y sus límites en el diseño? El diseño de la usabilidad de una aplicación podría estar afectado por las expectativas de productividad para distintos grupos de usuarios, por ejemplo se puede definir que el 40% de los usuarios nuevos deben poder instalar el producto en menos de 15 minutos sin ayuda alguna, o puede definirse que el 80% de los usuarios experimentados deben ser capaces de construir un documento pequeño completo en menos de 10 minutos. Este tipo de consideraciones nos permiten direccionar el rendimiento de la aplicación hacia el tipo de usuarios que son más importantes para nosotros.

¿Se han involucrado en el diseño de usabilidad a los usuarios finales de manera previa a la construcción? No hay nada peor que el esfuerzo y el trabajo perdido, y en algunas ocasiones los diseñadores y desarrolladores definen formas de interacción con el usuario que no han sido consultadas ni aprobadas por los mismos, esto redunda en un esfuerzo en vano y un rechazo frente a una funcionalidad esperada de cierta manera por los usuarios de la aplicación. Es importante que una vez se haya diseñado la forma en la que los usuarios interactuarán con la aplicación se someta a la aprobación por parte de los mismos para evitar construir algo que no obedezca a las expectativas de uso de quienes finalmente utilizarán la aplicación.

Construyendo Interfaces intuitivas


Un aspecto fundamental en el diseño de la usabilidad de una aplicación es la capacidad que brinda el software construido para ser comprendido y aprendido por el usuario en una manera eficiente, se espera que un usuario pueda intuir el funcionamiento básico de una aplicación sin un conocimiento previo de los elementos visuales, de igual manera se espera que un usuario experimentado pueda identificar de manera eficaz las acciones a realizar. Para lograr esto de manera eficaz se requiere que se diseñen opciones de presentación de mensajes que le permitan a un usuario novato consultar las funcionalidades, una forma muy común de lograrlo es utilizar mensajes emergentes (tooltips) que se presenten al posicionarse en los elementos visuales, en algunas ocasiones también se pueden presentar descripciones sobre las opciones de la aplicación en barras de estado o con menús emergentes con opciones como“Que es esto?” aunque esta opción personalmente no me gusta mucho. Los mensajes deben ser lo suficientemente descriptivos para que el usuario novato comprenda de qué se trata la opción adecuada. De la misma manera, las acciones que puedan comprometer datos o tener consecuencias irrecuperables deberían presentar mensajes de confirmación que le permitan al usuario nuevo entender las consecuencias de la acción que está por efectuar.

Es importante que una aplicación le permita al usuario comprender el estado y el contexto en el que se encuentra trabajando para que de esta forma pueda tomar las decisiones pertinentes, por ejemplo si un usuario está efectuando una tarea que implica un largo tiempo de procesamiento debe presentarse algún indicador sobre el progreso de la operación, de otra manera el usuario no comprenderá lo que está sucediendo y eventualmente buscará la manera de deshacerse del programa en ejecución lo que para algunos procesos pueden resultar en consecuencias desastrosas. Se pueden presentar barras de progresión o imágenes y mensajes que indiquen que existe una operación en proceso.

Hay que tener en cuenta que a veces es conveniente que las pantallas tengan un comportamiento dinámico, esto debe realizarse con moderación ya que una presentación muy cambiante puede despistar y confundir al usuario sobre la ubicación de las funcionalidades, al momento de dinamizar el comportamiento de una pantalla de captura por ejemplo prefiera presentar componentes inactivos en vez de ocultarlos, si están inactivos el usuario sabrá que no se encuentran disponibles pero tendrán una idea clara de la ubicación de dicha funcionalidad mientras que si se ocultan la mente del usuario no relacionará la funcionalidad oculta con su localización dentro de la aplicación lo cual logrará que en futuros usos tarde mas en identificar donde se encontraba.

Captura de Datos


Algunos desarrollos presentan problemas en la captura de datos, en algunos casos debido al exceso de ventanas modales anidadas durante el proceso de captura de datos específicos de una aplicación. Hay algo que es necesario entender sobre las ventanas modales, estas sirven como instrumento para sincronizar la entrada de la información y evitar estados inconsistentes debido a ingresos paralelos, sin embargo, para capturas de datos jerárquicas esto suele incluir algunos problemas de usabilidad, entre dichos problemas podemos encontrar la pérdida de la visión global de los datos de entrada dentro de la jerarquía. Para entender esto pensemos en el siguiente ejemplo, imagine una ventana modal que tiene dos botones, cada botón presenta una nueva ventana modal que nos impide ver la información en la ventana anterior, en este caso el usuario incurre en un sobre esfuerzo ya que es probable que para tomar una decisión deba consultar un dato de la ventana padre, para esto deberá mover la ventana para visualizar dicha información. Ahora supongamos que esta segunda ventana tiene una tercera anidada o ventaja hija, teniendo en cuenta que cada ventana bloquea las acciones de la anterior, el usuario podrá mover la tercera ventana para visualizar los datos de la segunda, sin embargo, si deseara visualizar información en la ventana principal, el usuario deberá cerrar la tercera ventana y mover la segunda. A medida que se agregan más cuadros de dialogo anidados se hace más difícil utilizar la aplicación. Una solución a este problema es utilizar un modelo coherente de los datos que se están solicitando y diseñar una única forma que permita administrar la jerarquía, por ejemplo con un árbol que presente la jerarquía y una ventana de propiedades cambiante según la posición dentro del árbol, de esta manera si un usuario se encuentra ubicado en a tres niveles y desea saber la información en el nivel superior con un solo click se puede trasladar hasta el nodo principal, en la mayoría de los casos puede presentarse toda la información en la misma ventana sin que se sature mucho la interfaz de usuario.

La captura de los datos suele requerir validaciones para garantizar que los datos solicitados tengan cierto nivel de consistencia. La presentación de errores debería nuevamente minimizar la presentación de cuadros de mensajes en los que no se toma ninguna decisión, esto suele ser incomodo para un usuario ya que debe realizar un clic adicional cada vez que se equivoca debido a la presentación del cuadro de mensaje. Una estrategia que simplifica este tipo de problemas es agregar una etiqueta o lista dentro de la misma ventana que presente todos los errores dentro de los datos ingresados. No utilice mensajes genéricos como el “campo es inválido” el usuario poco experimentado necesitará información adicional para resolver el problema, a cambio de esto puede complementar el mensaje por ejemplo diciendo “El valor del campo XXX debe ser un número válido”.
Espero que las sugerencias plasmadas en este documento por muy sencillas que parezcan sean tenidas en cuenta para poder cada dia mas disfrutar de una mayor comodidad en nuestros quehaceres informáticos. Adicionalmente agradezco su participación en el desarrollo de estos contenidos y espero sus comentarios.

lunes, 8 de octubre de 2012

SOBRE EL SOFTWARE Y OTROS PROBLEMAS

Antes que nada, gracias a todos los lectores con paciencia para revisar los conceptos expuestos en las entradas expuestas.  Espero que las mismas sean de utilidad para mis lectores.

SOBRE EL SOFTWARE Y OTROS PROBLEMAS

Una situación muy común en el desarrollo de software que vemos por montones en empresas de tecnología es la ausencia de los propósitos específicos en la construcción, muchas empresas esperan obtener buenos resultados en su construcción, sin embargo sienten que por más esfuerzo que se invierta en el desarrollo, el software resultante carece de calidad o produce errores no previstos, sienten que soportar las funcionalidades existentes es una pesadilla y al mismo tiempo quieren que su software crezca a medida que avanzan las exigencias de los usuarios.  Este tipo de situaciones lo que evidencian es una clara falta de estructura y desconocimiento sobre lo que hacemos, a continuación se presentan algunas preguntas que suelen ser claves en la adquisición de este conocimiento y que pueden representar la diferencia entre alcanzar el resultado que deseamos y fracasar en el intento.

¿Qué es nuestro producto?


Toda empresa debe saber de manera clara a que se dedica, si no sabemos lo que queremos no debe extrañarnos que no obtengamos lo que deseamos.  Esto lo entienden personas sin educación especializada que administra un negocio familiar, si se le pregunta, probablemente su respuesta sea “fabrico zapatos” o “fabrico trajes”.  Aunque el software es un tanto más difícil de definir ya que el concepto toma diferentes significados dependiendo de las soluciones que este brinde a los clientes, el caso de la producción de software no es la excepción, si pensamos que el resultado de nuestras operaciones es un conjunto de líneas de código que implementan diversas funcionalidades, probablemente no hemos definido apropiadamente nuestro producto.  El código fuente de una aplicación es sólo una parte de nuestra fábrica, una parte muy importante ya que nuestro trabajo se ve reflejado de manera directa en su funcionamiento, sin embargo, un código fuente que requiere ser modificado permanentemente  incrementa los costos al momento de hacerlo crecer,  un código fuente que ha sido el resultado de solucionar situaciones particulares de negocio probablemente no tenga la generalidad necesaria para ser extensible a mediano plazo.  Un código fuente que se ha creado de manera tal que no se puedan sacarse conclusiones sobre la forma en la que ejecutamos nuestras tareas es un artículo que únicamente ha generado valor a los usuarios finales y nos ha impedido adquirir un nuevo conocimiento sobre la manera en la que hacemos las cosas. Un código fuente cuya calidad no es susceptible de cuantificarse suele representar un problema frente a futuros cambios.  Un código fuente carente de documentación crea problemas potenciales de dependencias de recursos humanos, mala comunicación y rendimiento frente a cambios imprevistos de personal.  Todos estos aspectos tienen sus consecuencias en los costos de implementación del mismo.

Por las razones mencionadas anteriormente y muchas otras es necesario que tengamos una visión clara de lo que esperamos producir que en el caso de software, evidentemente es algo más que simples líneas de código en un sistema de administración de versiones.  Para definir sin ambigüedades lo que espera que sea su producto tenga en cuenta los siguientes puntos:

·         Qué problema general del mundo real se resuelve con la aplicación del producto realizado?

·         Cuál es el público objetivo beneficiado de la utilización del producto?

·         Que características agregan mayor valor al producto?

¿Con que contamos?


Algo importante para alcanzar el producto definido previamente es tener una idea realista de los recursos con los cuales contamos, muchas pequeñas empresas establecen sus expectativas al nivel de otras empresas que llevan mucho tiempo, años de experiencia en el desarrollo de software y mucho más personal estructurado y trabajando en equipo de manera coordinada.  Esta situación inevitablemente nos llevará a un sobre esfuerzo (posiblemente inhumano) o a un resultado fallido en nuestro proceso de construcción. 

Con lo anterior no queremos decir que deba redefinir su producto por uno con un menor alcance, lo que se pretende es mostrar que existe un conjunto de limitaciones sobre cuanto podemos producir.  Aunque no cuente con los recursos necesarios para asistir a todos los aspectos relacionados con su producto, Usted siempre tendrá la opción de hacer lo mínimo (siempre que se haga bien) y postergar las oportunidades de mejora sobre el producto.  Tenga en cuenta que postergar significa en este contexto que deberá idear un plan y fijarse unas metas para poder alcanzar el objetivo, significa que se ha cambiado la prioridad a estas oportunidades y no que se hayan descartado.  A medida que pase el tiempo debemos tratar de darle una prioridad cada vez mayor de otra manera nunca realizaremos estos trabajos postergados.

Si se le pregunta a un fabricante de zapatos cuantas suelas tiene, cuántos trabajadores tiene, cuanto cuero le queda, si tiene martillo o no, probablemente éste le contestará de manera inmediata y esto se debe a que para la elaboración de sus productos se tiene inventariada la materia prima, las herramientas, y mucho mas, esto nos permite estimar cuantos zapatos es capaz de producir dicha fábrica.  De igual manera en la construcción de software es conveniente contar con un inventario que nos ayude a inferir la cantidad y la calidad de lo que podemos producir en un momento dado.  Para poder realizar esto de manera efectiva, tenga en cuenta que la materia prima de un equipo de desarrollo de software son el conocimiento, las habilidades y el talento humano de los miembros del equipo, hecho por lo cual deberíamos conocer los aspectos mencionados anteriormente en detalle.  Tenga en cuenta que la cantidad y la calidad de las características generadas no son necesariamente proporcionales al número de miembros del equipo de trabajo, esto se puede explicar por el desconocimiento de las habilidades que redundan en malas asignaciones en la construcción o simplemente por los errores introducidos por la interacción y la mala comunicación entre los miembros del equipo de trabajo.  Existen proyectos, por ejemplo, con funcionarios extremadamente calificados que realizan sus asignaciones o tareas de trabajo en tiempo record y al momento de integrar todo en una misma solución el proyecto se alarga de manera estrepitosa,  esto suele ocurrir debido a una distribución inapropiada o a la poca claridad de las responsabilidades individuales teniendo en cuenta su función dentro del desarrollo colectivo. 

De una manera bien estructurada, la fabricación de productos de software puede crecer a medida que se incrementa la mano de obra, de otra forma simplemente se incurre en sobrecostos y se extienden las fechas de entrega.

Pero no solo necesitamos personas y una estructura organizacional, también necesitamos las herramientas, si ya contamos con herramientas especializadas no hay problema, sino, deberemos definir si contamos con recursos económicos para adquirirlas o si podemos hacer uso de herramientas gratuitas disponibles en internet.

¿Cómo lo hacemos?


Definir la forma en la que vamos a realizar nuestras operaciones suele ser inicialmente una tarea ardua y compleja, sin embargo, en el tiempo se mejoraran los procedimientos a medida que se vayan identificando las necesidades de nuestro equipo de desarrollo.  Defina un plan de mejoramiento continuo sobre sus procesos, esto estará allí recordándole que existen oportunidades de mejora sobre dichos procedimientos.  Cada vez que finalice una construcción identifique aquellas cosas que fueron muy útiles  en el proceso y las que causaron problemas, intente darle un orden viendo las actividades como un todo.

¿Qué aprendemos de lo que hacemos?


Pareciera que muchas empresas de tecnología trabajan arduamente y obtienen los resultados esperados en algunas ocasiones, sin embargo, notamos que muchas veces se comienzan a producir errores en los procedimientos que han ocurrido anteriormente.  En algunas situaciones no se cuenta con el tiempo o los recursos suficientes para tomar medidas al respecto, algunas veces es simplemente falta diligencia en la toma de decisiones.  Todos estos temas pueden estudiarse con una simple pregunta ¿Qué aprendemos de lo que hacemos?  Esta parece una pregunta sencilla pero que puede ser muy difícil de responder si no tenemos la disposición suficiente para autoevaluarnos. 

Aprender de lo que hacemos puede ayudarnos  en los siguientes aspectos:

·         Nos brinda posibilidades para mejorar nuestros procedimientos y encausarlos por una dirección que esté alineada con los objetivos de la construcción.

·         Nos ayuda a aprender a detectar donde están las fallas de dichos procedimientos para poder establecer planes para corregirlas.

·         Nos permite agrupar las experiencias y de esta manera identificar áreas de interés común.

·         Nos permite establecer procedimientos claros frente a situaciones particulares para poder invertir nuestros esfuerzos en aspectos importantes del negocio.

·         Nos lleva a cuestionarnos sobre otros aspectos en los procedimientos que anteriormente no hubiéramos tenido en cuenta.

Esta pregunta puede dividirse en muchas otras dependiendo de la naturaleza del negocio.  Por ejemplo, podríamos preguntarnos ¿Qué hemos aprendido de nuestro manejo con los clientes?  Esto nos ayudará a mejorar nuestra relación con los mismos y consecuentemente se reflejará finalmente en su satisfacción y lealtad.  Muchas compañías invierten cantidades significativas de su presupuesto en sistemas de información para la administración de las relaciones con los clientes y aún así fracasan en sus estrategias, esto se debe a que no basta con tener los datos,  no basta con tener la infraestructura sino que adicionalmente toca comprender de manera objetiva la información.  

Otra pregunta que podríamos hacernos es ¿Qué hemos aprendido de nuestros costos?  Muchos proyectos de tecnología podrían verse como “agujeros negros de capital” ya que se invierte en personal calificado, se invierte en recursos, se invierte en tecnología y aun así los tiempos de construcción se alargan hasta el infinito lo que finalmente se refleja en los costos de la construcción.  Este tipo de proyectos suelen consumir todos los recursos invertidos y perderlos sin ningún resultado, esto puede ser consecuencia de un riesgo asumido durante las negociaciones previas a la construcción o a ideas mal definidas o poco claras sobre lo que se espera de dicha construcción.  Una mala o excesiva gestión de los requerimientos podría también impactar significativamente en los tiempos de implementación.  Una fábrica podría operar de esta forma en los desarrollos iniciales, sin embargo si esto se vuelve recurrente probablemente no estamos aprendiendo nada de lo que hacemos con nuestras inversiones.  

¿Qué hemos aprendido del trabajo en equipo?  El trabajo en equipo suele adoptar diferentes formas en una organización, esto se debe a factores externos tales como las relaciones interpersonales,  aspectos culturales colectivos e individuales.  Identificar puntos de falla y buenas prácticas en nuestro trabajo de equipo nos ayudará a ser más productivos, a reestructurar ciertas áreas y a visualizar algunas que antes no se tenían previstas. De manera adicional aprender de nuestro trabajo en equipo nos ayudará a identificar habilidades dentro de nuestros grupos de trabajo y de esta manera tener una base experimental a partir de la cual se puedan asignar de una manera coherente las responsabilidades dentro de los miembros de la organización, de otra forma termina Albert Einstein siendo un secretario de la recepción y personas menos capacitadas o menos interesadas en la administración dirigiendo aspectos fundamentales sin ningún rumbo.

¿Qué hemos aprendido de las negociaciones?  Aparentemente cada negociación es única y depende de muchos factores en la mayoría circunstanciales por lo que es difícil tratar de predecir como resultarán, sin embargo, es necesario que se adopten políticas dependiendo del aprendizaje previo, de no verse de esta forma se corre el riesgo de tener negociaciones que redunden en pérdidas para la fabrica.  Resolver esta pregunta es vital para tener una base sobre el comportamiento de nuestras negociaciones y poder tomar acciones correctivas y definir estrategias  que nos ayuden a crecer en estos aspectos.

¿Podemos medir nuestros productos?


Como podría un zapatero tener utilidades numerosas si no sabe cuánto material gasta en la construcción de un articulo?  ¿Cómo podría el mismo saber cuánto puede producir si no conoce su inventario? ¿Cómo puede establecer el precio del artículo si no conoce las diferencias en calidad y esfuerzo invertido para cada uno de sus modelos?  Estas preguntas nos llevan a entender que mientas más información tengamos de nuestros productos y nuestros procesos podremos darle el valor.  En el caso de la construcción de software una fábrica que no conoce la arquitectura ni el estado de su código fuente, que no puede medir la producción o que no puede cuantificar la calidad de sus desarrollos es una fábrica que trabaja a ciegas, con una incertidumbre muy alta y esperando siempre resultados fantásticos.   Para tener una visión apropiada al respecto, debemos pensar primero en nuestras métricas, saber que deseamos medir y  como repercuten las mejoras a dichas métricas en el objetivo final de nuestra fábrica. 

¿Podemos medir nuestros procedimientos?


En nuestra fábrica podemos medir el tiempo para realizar todas las tareas requeridas para la producción del software?  Probablemente el zapatero si lo sabe. En muchas ocasiones los gerentes de proyectos de tecnología no conciben la idea de no poder estimar cuanto tomará en tiempo por ejemplo la definición de los requerimientos de determinada aplicación, o cuanto tomará en recursos la construcción de un módulo o una funcionalidad. 

¿Podemos predecir los impactos? ¿En cuántos Niveles?


Predecir el impacto que pueda producir un cambio sobre una solución no es una tarea fácil si no se tiene una idea general suficientemente clara de la estructura de nuestros desarrollos, existen relaciones y reglas conceptuales o implícitas entre las componentes de nuestro producto que no se reflejan de manera directa en la programación y mientras menos información se tenga sobre las dependencias de cada uno de los componentes que conforman la solución o conjunto de soluciones, será más difícil estimar dicho impacto.  El diseño dirigido por modelos arquitectónicamente bien construidos suele ser una aproximación interesante y poderosa al momento de asignar e identificar claramente dependencias entre componentes con distintas responsabilidades. 

Como usualmente ocurre, una solución por software a un problema general estará compuesta de un subconjunto de problemas particulares e independientes que de manera conjunta interactúan para dar una solución completa a un caso de negocio específico.  De esta manera algunos estructuran el software en capas, otros en anillos, otros por funcionalidad, sin embargo, parece que no importa de qué manera delimitemos las componentes de nuestro desarrollo, siempre debería ser posible cuantificar cuantos niveles se afectarían por los cambios realizados.   Si ya tenemos el conocimiento sobre el número de dependencias sobre los componentes de la solución, entonces debemos dar el siguiente paso, y este consiste en diagnosticar los segmentos de código que podrían presentar efectos indeseados.  Posteriormente se presentan algunas estrategias para combatir este tipo de problemas.

¿Tenemos problemas heredados del pasado? ¿Cómo los combatimos?


Los problemas heredados del pasado suelen ser una de las causas más relevantes de resistencia a cambios al momento de revaluar la arquitectura de un producto.  Si se plantea reestructurar una solución de software, pensamos inmediatamente en problemas de arquitectura que se presentan actualmente debido a correcciones del pasado que aún se soportan.  Como combatimos estas circunstancias?  Una forma es separar la implementación comercial de la implementación reestructurada.