User Tools

Site Tools


wiki:psp_1

This is an old revision of the document!


Propiedades de Diseño

Es cierto que el diseño de sistemas de software depende de la experiencia y, en alguna medida, también del talento y la creatividad. Sin embargo, existen algunas propiedades importantes en el diseño de sistemas. Por eso, estudiar y conocer estas propiedades de diseño puede ayudar en la concepción de sistemas con mayor calidad. En esta sección se estudian las siguientes propiedades de los diseños de software: integridad conceptual, ocultación de información, cohesión y acoplamiento. Además, se enunciarán a continuación algunos principios de diseño, los cuales representan directrices para garantizar que un diseño cumple con determinadas propiedades.

Integridad Conceptual

Integridad conceptual es una propiedad de diseño propuesta por Frederick Brooks, el mismo autor de la Ley de Brooks. El principio fue enunciado en 1975, en la primera edición del libro The Mythical Man-Month. Brooks sostiene que un sistema no puede ser una acumulación de funcionalidades sin coherencia ni cohesión entre ellas. La integridad conceptual es importante porque facilita el uso y la comprensión de un sistema por parte de sus usuarios. Por ejemplo, con integridad conceptual, el usuario acostumbrado a utilizar una parte de un sistema se siente cómodo al usar otra parte, ya que las funcionalidades y la interfaz implementadas a lo largo del producto son siempre consistentes.

Para citar un contraejemplo, es decir, un caso de ausencia de integridad conceptual, asumamos un sistema que utiliza tablas para presentar sus resultados. Dependiendo de la pantalla del sistema en la que se usen, estas tablas tienen diferentes diseños, en términos de tamaño de fuente, uso de negrita, espaciado entre líneas, etc. Además, en algunas tablas es posible ordenar los datos haciendo clic en el título de las columnas, pero en otras tablas esa funcionalidad no está disponible. Por último, los valores se muestran en diferentes monedas. En algunas tablas, los valores se refieren a reales; en otras tablas, se refieren a dólares. Esta falta de estandarización es una señal de falta de integridad conceptual y, como mencionamos, añade complejidad accidental en el uso y la comprensión del sistema


Enfatizamos el impacto de la falta de integridad conceptual en los usuarios finales de un sistema. Sin embargo, el principio también se aplica al diseño y al código de un sistema. En este caso, los afectados son los desarrolladores, quienes tendrán más dificultad para entender, mantener y evolucionar el sistema. A continuación, mencionamos ejemplos de falta de integridad conceptual a nivel de código:

  • Cuando una parte del sistema usa un patrón de nombres para variables (por ejemplo, camel case, como en notaTotal), mientras que en otra parte se usa un patrón diferente (por ejemplo, snake case, como en nota_total).
  • Cuando una parte del sistema utiliza un framework determinado para la manipulación de páginas web, mientras que en otra parte se usa un segundo framework o una versión diferente del primer framework.
  • Cuando en una parte del sistema se resuelve un problema utilizando una estructura de datos X, mientras que, en otra parte, un problema similar se resuelve mediante una estructura Y.
  • Cuando funciones de una parte del sistema que necesitan cierta información — por ejemplo, la dirección de un servidor — la obtienen directamente de un archivo de configuración. Sin embargo, en otras funciones, de otras partes del sistema, esa misma información debe pasarse como parámetro.

Estos ejemplos revelan una falta de estandarización y, por lo tanto, de integridad conceptual. Son un problema porque dificultan que un desarrollador acostumbrado a mantener una parte del sistema pueda ser asignado para mantener otra parte.

Ocultamiento de la Información

Esta propiedad, una traducción de la expresión information hiding (ocultación de información), fue discutida por primera vez en 1972 por David Parnas, en uno de los artículos más importantes e influyentes en el área de Ingeniería de Software de todos los tiempos, cuyo título es “On the criteria to be used in decomposing systems into modules”.

Este artículo discute la modularización como un mecanismo capaz de hacer que los sistemas de software sean más flexibles y fáciles de entender y, al mismo tiempo, reducir su tiempo de desarrollo. La efectividad de una determinada modularización depende del criterio utilizado para dividir un sistema en módulos David Parnas, “On the criteria to be used in decomposing systems into modules”

Aviso: Parnas usa el término módulo en su artículo, pero esto fue en una época en que la orientación a objetos aún no había surgido, al menos como la conocemos hoy. En este capítulo, escrito casi 50 años después del trabajo de Parnas, optamos por el término clase, en lugar de módulo. El motivo es que las clases son la principal unidad de modularización en lenguajes de programación modernos como Java, C++ y Ruby. Sin embargo, el contenido del capítulo se aplica a otras unidades de modularización, incluidas aquellas más pequeñas que las clases, como métodos y funciones, y también a unidades más grandes, como paquetes y componentes.

El ocultamiento de información aporta las siguientes ventajas a un sistema:

  • Desarrollo en paralelo: Supongamos que un sistema X fue implementado mediante las clases C1, C2, …, Cn. Cuando estas clases ocultan su información principal, es más fácil implementarlas en paralelo por diferentes desarrolladores. Como resultado, se reduce el tiempo total de implementación del sistema.
  • Flexibilidad ante cambios: Por ejemplo, supongamos que descubrimos que la clase Ci es responsable de los problemas de rendimiento del sistema. Cuando los detalles de implementación de Ci están ocultos del resto del sistema, es más fácil reemplazar su implementación por una clase Ci', que use estructuras de datos y algoritmos más eficientes. Este cambio también es más seguro, ya que como las clases son independientes, se reduce el riesgo de que el cambio introduzca errores en otras clases.
  • Facilidad de comprensión: Por ejemplo, un nuevo desarrollador contratado por la empresa puede ser asignado a trabajar en algunas clases únicamente. Por lo tanto, no necesitará comprender toda la complejidad del sistema, sino solo la implementación de las clases que le fueron asignadas.

No obstante, para alcanzar los beneficios mencionados, las clases deben cumplir con la siguiente condición (o criterio): deben ocultar decisiones de diseño que están sujetas a cambios. Debemos entender una decisión de diseño como cualquier aspecto del diseño de la clase, como los requisitos que implementa o los algoritmos y estructuras de datos que se usarán en su código. Por lo tanto, el ocultamiento de información recomienda que las clases deben ocultar detalles de implementación que estén sujetos a cambios. Modernamente, los atributos y métodos que una clase pretende encapsular se declaran con el modificador de visibilidad privado, disponible en lenguajes como Java, C++, C# y Ruby.

Sin embargo, si una clase encapsula toda su implementación, no será útil. Dicho de otra manera, una clase, para ser útil, debe hacer públicos algunos de sus métodos, es decir, permitir que puedan ser llamados por código externo. El código externo que llama a los métodos de una clase se denomina cliente de la clase. También decimos que el conjunto de métodos públicos de una clase define su interfaz. La definición de la interfaz de una clase es muy importante, ya que constituye su parte visible.

Las interfaces deben ser estables, porque los cambios en la interfaz de una clase pueden requerir actualizaciones en sus clientes. Para ser más claro, supongamos una clase Math, con métodos que realizan operaciones matemáticas. Supongamos un método sqrt que calcula la raíz cuadrada de su parámetro. Supongamos además que la firma de este método se modifica, por ejemplo, para devolver una excepción si el valor del parámetro es negativo. Esta modificación tendrá un impacto en todo el código cliente del método sqrt, que deberá ser modificado para manejar la nueva excepción.

Ejemplo:

A continuación un trecho de código para un sistema de estacionamiento en su primera versión. Identifique el problema en relación a la propiedad de diseño de ocultamiento de la información.

import java.util.Hashtable;
 
public class Estacionamiento {
 
  public Hashtable<String, String> vehiculos;
 
  public Estacionamiento() {
    vehiculos = new Hashtable<String, String>();
  }
 
  public static void main(String[] args) {
    Estacionamento e = new Estacionamiento();
    e.vehiculos.put("TCP-7030", "Uno");
    e.vehiculos.put("BNF-4501", "Gol");
    e.vehiculos.put("JKL-3481", "Corsa");
  }
}
wiki/psp_1.1724357715.txt.gz · Last modified: 2024/08/22 16:15 by admin