PDF de programación - Clase 2: Desacoplamiento I

Imágen de pdf Clase 2: Desacoplamiento I

Clase 2: Desacoplamiento Igráfica de visualizaciones

Publicado el 6 de Septiembre del 2017
1.189 visualizaciones desde el 6 de Septiembre del 2017
225,8 KB
22 paginas
Creado hace 20a (30/09/2003)
Clase 2: Desacoplamiento I



Uno de los aspectos básicos del diseño de software es cómo descomponer un programa en

partes. En esta clase introduciremos algunas nociones fundamentales que nos permitan hablar

sobre las partes y sobre el modo en que éstas se relacionan entre sí. Nos centraremos en el

análisis del problema del acoplamiento entre partes, y en mostrar métodos para simplificarlo.

En la próxima clase, veremos una serie de técnicas de Java pensadas específicamente para

soportar el desacoplamiento.



La idea clave que presentaremos hoy es la de especificación. Es erróneo pensar que las

especificaciones no son más que documentación tediosa. Por el contrario, resultan esenciales

para el desacoplamiento y, por lo tanto, para el diseño de alta calidad. Veremos que en

diseños más avanzados, las especificaciones se convierten por sí mismas en elementos de

diseño.



El libro de texto de la asignatura trata los términos usa y depende como sinónimos. En esta

clase, haremos una distinción entre los dos, y explicaremos cómo la noción depende resulta

más útil que la noción usa, que es un término más antiguo. El alumno aprenderá a construir y

analizar diagramas de dependencia; los diagramas de casos de uso se tratarán sólo de pasada.


2.1 Descomposición

Un programa se construye a partir de un conjunto de partes. El problema de la

descomposición consiste en descubrir qué partes integran ese conjunto y qué relación guardan

entre ellas.



2.11 ¿Por qué descomponer?

Dijkstra ha puesto de manifiesto que si un programa se compone de N partes, y cada una de

ellas tiene una probabilidad de exactitud de c –es decir, si existe una probabilidad de 1 – c de



1

que el programador cometa un error –entonces la probabilidad de que toda la estructura
funcione es de cN. Si N tiene un valor alto, entonces, a menos que el valor de c se halle muy
cerca de uno, cN será un valor próximo a cero. Con este argumento, Dijkstra pretende mostrar

lo importante que es crear un programa correctamente, y que el grado de importancia es

proporcional al tamaño del programa. Si no se logra que cada parte sea prácticamente

perfecta, no se podrá esperar que el programa llegue a funcionar.



(Este razonamiento se halla en un texto ya clásico: Structured Programming, de Dahl,

Dijkstra y Hoare, Academic Press, 1972. Se trata de una argumentación atractiva y sugerente,

aunque tal vez un tanto falaz; ya que, en la práctica, la probabilidad de conseguir que todo el

programa resulte totalmente correcto es cero. Lo verdaderamente importante es asegurar que

se mantengan ciertas propiedades, limitadas pero cruciales, y puede que éstas no se hallen en

cada una de las partes. Volveremos sobre esta cuestión más adelante).



Sin embargo, el argumento de Dijkstra parece insinuar que no se debería descomponer un

programa en partes. Cuanto más pequeña sea N, mayor será la probabilidad de que el

programa funcione. Por supuesto, no hablo en serio –resulta más fácil conseguir que una parte

pequeña, y no una grande, funcione correctamente (por lo que el parámetro c no es

independiente de N). No obstante, merece la pena preguntarse qué ventajas se derivan de la

división de un programa en partes pequeñas. He aquí algunas:

• División del trabajo. Un programa no surge de la nada: tiene que construirse

gradualmente. Si se divide en partes, el proceso de construcción se agiliza, ya que ello

permite que varias personas se dediquen a trabajar en las distintas partes.

• Reusabilidad. Algunas veces es posible aislar las partes que son comunes a diferentes

programas, de modo que se puedan crear una sola vez y utilizar muchas veces.

• Análisis modular. Incluso si un programa haya sido construido por una única persona,

resulta conveniente construirlo por partes pequeñas. De este modo, cada vez que se

completa una parte puede analizarse para comprobar su exactitud (leyendo el código,



2

testeándolo o mediante métodos más sofisticados de los cuales hablaremos más

adelante). Si funciona, otra parte podrá utilizarla sin necesidad de volver sobre ella.

Además de la satisfacción que supone poder progresar con rapidez, el análisis modular

proporciona una ventaja más sutil. Esto, aparte de dar una idea satisfactoria de

progreso, posee una ventaja más sutil. Analizar una parte que es doblemente extensa

supone el doble de esfuerzo, así que analizar un programa que está descompuesto en

partes pequeñas reduce drásticamente el coste global del análisis.

• Cambio localizado. Todo programa útil necesita de adaptaciones y ampliaciones a lo

largo de su existencia. La posibilidad de localizar un cambio en unas cuantas partes

permite que sólo haya que tener en cuenta una porción mucho más pequeña del total

del programa a la hora de llevar a cabo dicho cambio y validarlo.

En este sentido, resulta interesante el razonamiento propuesto por Herb Simon sobre por qué

las estructuras –ya sean de origen humano o naturales– tienden a construirse a partir de una

jerarquía formada por partes. Imaginemos dos relojeros; uno de los cuales fabrica relojes de

una sola vez, mediante ensamblajes únicos de grandes dimensiones, mientras que el otro

realiza combinaciones de pequeños ensamblajes que luego va uniendo. Cada vez que un

relojero interrumpe su labor (por ejemplo, para atender el teléfono), debe dejar el ensamblaje

en el que esté ocupado, lo que supone echarlo a perder. El relojero que hace los relojes de una

sola vez echa por tierra ensamblajes completos, debiendo empezar desde cero cada vez. Sin

embargo, el relojero que fabrica relojes de forma gradual no pierde el trabajo realizado en los

ensamblajes parciales ya terminados, con lo que De modo que tiende a perder menos trabajo

cada vez que se interrumpe y a fabricar relojes de manera más eficaz. ¿Cómo aplicaríamos

este razonamiento al software?



(Puede encontrar este razonamiento en el artículo de Simon titulado The Architecture of

Complexity.)



3



2.1.2 ¿Cuáles son las partes?

¿Cuáles son las partes en las que se divide un programa? Por el momento, utilizaremos mejor

el término “parte” en vez de “módulo”, lo que nos permitirá mantenernos alejados de las

nociones específicas de un lenguaje de programación. (En la próxima clase, nos centraremos

en ver cómo la programación en Java, en particular, soporta la descomposición en partes). Por

ahora, nos basta con señalar que las partes de un programa son descripciones: de hecho, el

desarrollo de software se centra en realidad en producir, analizar y ejecutar descripciones.

Pronto veremos que las partes de un programa no son todas código ejecutable, por lo que es

conveniente que también pensemos en las especificaciones como partes.



2.1.3 Diseño descendente ("top down")

Supongamos que necesitamos una parte A y que deseamos descomponerla a su vez en otras

partes. ¿Cómo llevar a cabo correctamente esta descomposición? Gran parte de los temas que

veremos en esta asignatura giran en torno a esta cuestión. Imaginemos que descomponemos A

en B y C: debería ser posible, como mínimo, construir B y C y, a continuación, obtener A

uniendo B y C.



En la década de los años 70 existía un enfoque generalizado sobre el desarrollo del software,

llamado diseño descendente, o diseño "top down". La idea de la que parte este diseño consiste

simplemente en aplicar de manera recursiva el siguiente paso:

• Si la parte que se quiere construir se halla ya disponible (como, por ejemplo, las

instrucciones de un aparato), el proceso ya está terminado.

• Si la parte no está disponible, se divide en subpartes, que se desarrollan y combinan

entre sí.



La división en subpartes se llevaba a cabo mediante la “descomposición funcional”: se piensa

en la función que debe tener la parte y se desglosa esa función en pasos más pequeños. Si



4

tomamos como ejemplo un navegador, que recoge los comandos del usuario, obtiene páginas

web y las muestra; podríamos dividir la parte Navegador en LeerComando, ObtenerPágina y

MostrarPágina.



La idea resultó atractiva en su momento, y tiene aún hoy en día sus defensores. Sin embargo,

se trata de un enfoque que fracasa rotundamente, por la razón siguiente: la primera

descomposición que se hace es la más decisiva, y aún así, no se descubre si se ha hecho

correctamente hasta que no se llega al nivel más bajo del árbol de descomposición. No es

posible hacer muchas evaluaciones durante el desarrollo del proceso, puesto que no se puede

testear una descomposición en dos partes que no se han implementado, y una vez que se ha

llegado al final, es demasiado tarde para actuar sobre las descomposiciones realizadas en

niveles superiores. Por lo tanto, desde el punto de vista del riesgo (es decir, tomar decisiones

sólo cuando se dispone de la información necesaria y minimizar la probabilidad de incurrir en

errores y el coste de los mismos), se trata de una estrategia totalmente inadecuada.



En la práctica, lo que normalmente ocurre es que la descomposición es imprecisa, y se

mantiene la esperanza de que las partes se vayan definiendo más claramente a medida que se

desciende por el árbol de descomposición. Es decir, que sólo se sabe qué problema es el que

se intenta resolver cuando se está ya estructurando la solución al mismo. A consecuencia de

ello, resulta que cuando se está llegando a los niveles más inferiores del árbol se hace

necesario recurrir a trucos de todo tipo para lograr que las partes encajen unas con otras y

puedan servir para la función deseada. Las partes quedan acopladas entre sí de forma muy

extensa, hasta tal punto que resulta imposible introducir la más mínima variación en una de

ellas sin cambiar las otras. Y, en el peor de los casos, las partes no encajarán en absoluto. Por

último, ninguna de las características del diseño top-down fa
  • Links de descarga
http://lwp-l.com/pdf6799

Comentarios de: Clase 2: Desacoplamiento I (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad