sábado, 4 de septiembre de 2021

Todo lo que quiero hacer es mantener la cabeza baja y escribir código. ¿Por qué es eso un crimen en tantas empresas?



Este post es una copia de una respuesta que di en Quora a la pregunta   “Todo lo que quiero hacer es mantener la cabeza baja y escribir código. ¿Por qué es eso un crimen en tantas empresas?”, y que se me hizo interesante el tema sobre todo por los temas que hemos tratado en el blog.


Porque la mayoría del software empresarial actual no puede ser desarrollado por una sola persona, y en el caso casi imposible que sea así, necesitara mantenerse y dicho mantenimiento debe ser completamente independiente del codificador que lo escribió.

Tienes que tener en cuenta que el trabajo de los desarrolladores (empresariales) de software, no es crear software, sino resolver necesidades a través de la creación   de   software, Para comprender dichas necesidades, hace falta tener habilidades de comunicación y trabajar en equipo.


Una de las cosas en las que más se batalla como jefe de proyecto es lo que yo llamo las "tareas de escuela". Es cuando se asignan tareas a   programadores, y te dan soluciones técnicamente correctas pero que no resuelven el problema que supone que deben resolver, es decir lo toman como si fuera una "tarea de escuela" y resuelven al pie de la letra lo que se les pide, sin plantearse porque lo están haciendo y sin ver un motivo practico para ello. Al final estas piezas de código, no encajan con el resto del código, y no resuelven realmente una necesidad de negocio

Siempre puedes tener un líder de proyecto o incluso un programador sr, que te diga paso a paso que hay que resolver y como lo quiere, hasta que consigas lo que necesita la empresa, pero trabajar con codificadores así es muy costoso, y en el fondo poco práctico, acaba cansando (y frustrando) a todas las partes implicadas.



Recomiendo los siguientes enlaces, para tener una idea clara del trabajo empresarial y las relaciones entre los distintos elementos de un equipo.


sábado, 26 de junio de 2021

A 20 años de la creación del manifiesto ágil


En febrero del 2001, varios programadores algo ya hartos de la forma de desarrollar sistemas tradicional y queriendo mejorar por un lado calidad del software y los sistemas y por el otro (y sobretodo) reivindicar el valor de la figura de programador crearon los que se conoció como manifiesto ágil.



Las metodologías de desarrollo de software nacido de la adopción de otras metodologías, pertenecientes a industrias y mercados que llevaba vigentes muchos antes que la creación de sistemas. A pesar de eso el desarrollo del software y su alcance ha aumentado de forma más rápida que cualquier otra industria. Realmente se podría decir que las necesidades del desarrollo de software, han crecido más que la capacidad de adaptarse de los desarrolladores para hacer software.

Originalmente (o más bien en la década setenta), cuando se vio que el desarrollo del software iba a ser imprescindible en el futuro (de una forma u otra) se comenzaron a usar varias metodologías y procesos para la construcción de este. Hay que considerar, que tanto el desarrollo del software, así como el mismo hardware eran recursos muy caros, y frecuentemente de difícil acceso.

Antecedentes clásicos relacionados con la programación



  • Creación de FORTAN en 1954, con un enfoque matemático y científico practico.

  • Creación de COBOL en 1960, con un enfoque hacia los negocios y una clara intención de vender las ventajas de programación a las empresas. Fue un lenguaje usado en los bancos de forma casi exclusiva hasta principios de los 2000.

  • Creación de BASIC en 1964, creado con intención de hacer más humana y accesible los conceptos de programación. Fue extremadamente popular en los 80, donde prácticamente cada ordenador personal tenia instalo una versión de BASIC

  • Gestación de la programación estructurada, durante toda la década de los 70: Una nueva visión de la forma de programar que abogaba (entre otras cosas) por la eliminación de programación goto.

  • Creación de Pascal en 1969: El lenguaje de programación que mejor implemento la programación estructurada, y uno de los más limpios y claros existentes. Tuvo varias evoluciones y actualmente es raro verlo implementado de forma empresarial.

  • Creación de C en 1970, A fecha de hoy una de los lenguajes más importantes, y inspiración de multitud de lenguajes actuales.

  • Creación de Unix en 1970: Uno de los sistemas operativos mas importantes y igualmente fuente de inspiración para multitud de sistemas operativos.

  • Creación de C++ en 1983: Extensión del lenguaje C, con multitud de nuevas características, además del uso de programación orientada a objetos, extendiese su uso bastante en los 80 y sobre todo en los 90, se en la base de multitud de sistemas y desarrollos.

  • Creación de SQL en 1986, Estándar para realizar consultas a las bases de datos, independiente del motor de esta y de los sistemas de la consulta. Se extendió su uso masivamente en los 90. El hecho de proporcionar una abstracción entre los datos y los programas, fue un hito importante, en una nueva concepción de cómo debieran estructurarse los sistemas.


Las necesidades y lenguajes iban evolucionando en los 70, 80 y 90. También debemos entender que realizar software era complicado, muchas veces debiendo aprender sobre la marcha e intentando adaptar métodos y formas propias de otras ramas, que no tenían por qué funcionar en el desarrollo de software.

Antecedentes que ocurrieron en los años 90



  • Implantación de Windows: Si bien Windows se gesto creo en los 80, su versión Windows 95 fue una atentica revolución, tanto en nivel mediático como en la amplitud de los hogares que tuvieron este sistema instalado en sus computadoras.

  • Regreso de Steve Jobs a Apple: Después de su despido en los 80, Steve Jobs regreso en 1997 a una Apple, que había perdido completamente su brillo y empuje inicial. Después de ciertas alianzas (algunas algo muy sorpresivas como con Microsoft) y de cambiar la visión y su enfoque comercial, tuvieron (y tienen) un gran impacto en la computación domestica, celular y la industria del entretenimiento de las dos siguientes décadas.

  • Programación Extrema (XP): Creada a finales de los 90, y predecesora inmediata de las metodologías agiles. Implica (entre otras cosas) la simplificad del código, la comunicación efectiva entre los codificadores y el cliente y de la importancia de las pruebas unitarias

  • Java: Java es un lenguaje/arquitectura creada en el 1996. En los 90 era muy popular el uso de C, C++ (y ASM), para la generación de programas y sistemas embebidos, pero tenía varios problemas y es que cada sistema operativo y dispositivo tenían su propias librerías, tamaños de números (y punteros), gestores de memoria y de hardware, lo que hacía que un programa escrito en C (o C++), fuera incompatible con otro. El nacimiento de Java prometía que un programa sería compatible con multitud de dispositivos, fue creado de cero con una inspiración clara de de C++, pero quitando todo lo que hacía difícil y propenso a fallar, con la intención de simplificar el desarrollo de software. En las siguientes décadas fue un lenguaje muy importante en el desarrollo WEB, en la renovación de los sistemas empresariales (principalmente en el sector bancario), y de diversas formas en los dispositivos móviles, igualmente (y a aunque no fueron los primeros en hacerlo), en el uso de componentes desplegables e instalables fácilmente desde internet. Popularizo a que fuera un lenguaje en que siempre encuentras una herramienta (o frameworks) para resolver casi cualquier problema.

  • Visual Basic: Microsoft tiene una relación muy estrecha con BASIC, fue uno de los primeros programas que vendió y ha incluido durante años versiones de Basic en sus sistemas operativos (GWBASIC, QBASIC, QuickBASIC). Visual Basic Clásico estuvo disponible desde el 92 hasta el 98, donde fue adoptado por muchas empresas para la creación de software, como puntos positivos presento un IDE muy sencillo de manejar, una serie de componente gráficos ampliable y fáciles de implementar, y sobretodo un esquema de acceso a base de datos unificado llamado ADO, común para cualquier motor de base de datos.

  • Efecto 2000: Originalmente y al ser la memoria un recurso limitado se usaban solo dos dígitos para representar el año de las fechas, por ejemplo 80, era 1980, esta circunstancia provocaría que los sistemas asumieran que él año 2000, era erróneamente el años 1900, provocando problemas en el manejo de las fecha, los plazos y el tiempo. Así se crearon muchos sistemas y lenguajes de programación. Entre estos lenguajes estaba COBOL, que era además el más usado en los sistemas bancarios (donde las fechas son realmente muy importantes), si bien se parcharon con más o menos dificultad los sistemas (al final el tan anunciado efecto no fue para tanto), Provoco como efecto colateral que hubiera una migración hacia otras tecnologías y sistemas, además de otras visión de cómo como debiera consumirse el software y las aplicaciones siendo más móvil, mas des localizado, interconectado y sobretodo mas usando entre la población general, convirtiéndose a fecha actual, en algo imprescindible en sus vidas

  • Internet y la WWW: Aproximadamente en el 92 se crea la WWW y unos años después se crea comienza a difundir domestica internet a través de un boom de proveedores comerciales. Inicialmente el contenido era tremendamente estático, pero años después el contenido fue evolucionado hacia algo más dinámico e interactivo, conocido como la Web 2.0, en la que el usuario es el centro de la información, creándose contenido por y para él.

  • Linux y el auge del Open Source: El concepto del código abierto se creó en los 80, con la finalidad de tener acceso al código fuente y tener el derecho de modificarlo y distribuirlo libremente, el movimiento tuvo un auge real (y comercial) por la creación del Linux (que es un kernel y no un sistema operativo como tal), por Linus Torval en el 91. A finales de los 90 y a principio de los 2000, la combinación de Linux y GNU se hizo extremadamente popular para los servidores y para una nueva visión de la informática basada en la nube. En la década pasada (los 2010), empresas que clásicamente se habían opuesto al software libre, como Microsoft entraron de lleno en este modelo y visión de desarrollo.

  • Patrones de software: Los patrones de software son “formulas” conocidas, prácticas y probadas en los que un programa (un código fuente) funciona de forma exitosa. Son “recetas” que si las seguimos tendremos éxito en la solución de un problema especifico. En el 90 se publica el libro Gang of Four (GoF), y a partir de los mediados de los 2000 se populariza el uso de patrones (quizás de una forma exagerada en algunos casos).

Creación del manifiesto ágil


Los preámbulos anteriores nos dan a entender que en un futuro próximo la informática y los sistemas, se iban a convertir en una de las partes centrales de nuestra vida (personal y laboral), prácticamente la totalidad de los negocios y empresas a lo largo del mundo esta gestionados por un sistemas software, y ¡qué decir de la cantidad de dispositivos móviles que existen por persona!

La situación era que a finales de los 90, y con pensamientos y técnicas obsoletas de desarrollo de software era imposible llegar cumplir las necesidades presentes y futuras del mercado. Es más, la falta de compresión de la labor exacta del programador y la importancia e impacto de su trabajo (además de un exceso de profesionales técnicos que se dio debido al efecto de la burbuja .com y su futura explosión) hizo que se crearan sentimiento de desasociacion, falta de pertenencia (a la empresa y sus objetivos) por parte del informático, y un sentimiento de frustración por parte del empresario y gestor del negocio que no obtenía lo que quería.

El 12 de febrero de 2001, diecisiete programadores (algunos muy importantes a futuro), se reunieron con la intención de mejorar la visión del desarrollo de software. En cierto sentido están hartos de las metodologías pesadas, llenas de documentación, burocracia y protocolos que limitaban el tiempo y el impacto de lo que mejor sabían hacer, crear software.

Lo que crearon es conocido como el manifiesto ágil, que tiene las siguientes premisas básicas.

  • Individuos e interacciones sobre procesos y herramientas

  • Software funcionando sobre documentación extensiva

  • Colaboración con el cliente sobre negociación contractual

  • Respuesta ante el cambio sobre seguir un plan


A lo que se refiere el manifiesto es que si bien los elementos de la derecha son importantes, los elementos de la izquierda deben estar por encima.

Individuos e interacciones sobre procesos y herramientas


Si hay algo que odie mas en el desarrollo de software es la burocracia, a veces olvidamos que los proceso fueren creados para facilitar el trabajo, para ser un reflejo del las tareas y sus pasos para resolver problemas, y sin embargo parece que el trabajo fue creado para “cumplir” el proceso.

Decía Sun Tzu, en el arte de la guerra, que nadie espera una orden para apagar un fuego. Las necesidad se imponen sobre los procesos y los individuos resuelven necesidades.

A veces hasta el más mínimo cambio o mejora se ve “ahogada” entre una montaña inmensa de procesos burocráticos, correos, documentos, validaciones y “visto Buenos”, que hace que francamente sea más costosos resolverla, que dejarlo pasar.

La iniciativa individual y colectiva se ve detenida por procesos que se interponen por ser “procesos”, más que por ser necesarios.

Muchas veces el proceso crea un cerco de “responsabilidad” que nos hace indiferentes a las “responsabilidad” y necesidades de nuestros compañeros, creemos que nuestro trabajo es seguir unos procesos específicos y asignados a nosotros, y no comprendemos que nuestro trabajo solo tiene sentido al integrarse con el trabajo de nuestros compañeros.

Recuerdo un proyecto cuando ejercería de programador en que el líder de proyecto, proporcionaba los requisitos del sistema, el sistema en si debía conectarse con otro sistema que esta construyendo otro equipo (con su propio líder de proyecto) , la comunicación entre equipos era prácticamente inexistente, todo se tenía que hacer a trajes del líder del proyecto y mediante documentos formales, después de muchas horas extra, trabajar sin tener claro el objetivo y muchos cambios de definición, el resultado al momento de las pruebas, fue que nada encajaba con nada y había que rehacer mucha partes tanto desde el lado del código fuente, como desde el lado del diseño. Todo esto se podría haber evitado dan prioridad (y reconociendo) a los integrantes de cada equipo y fomentando la comunicación entre ellos en lugar de seguir a raja tabla los procesos.

Software funcionando sobre documentación extensiva


Uno de los motivos que ms me ha tocado vivir y por los que un software no sale de la forma deseada o en el tiempo requerido, es querer definirlo y documentarlo completamente antes de construirlo.

En las metodólogas pesadas el orden donde ocurren las cosas es muy claro, primero el análisis, después el diseño y posteriormente la construcción y la pruebas.

También una de las frases que más se repiten en el desarrollo de software es “No hagas nada, sin tener claro todo lo que vas a hacer”. La verdad es que casi nunca podemos tener claro al 100% lo que vamos a hacer.

Posiblemente lo anterior funcione en otro tipo de proyectos de ingeniera, pero no en desarrollo de software.

Lo cierto que es que un problema no se entiende nunca completamente hasta que está resuelto.

Por norma general un cliente siente que tiene una necesidad (una carencia que necesita ser resulta), pero es muy raro que sepa cómo resolverla, e incluso que sepa de forma precisa que necesita. El desarrollador por otro lado desconoce la naturaleza del negocio del problema que necesita resolver.

La programación ágil, apuesta por comenzar a programar cuando antes, buscando hacer entregas que puedan estar productivas cada pocas semanas, cada entrega se acerca más a la solución final, y no permitirte no tener que avanzar mucho antes de darnos cuenta que vamos en mal camino, porque créenme no hay nada peor que estar meses en un proyecto y al momento de entregarlo ver que no le sirve al cliente, y que el trabajo de un equipo fue en vano, no generando satisfacción en ninguno de los implicados.

Colaboración con el cliente sobre negociación contractual


Una vez tuve que trabajar con una empresa que se contrato para desarrollar un producto web (es decir en este caso nosotros éramos el cliente). La relación con la empresa fue complicada, porque ellos a la vez contrataron a unos programadores externos (de otra empresa) para resolver el problema, con lo que había una seria de escalones burocráticos y contractuales entre nosotros y los que realmente hacían la pagina web.

Una de las discusiones que mas me saco de quicio, fue cuando les pedí que limitara la entrada de un cuadro de texto, para que fuera acorde con el tamaño del campo relacionado en la base de la base de datos, la empresa quería cobrarnos un precio adicional por que eso no está especificado en la definición, yo alegaba que no era necesario que se lo especificamos por que era un requisito no funcional que debería haberse detectado por ellos y no por nosotros. Total al final fue más fácil pagarles, y nunca volver a trabajar con ellos.

El caso es que el trato no fue beneficios para ninguna de las partes, ni para nosotros que no obtuvimos el producto que necesitamos, ni para la empresa desarrolladora ya que no volvimos a colaborar con ellos.

La programación ágil propone un acercamiento constante con el cliente, se asume que no se comprende al cliente a través de definiciones, sino de prototipos funcionales, se colabora con el cliente para poder crear un software que sea satisfactorio.

Evidentemente en este punto surgen dudas sobre cuál es el límite de aceptación de lo que si hay que programar, y lo que no, sobre todo por motivos de recursos.

Y aquí hay tener claro que estamos resolviendo una necesidad en concreto, todo lo que nos acerque a esa resolución es positivo, lo que nos aleje es negativo. Por ejemplo se deben evitar y postergar en la medida de los posible, soluciones que parecen mágicas, para casos extraordinarios y inverosímiles que rara vez pasan, y centrarnos en los que pasa la mayoría de las veces. Esto se relación con el principio de paleto, que resumiendo es que el 80% de la funcionalidad de un sistema, es suplicada por el 20% por cierto del código de dicho sistema.

Cuando un cliente ve su software funcionando se olvida rápidamente de idea, casos de uso y caminos extraños para su sistema que no llevan a ninguna parte. Cuando está definiendo todo completamente al principio del proyecto, se pierde en callejones que no llevan a nada, y que en la práctica requieren un enorme esfuerzo de desarrollo y recursos, para el beneficio real que producen.

Respuesta ante el cambio sobre seguir un plan


El cambio esta inherentemente ligado al desarrollo del software, sobre todo al desarrollo de software empresarial. La velocidad con la cambian los mercados y los consumidores hacen que el software deba adaptarse rápidamente para por tener valor.

Pero en el desarrollo de un sistema especifico, hay que entender que cuando más se avanza en la construcción de un sistemas, mas se comprende las necesidades y eso lleva a cambios, y adecuaciones, cuando mejor sea la arquitectura de un sistemas, mas fácil es esto. Esto es siempre así, se realicen se realice en un escenario ágil o no.

Como vemos todos los puntos están relacionados entre sí, el disminuir el análisis inicial y generar entregas continuas que generen valor, no solo nos ayuda a resolver más rápido el problema y a comprenderlo menor, sino además a descartar las ideas iniciales que pudiera tener el cliente, y que realmente no solucionarían su problema. Aunque parezca una contracción las entregas incrementales y un acercamiento al problema por partes minimiza los cambios que hay que realizar en el proyecto. En una metodología pesada los cambios serian solicitados al final, cuando la fecha de entrega esta sobre nosotros, y las modificaciones a realizar pueden tener mayor impacto.

Perspectiva a 20 años del manifiesto



Es estas dos décadas, la tecnología no ha dejado de evolucionar y de ser adoptada masivamente, tenemos la implementación casi total de internet, la web 2.0, las redes sociales, la conexión las 24 horas y la demanda en línea de servicios, entre otras cosas.

Las metodólogas agiles han sido ideales para conseguir esta unión entre tecnología y sociedad.

Han surgido nuevos enfoques de desarrollo de software, y herramientas maravillosas, que nos permiten comunicarnos más fácilmente, y de diversas formas.

Pero también existieron puntos negativos, si bien el manifiesto apareció como una reivindicación de la figura del programador y su importancia dentro del desarrollo de software, poco a poco se uso la palabra ágil para definir tareas de gestión y administración de diversa índole (y en muchos conceptos), quedando la palabra “hueca” en sus significado, casi convirtiéndose en una idea genérica, abstracta y vende humos, más que en una cosa real y practica.

Hay considerar siempre al programador, su experiencia, y su potencial, como le elemento central y principal del desarrollo de software ágil, y la clave del éxito para crear software de calidad.




Si te ha gustado la entrada, ¡Compártela! ;-)

sábado, 13 de marzo de 2021

Regla Nº20 No depender del llamador, ni de la implementación (evitar acoplamientos)

Frecuéntenme, en nuestra vida personal y laboral, cambiamos nuestro comportamiento y actitud según con quien estemos hablando con la finalidad de poder conseguir y resolver las necesidades o circunstancias que se nos plantean. No es lo mismo (o no diera) que un doctor este dando una clase sobre alguna enfermedad que le este comunicando dicha enfermedad a un paciente, ni tampoco es igual como hablamos con nuestros padres o hijos a como hablamos con nuestros compañeros de trabajo. Por otro lado tampoco recibimos la información de la misma forma de personas que apreciamos y conocemos que de desconocidos, “modulamos” nuestro comportamiento según con quien estemos hablamos.

Ese punto de vista, tan normal en interacciones humanas, supone un problema a la hora de implementar software.

Una clase no debe cambiar su comportamiento según quien la consume, igualmente el consumidor de una clase no debiera saber cómo esta implementada internamente dicha clase, para poder consumirla de forma adecuada.

Estos días he tenido que dar mantenimiento a un sistema, un sistema que es consumido por otros, bastante viejo, ¡pero no tanto como para los problemas que me he encontrado!


Había que agregar un nuevo comportamiento, hasta ahí todo normal, como ya hemos hablado en varias circunstancias (Regla N°1: Va a cambiar), el software se modifica contantemente para adaptarse a negocio cambiante. ¡El problema es que básicamente toda la lógica de negocio estaba en una misma función, con multitud de if anidados  y ramificaciones! (Regla N°18: evita el código espagueti). No solo era difícil de entender, si no extremadamente delicado de modificar, cada vez que se moviera algo, podría afectar de cualquier forma a los consumidores, para colmo el sistema reacciona de forma diferente si lo llama un sistema o si lo llama otro, es decir la clases tiene que reconocer que quien le está llamando, para saber cómo debe comportarse.

 Lo anterior resume un gran problema de acoplamiento y falta de cohesión, lo que está ligado directamente a la dificulta de mantenimiento del software (lo que a su vez es ligado a costos económicos, tiempo, y muy posibles desastres productivos)

Acoplamiento


El acoplamiento entre dos clases es una medida que indica cuanto depende una clase de otra, específicamente cuando depende de su implementación interna. Cuando mas acoplamiento, peor es nuestro código, cuando mas desacoplado este, mas fácil de mantener.

Idealmente una clase solo se debiera relacionar con otras a través de la definición de los métodos, el cómo hagan esos métodos sus funciones con cosas que nos deben preocupar. Lo anterior se ve claramente cuando podemos sustituir la referencia de una clase, por la referencia a una interface, y cambiar la clase que lo implementan sin mucho (o ningún) impacto.

Si podemos cambiar una clase consumida por otra, sin realizar cambios en el consumidor, hemos conseguido un nivel aceptable de desacoplamiento.

Con respecto a no depender de la “implementación interna de una clase”, se dan varios escenarios que demuestran un alto acoplamiento:

  • Cuando la clase consumidora debe almacenar información que no le sirve de nada, salvo para consumir otra clase. Aquí es donde se ve un defecto de diseño, puesto que debiera ser la clase consumida la que debe contener sus propios datos, sin forzar a los consumidores a hacerlo.

  • Las clases se comunican de forma estrafalaria y poco comprensible, por ejemplo se usan cadenas de texto, para comunicar cosas que claramente no lo son, como números, fechas u objetos. El ejemplo de la fecha es muy común, se pasa una fecha en formato texto, pero hay muchas formas de expresar una fecha por texto, no es lo mismo el 1 de Febrero (01/02/2021), que el 2 de Enero  (02/01/2021), pero según el formato de la fecha podría ser una u otra. La única forma correcta de pasar una fecha es mediante un objeto de tipo fecha.

  • Los métodos de una clase deben llamarse en un orden determinado para que funcionen, si no dan resultados inesperados, cada métodos debe hacer algo en concreto, y debe hacerlo independiente en el orden en lo que se les llama, si no puede hacerlo por algún motivo, debe lanzar una excepción (es mejor no hacer algo que hacerlo mal).

    Una situación reciente que me acaba de pasar, tenía que usar un control grafico de terceros, un datagrid para mostrar tabla en pantalla (en una aplicación de escritorio). Una vez mostrada la información en pantalla había que cambiar el valor de una celda en particular, pero por algún motivo extraño, la celda tenía que estar visible, si no ignoraba la instrucción para cambiar el valor (sin producir ningún fallo), así que la solución fue posicional visualmente el componente en la fila requerida y cambiar el valor, y después volver a la fila que estaba el usuario actualmente (que pudiera ser otra), pero esta daba otro problema como un parpadeo innecesario en el programa, eso se solucionaba desactivando el control antes de realizar la operación. Al final el programa consumidor, se lleno de instrucciones que hay que ejecutar antes (y después) de cambiar el valor de una celda, y no se comprende muy bien porque es así, y desde luego si se cambia el componente todo ese código esta de mas.

  • La clase consumida cambia su comportamiento según quien lo está consumiendo, ese es el acoplamiento más rocambolesco de todos. Es decir si la clase A, y B consumen la clase C,  la C cambia su funcionalidad según quien la este llamando.

    Para comenzar, de por si suena muy extraño. Una clase debe tener una misión sea cual sea, debe ser clara y concisa y realizarla de la misma forma independientemente de quien le este llamando.

    Que modifique su comportamiento según el llamador, suena a que la clase no tiene un diseño bueno orientado a objetos, donde se usa una serie de estructuras condicionales gigantescas, en lugar de usar herencia y polimorfismo.

    Cuando se modifica la clase consumida, se puede afectar a la clase consumidora obligándola también a  ser modificada, si hay más de un sistema que consuma dicha clase, habrá que cambiar todos y cada uno de ellos con un consumo en tiempo y recursos. Si además los sistema a modificar son consumidos por otros sistemas, pueden desencadenas una cadenas de modificaciones enorme y costosa.

    Es posible, no obstante, que debamos modificar el acceso a la funcionalidad en cuestión de permisos, es decir dichas componente tendrá acceso a alguna funcionalidad y otra no. Un ejemplo muy típico de esto es cuando las aplicaciones se logean con facebook y nos muestra un mensaje que nos dice a que tendrá acceso la pagina web donde nos logeamos, puede ser al perfil público y a nuestro correo, otra quieren acceder a nuestra lista de contactos y otra incluso a publicar en nuestro nombre. Pudiera parecer que se está creando un acoplamiento en el que facebook devuelve información según la aplicación que se lo pida pero no cierto. Hay una capa de seguridad adicional que se encarga de generar un “token” con ciertos permisos hacia facebook y la aplicación web consumidora usara este token, pero en ningún caso facebook lo hará por que la pagina web que lo consume sea una o la otra, sino porque se solicito unos permisos y se trabaja con la autorización previa de con dichos permisos.

  • Una medida del acoplamiento de una clase es la cantidad de clases adicionales que consume. Puede ser que parezca que no dependa de la implementación interna de cada uno de los componentes que consume pero cuando una clase consume muchas clases, comienza a perder su identidad y a depender de elementos externos para realizar su tarea,  lo que al final repercute en un alto acoplamiento. En una aplicación empresarial se supone que una clase solo debe consumir las clases que estén en un nivel más por debajo que el suyo con lo que sería bastante raro que consumiera muchas clases.


Cohesión


La cohesión posiblemente sea unos de los conceptos que son más difíciles de explicar y comprender acertadamente de la ingeniera de software.

A veces se explica simplemente como que todo lo que pertenezca a mismo ámbito o tenga que ver entre sí debe estar junto. Así agrupamos los métodos en clases, las clases en namespace (o paquetes), los namespace en componentes y los componentes en sistemas.

Pero lo anterior es solo organización, agrupar las cosas según su semejanza y naturaleza, para que sea más sencillo encontrarlas y usarlas pero no define el nivel de cohesión como tal.

  • Una clase se debe componer de datos, representados por atributos (o propiedades) y por funcionalidad que usa esos datos. ¿Qué tantos atributos debe usar cada función o métodos?, en principio debiera usar todos, ya que los atributos es lo que representa el estado del objeto y cada función debiera cambiarlo (por que debiera hacer algo con el objeto), en la medida que use mas métodos y mas atributos de la clase, la misma clase esta mas cohesionada.

  • Si en una clase, una  colección de métodos usa unos atributos y otra colección de métodos usan otros atributos diferentes entonces la clase no tiene cohesión y realmente son dos clases que se han convertido en una sola, debiéndose separar. Si esto lo tenemos varias veces, lo que tenemos es lo que se llama una “clase gorda”, una clase con muchas cosas dentro sin nada que ver entre sí y que posiblemente solo sea una colección de métodos, que no son parte de una objeto con identidad. Posiblemente las  clase tenga más de un motivo para cambiar y dichos motivos no tengan nada que ver entre sí (lo que hace que no se cumpla el principio de “responsabilidad única”).

  • De igual manera si una clase consume en exceso a otra clase, y sobretodo usa sus atributos (a atreves de sus propiedades o métodos) de forma constante pareciendo que no tiene ningún sentido una clase sin la otra, estaríamos en un caso de “clase famélica”, y posiblemente debiera ser una sola.

  • Lo anterior vuelve a pasar con los namespaces (o paquetes). Estos deben componerse de clases que se consumen o se relacionan entre sí (por medio de mecanismos de (herencia, agregación, composición, colección u otros). También debe evitar incluir clases que no se usan de ningún modo. Esto hacen que las clases sea cohesionadas y tengan un objetivo, fácilmente identificable.

  • Los namespaces se agrupan en componentes. Los componentes igualmente tiene un objetivo común y identificable, pero es una agrupación “física”, en forma de elemento reusable como una librería, un jar de java o un servicio.

  • Los sistemas son agrupaciones de uno o más componentes que interactúan entre sí para resolver una serie de problemas de negocio a través de flujos e interacciones con el usuario.


La cohesión nos ayuda a que los problemas que tenemos que resolver sean pequeños, conexos y fácilmente escalables.

Relación entre cohesión y acoplamiento


Cohesión y acoplamiento son dos valores tan relacionados que siempre se van a encontrar juntos.
  • Si aumenta la cohesión disminuye el acoplamiento.

    Si tenemos juntos los elementos que si deben estar juntos, el acoplamiento debiera disminuir porque la organización de los mimos elementos nos lleva a consumir solo los que necesitamos, con cierto control y estructura.

  • Si disminuye la cohesión aumente el acoplamiento.

    Lo contrario de “tener todo en un lugar”, es “tenerlo todo junto”. Si tenemos todas las clases a la mano, es normal que comencemos a usar clases simplemente porque están accesibles, mezclando cosas que poco o nada tiene que ver, y eso aumentaría el acoplamiento

  • Si disminuye el acoplamiento aumenta la cohesión.

    Si diseñamos nuestro código disminuyendo la cantidad de clases que consumimos, no dependemos de su implementación interna y nos comunicamos a través de interfaces, quiere decir que tenemos un nivel de organización y agrupación lo suficientemente algo.

  • Si aumenta el acoplamiento disminuye la cohesión.

    Si nuestra clase comienza a consumir clases de diversa índole y sin ningún control ni estructura, es forzosamente necesaria tenerlas accesibles y tenerlas accesibles le fuerza a que tenerlas lo mas “cerca” posible, disminuyendo considerablemente la cohesión.




Si te ha gustado la entrada, ¡Compártela! ;-)

Reglas de la Ingeniería de software (índice): https://desdelashorasextras.blogspot.com/2019/12/reglas-de-la-ingenieria-de-software_15.html