Sei sulla pagina 1di 15

Clase 20.

Estrategia de diseño
La presente clase reúne varias de las ideas ya vistas en clases anteriores: modelos de objeto
de problemas y código, diagramas de dependencia de módulos y patrones de diseño. El
objetivo que en ella se persigue es ofrecer algunos consejos de carácter general sobre cómo
enfrentarse al proceso de diseño de software.

20.1 Descripción general del proceso y pruebas


Los principales pasos del proceso de desarrollo son los siguientes:
• Análisis del problema: da como resultado un modelo de objeto y una lista de
operaciones.
• Diseño: da como resultado un modelo de objeto de código, un diagrama de
dependencia de módulos y especificaciones de módulos.
• Implementación: da como resultado un código ejecutable.

Lo ideal sería que las pruebas se llevaran a cabo a medida que se realiza el proceso de
desarrollo, de modo que los errores aparezcan lo antes posible. En un conocido estudio
sobre proyectos desarrollados por TRW e IBM, Barry Boehm llegó a la conclusión de que
el coste de corregir un error puede llegar a multiplicarse hasta por 1.000 cuando se detecta
tardíamente. Hemos empleado el término "pruebas" exclusivamente para describir la
evaluación de códigos, pero se pueden aplicar técnicas parecidas a descripciones de
problemas y diseños cuando se han registrado en una notación que tenga asociada una
semántica. (En mi grupo de trabajo hemos desarrollado una técnica de análisis para
modelos de objetos). En este curso, el estudiante deberá basar su trabajo en la
meticulosidad de las revisiones y en el uso de escenarios manuales para evaluar las
descripciones y los diseños del problema.
Por lo que a probar las implementaciones se refiere, el estudiante debe marcarse como
objetivo que las pruebas se realicen tan pronto como sea posible. La programación extrema
(XP), una metodología de desarrollo muy extendida en la actualidad, aboga por escribir las
pruebas antes incluso de haber escrito el código al que se van a aplicar éstas. Se trata de una
idea muy interesante, en primer lugar porque significa que es menos probable que una
selección de pruebas quede expuesta a sufrir los mismos errores conceptuales que esas
pruebas tratan precisamente de detectar. Además, estimula al usuario a pensar en las
especificaciones por adelantado. Es un enfoque ambicioso, aunque no siempre factible.
En vez de probar el código de una manera ad hoc, es más conveniente crear una base
sistemática de pruebas que no requieran la interacción del usuario para su ejecución y
validación. Este sistema reporta numerosos beneficios: por ejemplo, permite, cuando se
introducen cambios en un código, detectar rápidamente los nuevos errores que se han
producido al volver a ejecutar estas "pruebas de regresión". Es aconsejable hacer un uso
liberal de las certificaciones en tiempo de ejecución y comprobar las constantes de
representación.
20.2 Análisis del problema
El resultado principal del análisis de un problema es un modelo de objeto que describe las
entidades fundamentales del mismo y sus relaciones con otro problema. (El libro de texto
del curso utiliza el término "modelo de datos" para referirse a esto). Conviene escribir
descripciones breves para cada uno de los conjuntos y cada una de las relaciones del
modelo de objeto, explicando lo que significan. Aunque nos parezcan evidentes en el
momento de escribirlas, es fácil olvidar más tarde el significado de algún término. Además,
muchas veces una descripción que nos parecía clara resulta no serlo tanto cuando la vemos
por escrito. Por ejemplo, en mi grupo de trabajo estamos diseñando un nuevo componente
de control de tráfico aéreo, y hemos descubierto que en nuestro modelo de objeto el término
Flight resulta bastante confuso y que es importante describirlo con claridad.

También resulta útil escribir una lista de las operaciones primarias que el sistema
proporciona. Con ello se aprende a controlar la funcionalidad global y se puede comprobar
que el modelo de objeto es capaz de soportar las operaciones. Por ejemplo, un programa
pensado para llevar un seguimiento de precios de valores en Bolsa puede incluir
operaciones para crear y suprimir carteras, añadir acciones a carteras, actualizar el precio de
un valor, etc.

20.3 Propiedades del diseño

La fase de diseño produce como resultado principal un modelo de objeto de código que
muestra la forma en la que se implementa el estado del sistema, y un diagrama de
dependencia de módulos que representa la división del sistema en módulos y el modo en
que éstos se relacionan entre sí. En el caso de módulos que presenten complicaciones,
resulta también conveniente disponer de un esquema con las especificaciones del módulo
antes de comenzar la codificación.
¿En qué se basa un buen diseño? Obviamente, no hay un modo sencillo y objetivo de
decidir si un diseño es mejor o peor que otro, pero sí que hay ciertas propiedades clave que
permiten evaluar su calidad. Lo ideal sería un diseño que funcionara bien en todos los
aspectos, pero en la práctica normalmente es necesario sacrificar algún aspecto a cambio de
otro.
Estas propiedades clave son:
• Extensibilidad. El diseño debe ser capaz de soportar nuevas funciones. Aunque sea
perfecto en todos los demás aspectos, un sistema que no muestre disposición a
integrar el más ligero cambio o perfeccionamiento resulta inservible. Quizás no
haya necesidad de añadir nuevas funciones, pero siempre es posible que se
produzcan alteraciones en el dominio del problema que exijan introducir cambios
en el programa.
• Fiabilidad. El sistema debe tener un comportamiento fiable, lo que no significa
solamente que no se bloquee ni corrompa los datos; debe además realizar todas sus
funciones correctamente y de la forma prevista por el usuario. (Lo que, por cierto,
quiere decir que tampoco basta con que el sistema satisfaga una especificación
confusa; debe satisfacer una que el usuario comprenda fácilmente, de forma que
éste pueda predecir su comportamiento). La disponibilidad es una característica
importante si el sistema es distribuido, mientras que en los sistemas en tiempo real
tiene más importancia el tiempo: no tanto que el sistema sea rápido, sino que
complete las tareas en el tiempo previsto. La forma de contemplar la fiabilidad
varía mucho de un sistema a otro. Así, la falta de precisión a la hora de presentar
imágenes es menos grave en un navegador que en un programa de edición
electrónica. Los conmutadores telefónicos, por su parte, deben cumplir estándares
de disponibilidad extraordinariamente altos, si bien ello ocasiona de vez en cuando
errores de desvío de llamadas. Los pequeños retrasos quizás no importen mucho
cuando se trata de un cliente de correo electrónico, pero son inaceptables en el caso
del controlador de un reactor nuclear.
• Eficiencia. El consumo de recursos por parte del sistema debe ser racional, lo que
una vez más depende del contexto. Una aplicación que se ejecuta en un teléfono
móvil no puede asumir la misma disponibilidad de memoria que la que se ejecuta
en un ordenador de consola. Los recursos más específicos son el tiempo y el
espacio que consume el programa que se ejecuta. Pero no hay que olvidar que,
como ha demostrado Microsoft, el tiempo empleado en el desarrollo del programa
puede tener idéntica importancia, al igual que otro recurso que no se debe pasar por
alto: el dinero. Un diseño que se implemente de modo económico puede ser
preferible a otro que funcione mejor conforme a otros parámetros pero que resulte
más caro.

20.4 Estrategia: visión general


¿Cómo se obtienen estas propiedades?

20.4.1 Extensibilidad
• Suficiencia del modelo de objeto. El modelo de objeto del problema debe ser capaz
de describir éste de un modo suficientemente fiel. Uno de los obstáculos
habituales a la hora de extender un sistema es la falta de espacio para añadir una
nueva función, debido a que sus nociones no se hallan expresadas en el código.
Microsoft Word nos muestra un ejemplo de este tipo de problemas. Word se
diseñó asumiendo que los párrafos eran la noción clave de la estructura de los
documentos, sin que se incluyera la noción de flujos de texto (los espacios físicos
del documento a través de los que se hilvana el texto) ni ningún tipo de estructura
jerárquica. A consecuencia de ello, Word no admite fácilmente la división en
secciones y no es capaz de ubicar figuras. Es importante tener mucho cuidado de
no optimizar el modelo de objeto del problema y eliminar subestructuras que no
parezcan necesarias a primera vista. No se debe introducir una abstracción para
sustituir nociones más concretas a menos que se esté totalmente seguro de que se
halla bien fundada. Como se suele decir, toda generalizaciones suele conllevar
errores.
• Localización y desacoplamiento. Aunque el código consiga reunir suficientes
nociones que permitan la adición de nuevas funcionalidades, puede resultar
complicado realizar el cambio que se desea introducir sin alterar el código en todo
el sistema. Para evitar esto, el diseño debe proporcionar localización: cuestiones
distintas deben estar separadas, en la medida de lo posible, en distintas regiones
del código. Asimismo, los módulos deben hallarse desacoplados todo lo posible
unos de otros, de modo que un cambio no provoque alteraciones en cascada. Ya
hemos visto ejemplos de desacoplamiento en la clase sobre espacios de nombres y,
más recientemente, en las clases sobre patrones de diseño (por ejemplo, al hablar
de Observer). Estas propiedades se ven con mayor claridad en el diagrama de
dependencia de módulos, razón por la que construimos éste. Las especificaciones
del módulo son también importantes para obtener localización; en este sentido,
una especificación debe ser coherente, con una colección de comportamientos
claramente definida (sin características ad hoc especiales) y una división
terminante entre los métodos, de modo que éstos sean ampliamente independientes
unos de otros.

20.4.2 Fiabilidad
• Esmero en el modelado. No es fácil dotar de fiabilidad a un sistema ya existente. La
clave para lograr que un software sea fiable radica en desarrollarlo con el mayor
cuidado, manteniendo ese esmero durante todo el proceso de modelado. Los
problemas más graves en sistemas críticos no provienen de errores de código, sino
de fallos en el análisis del problema; normalmente porque el analista no ha tenido en
cuenta alguna propiedad del entorno en el que el sistema se halla insertado. Un
ejemplo de ello es el fallo mecánico del Airbus en el aeropuerto de Varsovia.
• Revisión, análisis y prueba. Por mucho cuidado que se ponga, es inevitable cometer
errores. Por ello, en todo proceso de desarrollo es preciso decidir por adelantado
cómo se van a solucionar éstos. En la práctica, uno de los métodos más eficaces
desde el punto de vista del coste a la hora de detectar errores de software, sea cual
sea el modelo, la especificación o el código utilizados, es el de la revisión por pares.
Hasta ahora, usted solamente habrá podido explorar este método con el profesor
auxiliar y en las clases de laboratorio; en el proyecto de final de curso le conviene
aprovechar la oportunidad de trabajar en equipo para analizar el trabajo de sus
compañeros. De esta forma, tanto usted como ellos ahorrarán tiempo a largo plazo.

Análisis y pruebas más específicos permiten hallar aquellos errores que hayan pasado
inadvertidos en el análisis de pares. Un análisis útil y fácil de realizar consiste
simplemente en comprobar la coherencia de los modelos. ¿Soporta el modelo de objeto
del código todos los estados del modelo de objeto del problema? ¿Se combinan
adecuadamente las multiplicidades y mutabilidades? ¿Tiene en cuenta el diagrama de
dependencia de módulos todas las restricciones del modelo de objeto? Otra posibilidad es
comprobar el código con los modelos. La herramienta Womble, que se puede descargar
desde el sitio http://sdg.lcs.mit.edu, construye automáticamente modelos de objetos a
partir de Codi-bait (Byte-code). Hemos descubierto numerosos errores en nuestro código
examinando modelos extraídos y comparándolos con los modelos planeados. Es
conveniente, por tanto, que usted compruebe las propiedades esenciales de su modelo de
objeto preguntándose si está seguro de que mantiene las propiedades. Suponga, por
ejemplo, que su modelo dice que un vector nunca es compartido por dos objetos de
cuenta bancaria. En tal caso, usted debería ser capaz de explicar por qué el código
garantiza esta afirmación. Siempre que su modelo de objeto contenga una restricción que
no se haya podido expresar gráficamente es especialmente aconsejable verificarla, ya que
es probable que comprenda relaciones que sobrepasen los límites del objeto

20.4.3 Eficiencia

• Modelo de objeto. La elección del modelo de objeto del código es esencial, ya que
una vez elegido resulta muy difícil de cambiar. Por ello es conveniente considerar
los objetivos de rendimiento crítico al comenzar el diseño. Más adelante veremos
algunos ejemplos de transformaciones que se pueden aplicar al modelo de objeto
para mejorar su eficiencia.
• Evitar el sesgo. Al desarrollar el modelo de objeto del problema deben dejarse de
lado las cuestiones relativas a la implementación. Cuando un modelo de problema
contiene detalles sobre su implementación se dice que está sesgado, ya que favorece
un tipo de implementación en perjuicio de otro. Ello supone reducir prematuramente
el espacio a posibles implementaciones, entre las que podría hallarse la más
eficiente.
• Optimización. La palabra "optimización" es engañosa: invariablemente significa
una mejora del rendimiento, pero en detrimento de otras cualidades (como la nitidez
de la estructura). Y si no se tiene cuidado con la optimización se corre el riesgo de
que el sistema acabe siendo peor en todos los aspectos. Antes de introducir un
cambio para mejorar el rendimiento, asegúrese de que tiene suficientes pruebas de
que las alteraciones tendrán probablemente un efecto muy positivo. En general es
aconsejable resistir la tentación de optimizar y concentrarse en lograr que el diseño
sea sencillo y claro. En cualquier caso, los diseños que cumplen estas premisas
suelen ser los que muestran mayor eficiencia y, en caso de que no la muestren,
siempre son los más fáciles de modificar.
• Elección de representaciones. En vez de perder el tiempo en lograr pequeñas
mejoras del rendimiento, es mejor centrarse en las clases de mejora positiva que se
pueden obtener eligiendo una representación diferente para un tipo abstracto, por
ejemplo, capaz de cambiar una operación de tiempo lineal a tiempo constante.
Muchos de ustedes lo habrán podido comprobar en su proyecto de MapQuick:
cuando se elige una representación para grafos que requiere un tiempo proporcional
al tamaño de todo el grafo para obtener vecinos de un nodo, la búsqueda resulta
totalmente impracticable. Asimismo, no se debe olvidar que compartir objetos
puede tener efectos positivos, por lo que hay que considerar la posibilidad de
utilizar tipos invariables y hacer que los objetos compartan una estructura. Por
ejemplo, en MapQuick, Route es un tipo invariable; si se implementa compartiendo
estructura, cada extensión de la ruta por un nodo durante la búsqueda exige
solamente situar un único nodo en vez de una copia entera de la ruta.
Ante todo, recuerde que lo más importante es la sencillez. Piense en lo fácil que resulta
terminar embrollado en una masa de complejidades, incapaz de alcanzar ninguna de estas
propiedades. Lo más sensato es diseñar y construir primero un sistema mínimo, lo más
sencillo posible, y sólo entonces comenzar a añadir recursos.

20.5 Transformaciones del modelo de objeto

En modelos de objetos de códigos y problemas, hemos visto dos usos distintos de la misma
notación. ¿Cómo puede un modelo de objeto describir un problema a la vez que describe
una implementación? Para responder a esta pregunta resulta útil pensar en la interpretación
de un modelo de objeto como un proceso en dos fases. En la primera, se interpreta el
modelo en función de conjuntos y relaciones abstractas. En la segunda fase, se asocian
estos conjuntos y relaciones, bien a las entidades y relaciones del problema, o bien a los
objetos y campos de la implementación.

Supongamos, por ejemplo, que tenemos un modelo de objeto con una relación employs
(contrata) que asocia Company (empresa) a Employee (empleado).

Matemáticamente, vemos esto como una expresión de dos conjuntos y de una relación entre
ambos. La restricción de multiplicidad nos dice que cada employee se asocia, conforme a la
relación employs, a una company como máximo. A la hora de interpretarlo como un modelo
de objeto de problema, contemplaremos el conjunto Company como un conjunto de
empresas del mundo real (real world), y Employee como un conjunto de personas que son
contratadas por las empresas. La relación employs relaciona c con e cuando la compañía c
contrata a la persona e.

Si lo interpretamos como un modelo de objeto de código, en cambio, contemplaremos el


conjunto Company como un conjunto de objetos situados en una pila (heap) de la clase
Company, y Employee como un conjunto de objetos situados en una pila de la clase
Employee. Aquí, la relación employs pasa a ser un campo de especificación que asocia c y e
cuando el objeto c mantiene una referencia a una colección (oculto en la representación de
Company) que contenga la referencia e.
Nuestra estrategia consiste en partir de un modelo de objeto de problema y transformarlo en
uno de código. Por lo general, uno y otro serán considerablemente distintos, dado que un
modelo que proporciona una descripción clara del problema no suele ofrecer una buena
implementación.
¿Cómo se obtiene esta implementación? Un método de trabajo bastante apropiado consiste
en realizar una sesión de brainstorming y, a partir de ella, jugar con diferentes fragmentos
de modelos de código hasta que encajen. Es necesario comprobar que el modelo de objeto
de código se corresponde fielmente al modelo de objeto del problema. Debe ser capaz de
representar al menos toda la información sobre los estados del modelo de problema, de
forma que sea posible, por ejemplo, añadir una relación, pero que no sea posible eliminarla.
Otra forma de llevar a cabo la transformación es mediante la aplicación sistemática de una
serie de pequeñas transformaciones. Cada una de ellas se elige de entre un repertorio de
transformaciones que preservan el contenido de los datos del modelo. De esta forma, como
cada paso mantiene el modelo intacto, toda la serie se mantendrá también invariable. Hasta
el momento, nadie ha propuesto un repertorio completo de tales transformaciones (lo que
representa un problema de investigación), pero sí que hay varias que se pueden identificar
como las más útiles. Antes de seguir adelante, veamos un ejemplo.

20.6 Ejemplo de Folio Tracker

Supongamos que queremos diseñar un programa para realizar el seguimiento de una cartera
de valores. El modelo de objeto nos da la descripción de los elementos del problema. Folio
es el conjunto de carteras, cada una de ellas con un Name (nombre), que contiene un
conjunto de posiciones Pos. Cada posición corresponde a un Stock (valor) concreto, del que
se mantiene algún número. Un stock puede tener un valor (cuando se haya obtenido
recientemente una cotización), y tiene asignado un símbolo de registro de cotización que
permanece invariable. Estos símbolos identifican únicamente a los valores. Se puede situar
un observador (Watch) en una cartera, lo que hace que el sistema muestre la información
relativa a la cartera cuando se produzcan determinados cambios en ésta.
20.7 Catalogo de transformaciones

20.7.1 Introducción de una generalización

Si A y B son conjuntos con relaciones p y q, de la misma multiplicidad y mutabilidad, al


conjunto C, podemos introducir una generalización AB y sustituir p y q por una única
relación pq de AB a C. La relación pq puede no tener la misma multiplicidad fuente que p y
q.

20.7.2 Inserción de una colección

Si una relación r de A a B tiene una multiplicidad objetivo que permite más de un elemento,
podemos interponer una colección, como un vector o un conjunto, entre A y B, y sustituir r
por una relación a dos relaciones, una desde A a la colección y otra desde la colección a B.
En nuestro ejemplo de Folio Tracker, podríamos sustituir/interponer un vector en la
relación posns entre Folio y Pos. Obsérvense las marcas de mutabilidad; la colección es
generalmente construida y reorganizada con su contenedor.

20.7.3 Inversión de una relación

Dado que la dirección de una relación no implica su capacidad para recorrerla en esa
dirección, siempre cabe la posibilidad de invertirla. Al final, naturalmente, interpretaremos
las relaciones como campos, por lo que es habitual invertir relaciones para orientarlas en la
dirección en que se espera que sean recorridas. En nuestro ejemplo, podríamos invertir la
relación name, ya que posiblemente querremos recorrerla desde nombres (names) a carteras
(folios), obteniendo una relación folio, por ejemplo.

20.7.4 Traslado de una relación

A veces es posible trasladar el objetivo o la fuente de una relación sin que ello suponga
pérdida de datos. Por ejemplo, una relación de A a C se puede sustituir por una relación de
B a C si A y B se hallan en una correspondencia de uno a uno.
En nuestro ejemplo, podemos sustituir la relación val entre Stock y Dollar por una relación
entre Ticker y Dollar. Resulta conveniente utilizar un mismo nombre para la nueva
relación, aunque técnicamente se trate de una relación diferente.

20.7.5 Relación a una tabla

Una relación de A a B que tenga una multiplicidad objetivo igual a exactamente uno o
cero-o-uno, puede sustituirse por una tabla. Dado que solamente se necesita una tabla,
puede utilizarse el patrón de instancia única (singleton), de manera que la tabla se pueda
referenciar por un nombre global. Si la multiplicidad objetivo de la relación es cero o uno,
la tabla debe ser capaz de admitir correlaciones a valores nulos.
En FolioTracker, por ejemplo, podríamos convertir la relación folio a una tabla que
permitiera hallar carteras mediante una operación de verificación constante. Así,
tendríamos:

Sería interesante convertir también en una tabla la relación val que vincula Ticker a Dollar, ya que ello haría
posible que la búsqueda de valores para símbolos de registro de cotización se encapsulara en un objeto
distinto de la cartera de valores. En este caso, debido a la multiplicidad cero-o-uno, necesitaremos una tabla
capaz de almacenar valores nulos.
20.7.6 Adición de estados redundantes

Suele ser útil añadir componentes de estado redundantes a un modelo de objeto. Dos casos
comunes de ello son la adición del traslado de una relación y la adición de la composición
de dos relaciones. Si p asocia A a B, podemos añadir el traslado q de B a A. Si p asocia A a
B, y q asocia B a C, podemos añadir la composición pq de A a C.

20.7.7 Descomposición de relaciones mutables

Supongamos que un conjunto A tiene relaciones de salida p, q y r, de las cuales p y q son


estáticas. Si se implementa directamente, la presencia de r hará que A sea mutable. Por
tanto, sería conveniente descomponer la relación r utilizando, por ejemplo, la
transformación Relación a Tabla, e implementar a continuación A como un tipo de datos
inmutable.
Volviendo a nuestro ejemplo, la descomposición de la relación val encaja en este patrón, ya
que hace inmutable a la relación Stock. La misma idea subyace en el patrón de diseño
Flyweight.

20.7.8 Interpolación de una interfaz

Esta transformación sustituye el objetivo de una relación R entre un conjunto A y un


conjunto B por un superconjunto X de B. Por regla general, A y B pasarán a ser clases y X se
convertirá en una clase o interfaz abstracta. Gracias a ello, la relación R se podrá ampliar
para asociar elementos de A a elementos de un nuevo conjunto C, implementando C como
una subclase de X. Dado que X descompone las propiedades compartidas de sus subclases,
tendrá una especificación más simple que B; la dependencia de A en X es, por lo tanto,
menos rígida que su dependencia anterior en B. Para compensar la pérdida de comunicación
entre A y B, se puede añadir (mediante una nueva transformación) una relación adicional
desde B de regreso a A.
El patrón de diseño Observer (observador)es un ejemplo del resultado de esta
transformación. En nuestro ejemplo, podríamos convertir los objetos Watch en
observadores de los objetos Folio:
20.7.9 Eliminación de conjuntos dinámicos

No es posible implementar como subclase un subconjunto que no sea estático: los objetos
no pueden migrar entre clases en tiempo de ejecución, por lo que es necesario
transformarlos. Una clasificación en subconjuntos puede transformarse en una relación del
subconjunto a un conjunto de valores de clasificación.

Cuando solamente hay uno o dos subconjuntos dinámicos, los valores de clasificación
pueden ser valores booleanos primarios.

La clasificación se puede también transformar en varios conjuntos únicos, uno para cada
subconjunto.

20.8 Modelo de objeto final

El siguiente gráfico muestra el resultado en el ejemplo de Folio Tracker de la secuencia de transformaciones


que hemos comentado. Llegados a este punto, debemos comprobar que nuestro modelo es capaz de soportar
las operaciones que el sistema debe realizar, y utilizar los escenarios de estas operaciones para construir un
diagrama de dependencia del modelo que nos permita verificar la viabilidad del diseño. Tendremos que añadir
módulos para la interfaz de usuario y para cualquier otro dispositivo que haya que utilizar para obtener las
cotizaciones de las acciones. Asimismo, nos conviene añadir un mecanismo para almacenar carteras en disco
de modo permanente. Para algunas de estas tareas, necesitaremos volver sobre nuestros pasos y construir un
modelo de objeto del problema, pero para otras partes habrá que trabajar en el nivel de implementación.

Así, por ejemplo, si queremos que los usuarios puedan dar nombre a los archivos para almacenar carteras
en ellos, es prácticamente seguro que necesitaremos un modelo de objeto del problema. Sin embargo, la
construcción de un modelo no resultará posiblemente eficaz para resolver cuestiones relativas al modo de
analizar una página Web para obtener cotizaciones de acciones.
20.9 Lenguaje unificado de modelado (UML) y métodos
Existen varios métodos que describen detalladamente estrategias para el desarrollo
orientado a objetos, indicando qué modelos hay que crear y en qué orden. En un escenario
industrial, establecer un método como estándar puede servir de ayuda a la hora de coordinar
el trabajo de diversos equipos. Aunque en este curso no se enseña ningún método en
concreto, las nociones que usted ha asimilado son la base de la mayoría de ellos, por lo que
no debería tener problema en aprender cualquier método específico. Casi todos los métodos
utilizan modelos de objeto, y algunos utilizan también diagramas de dependencia de
módulos. Si desea conocer más sobre la materia, le recomiendo introducir en Google una
búsqueda con los términos "Catalysis", "Fusion" y "Syntropy"; que le dirigirá a libros y
materiales online.

En los últimos años se han producido diversos intentos de estandarización de las


notaciones. El Object Management Group (grupo de administración de objetos) ha
adoptado como notación estándar el lenguaje unificado de modelado (UML), que es en
realidad una amplia colección de notaciones diversas, en la que se incluye una notación de
modelado de objetos similar a la nuestra (aunque mucho más compleja).

Potrebbero piacerti anche