Enfoques para el desarrollo de software

Como muestra el ejemplo 8, los desarrolladores necesitan tratar con las dependencias que surgen como resultado de su descomposición de un problema y su solución en un número de módulos. Decimos que un módulo de un sistema depende de otro si es posible que un cambio en un módulo requiera un cambio en otro. Por ejemplo, si una empresa cambia sus métodos de producción, esto puede provocar un cambio consecuente en la forma de calcular los pagos necesarios para los bienes que produce.

Un desarrollador no sólo debe ocuparse de la naturaleza de cada dependencia, sino también del número de dependencias. En ingeniería de software, el término «acoplamiento» se utiliza para referirse al grado de interdependencia entre las diferentes partes de un sistema. Es fácil ver que ciertos sistemas pueden tener cadenas de módulos interdependientes en las que, por ejemplo, el módulo A depende del módulo B, que depende del módulo C, y así sucesivamente. En algunos casos, estas cadenas pueden unirse y crear una dependencia circular, que es una forma particular de acoplamiento fuerte (o alto).

Los desarrolladores tratan de construir sistemas poco acoplados porque son más fáciles de entender y mantener. Así, un buen sistema de software tiene un bajo acoplamiento, lo que significa que es menos probable que los cambios en una parte se propaguen por el resto del sistema. Otra ventaja del bajo acoplamiento es que los componentes son fáciles de sustituir y, potencialmente, de reutilizar.

Cualquiera que sea el nivel de acoplamiento en un sistema de software, es importante saber qué módulos están acoplados. Si no hubiera registros del acoplamiento entre los módulos, un desarrollador tendría que dedicar tiempo a trabajar con los módulos para determinar si cada uno se ve afectado por un cambio. El resultado sería un gran esfuerzo de comprobación, aunque no fuera necesario realizar ningún cambio. El ejemplo 9 ilustra el peligro de tener más de un módulo haciendo uso de datos comunes o compartidos.

Ejemplo 9

El manejo de la fecha siempre ha sido un problema para los desarrolladores de software. Para las aplicaciones de cierta antigüedad, el formato de almacenamiento más aplicable para representar un año era un número entre 0 y 99. Tenía sentido porque 1966 se almacenaba como 66, 1989 como 89, y así sucesivamente, por lo que se necesitaba menos espacio para almacenar sólo dos dígitos. Además, si las fechas se almacenaban como números, las tareas que implicaban ordenar por orden de fecha eran sencillas: el 22 de enero de 1989 se almacena como 890122, es posterior al 22 de diciembre de 1966 y se almacena como 661222.

Desgraciadamente, varias de estas aplicaciones seguían en uso cuando se acercaba el año 2000, por lo que había que investigar cada módulo de cada aplicación que utilizaba la forma corta del año.

Un aspecto importante del problema del ejemplo 9 era que los diferentes desarrolladores tenían diferentes formas de leer y manipular los valores almacenados en las variables que utilizaban el formato de fecha de seis cifras. Esto aumentó el esfuerzo requerido para resolver el llamado error del milenio. Si los desarrolladores hubieran tenido una forma consistente de manipular las fechas que no dependiera del formato de almacenamiento, el error del milenio no habría sido un problema de preocupación.

La cohesión es una forma de describir lo estrechamente relacionadas que están las actividades dentro de un mismo módulo. La cohesión es un concepto general: por ejemplo, un departamento de una organización puede tener un conjunto cohesionado de responsabilidades (cuentas, por ejemplo), o no (servicios varios). En los sistemas de software, un módulo muy cohesionado realiza una tarea o consigue un único objetivo: «haz una cosa y hazla bien» es un lema útil. Un módulo debe implementar una única tarea lógica o una única entidad lógica.

El bajo acoplamiento y la alta cohesión son objetivos que compiten entre sí. Si cada módulo hace una sola cosa a un nivel bajo de abstracción, podríamos necesitar un complejo edificio de módulos altamente acoplados para realizar una actividad a niveles más altos de abstracción. Un desarrollador debe intentar conseguir el mejor equilibrio entre los niveles de acoplamiento y cohesión para un sistema de software. Por ejemplo, los hoteles generan ingresos alquilando sus habitaciones a los clientes. Es probable que el concepto de habitación esté representado en alguna parte del sistema de software para reservas de un hotel. Puede ser conveniente utilizar un módulo o clase que represente el concepto de habitación para recoger y almacenar datos sobre los ingresos generados por el alquiler de habitaciones. Sin embargo, una mejor solución es tener un módulo de factura o pago separado, porque es más cohesionado, especialmente cuando un hotel genera ingresos de otras formas, por ejemplo, por servir comidas a personas que no son huéspedes residentes.

Actividad 5 Divide y vencerás

Tiempo: Deje aproximadamente 20 minutos.
  • a.¿Por qué podría considerar la posibilidad de dividir un proyecto grande en trozos más pequeños?
  • b.¿Cómo afecta la complejidad de un sistema de software a la tarea de mantenimiento?
  • c.¿Qué es un módulo?
  • d.¿Por qué ayuda tener un bajo acoplamiento en un sistema de software?
  • e.Dé ejemplos de los tipos de información que serían valiosos al considerar un cambio en un módulo determinado.
  • f.¿Qué son las dependencias de contexto de un módulo? ¿Cómo se relacionan con la interfaz de un módulo?
  • g.¿Cuáles son las ventajas de utilizar módulos con interfaces definidas?
  • h.¿Por qué ayuda tener una alta cohesión en los módulos de un sistema de software?
  • i.¿Qué características debe presentar un módulo para que sea fácil y barato de desarrollar y mantener, y para que los errores sean mínimos?
  • j.¿Por qué es importante lograr un equilibrio entre el acoplamiento y la cohesión?

Respuesta

  • a.Hay un límite a lo que una persona puede entender en un momento dado. Por lo tanto, hay un límite en el tamaño de un sistema de software que una sola persona puede manejar. Al dividir un proyecto grande en trozos más pequeños, es posible identificar una serie de tareas más manejables para los involucrados.
  • b.Es esencial poder hacer un cambio en un sistema de software sin tener que saber todo sobre ese sistema. Cada cambio se vuelve difícil cuando el flujo de control y las dependencias dentro de los programas son complejos. Cuanto mayor es el número y la naturaleza de las dependencias, más difícil es mantener un sistema de software.
  • c.Un módulo es cualquier parte identificable de un sistema de software que se considera por separado. Por ejemplo, los módulos pueden ser subrutinas (en un lenguaje procedimental equivalente a los métodos), clases (en un lenguaje orientado a objetos), funciones de biblioteca u otras construcciones que pueden ser tratadas de forma independiente.
  • d.Con bajo acoplamiento, hay pocas dependencias entre los módulos. Por lo tanto, es menos probable que los cambios realizados en una parte (uno o más módulos) de un sistema de software se propaguen por todo el sistema. (Un registro claro de las dependencias entre módulos ayuda a predecir el impacto de un cambio propuesto en un sistema de software.)
  • e.Hay dos tipos de información que contribuyen al análisis de un cambio propuesto:
    • ¿Qué módulos son clientes del módulo en cuestión? Esta información indica hasta dónde puede propagarse un cambio a través del sistema de software.
    • ¿Qué suposiciones se han hecho en los módulos clientes del módulo en cuestión? Una comprensión de los servicios esperados de un módulo ayudará a evaluar los riesgos asociados con un cambio en particular.
  • f.Las dependencias de contexto para un módulo son los servicios de otros módulos que el módulo necesita para funcionar correctamente. Puedes expresar las dependencias de contexto de un módulo en términos de otras interfaces. En efecto, puedes expresar las responsabilidades de un módulo en términos de su interfaz y sus dependencias de contexto. Si el contexto proporciona los servicios que el módulo necesita y los clientes cumplen cualquier condición especificada en la interfaz, el módulo puede garantizar la prestación de los servicios descritos en su interfaz.
  • g.Las ventajas son las siguientes:
    • Los desarrolladores sólo tendrán que conocer la interfaz del módulo (su sintaxis y lo que requiere y consigue – su semántica), no cómo proporciona esos servicios. En consecuencia, los desarrolladores pueden ser más productivos.
    • Los desarrolladores pueden entender los aspectos del sistema de software más a fondo, por lo que se introducirán menos errores.
    • Debería ser más fácil encontrar errores, ya que se evitan los módulos irrelevantes.
    • La posibilidad de reutilización del módulo se incrementa una vez que se sabe lo que ese módulo proporciona y requiere.
  • h.Con una alta cohesión, un módulo lleva a cabo un conjunto razonable de operaciones o actividades. Idealmente, la alta cohesión implica sólo una abstracción principal por módulo. La interfaz se abstrae de lo que un desarrollador debe saber para utilizar un módulo. Esto facilita que los desarrolladores entiendan el propósito del módulo y cómo utilizarlo. Además, una alta cohesión tiende a hacer que un módulo sea más reutilizable en otras aplicaciones, ya que proporciona un conjunto de operaciones que se sientan naturalmente juntas.
  • i.Un módulo debe tener bajo acoplamiento y alta cohesión, representar una buena abstracción, y tener una interfaz bien definida que es una abstracción encapsulada de un concepto bien entendido.
  • j.Al construir un sistema, se puede elegir entre un conjunto más pequeño de módulos débilmente acoplados y menos cohesivos, o un conjunto más grande de módulos fuertemente acoplados y más cohesivos. En el primer caso, cada módulo puede ser difícil de entender, mientras que en el segundo las relaciones entre ellos pueden ser demasiado complejas. Hay que encontrar un equilibrio adecuado.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.