OOAD - Diseño orientado a objetos
Después de la fase de análisis, el modelo conceptual se desarrolla aún más en un modelo orientado a objetos utilizando diseño orientado a objetos (OOD). En OOD, los conceptos independientes de la tecnología en el modelo de análisis se asignan a las clases de implementación, se identifican las restricciones y se diseñan las interfaces, lo que da como resultado un modelo para el dominio de la solución. En pocas palabras, se elabora una descripción detallada que especifica cómo se construirá el sistema sobre tecnologías concretas.
Las etapas del diseño orientado a objetos se pueden identificar como:
- Definición del contexto del sistema
- Diseño de la arquitectura del sistema
- Identificación de los objetos en el sistema
- Construcción de modelos de diseño
- Especificación de interfaces de objetos
Diseño de sistemas
El diseño de sistemas orientados a objetos implica definir el contexto de un sistema seguido del diseño de la arquitectura del sistema.
Context- El contexto de un sistema tiene una parte estática y otra dinámica. El contexto estático del sistema se diseña utilizando un diagrama de bloques simple de todo el sistema que se expande en una jerarquía de subsistemas. El modelo de subsistema está representado por paquetes UML. El contexto dinámico describe cómo el sistema interactúa con su entorno. Se modela usandouse case diagrams.
System Architecture- La arquitectura del sistema se diseña sobre la base del contexto del sistema de acuerdo con los principios del diseño arquitectónico y el conocimiento del dominio. Normalmente, un sistema se divide en capas y cada capa se descompone para formar los subsistemas.
Descomposición orientada a objetos
La descomposición significa dividir un gran sistema complejo en una jerarquía de componentes más pequeños con menor complejidad, según los principios de divide y vencerás. Cada componente principal del sistema se denomina subsistema. La descomposición orientada a objetos identifica objetos autónomos individuales en un sistema y la comunicación entre estos objetos.
Las ventajas de la descomposición son:
Los componentes individuales son de menor complejidad y, por tanto, más comprensibles y manejables.
Permite la división de la fuerza laboral con habilidades especializadas.
Permite reemplazar o modificar subsistemas sin afectar a otros subsistemas.
Identificación de la concurrencia
La concurrencia permite que más de un objeto reciba eventos al mismo tiempo y que más de una actividad se ejecute simultáneamente. La concurrencia se identifica y representa en el modelo dinámico.
Para habilitar la concurrencia, a cada elemento concurrente se le asigna un hilo de control separado. Si la simultaneidad es a nivel de objeto, entonces se asignan dos subprocesos de control diferentes a dos objetos concurrentes. Si dos operaciones de un solo objeto son de naturaleza simultánea, ese objeto se divide entre diferentes subprocesos.
La concurrencia está asociada con los problemas de integridad de los datos, interbloqueo e inanición. Por lo tanto, se debe establecer una estrategia clara siempre que se requiera concurrencia. Además, la concurrencia requiere ser identificada en la propia etapa de diseño y no puede dejarse para la etapa de implementación.
Identificación de patrones
Al diseñar aplicaciones, se adoptan algunas soluciones comúnmente aceptadas para algunas categorías de problemas. Estos son los patrones de diseño. Un patrón se puede definir como un conjunto documentado de bloques de construcción que se pueden usar en ciertos tipos de problemas de desarrollo de aplicaciones.
Algunos patrones de diseño de uso común son:
- Patrón de fachada
- Patrón de separación de vista de modelo
- Patrón de observador
- Patrón de controlador de vista de modelo
- Publicar patrón de suscripción
- Patrón de proxy
Control de eventos
Durante el diseño del sistema, los eventos que pueden ocurrir en los objetos del sistema deben identificarse y tratarse adecuadamente.
Un evento es una especificación de un hecho significativo que tiene una ubicación en el tiempo y el espacio.
Hay cuatro tipos de eventos que se pueden modelar, a saber:
Signal Event - Un objeto con nombre arrojado por un objeto y atrapado por otro objeto.
Call Event - Un evento sincrónico que representa el despacho de una operación.
Time Event - Un evento que representa el paso del tiempo.
Change Event - Un evento que representa un cambio de estado.
Manejo de condiciones de contorno
La fase de diseño del sistema debe abordar la inicialización y la terminación del sistema en su conjunto, así como de cada subsistema. Los diferentes aspectos que se documentan son los siguientes:
La puesta en marcha del sistema, es decir, la transición del sistema del estado no inicializado al estado estable.
La terminación del sistema, es decir, el cierre de todos los hilos en ejecución, la limpieza de recursos y los mensajes que se enviarán.
La configuración inicial del sistema y la reconfiguración del sistema cuando sea necesario.
Previsión de averías o cese no deseado del sistema.
Las condiciones de contorno se modelan utilizando casos de uso de límites.
Diseño de objetos
Una vez desarrollada la jerarquía de subsistemas, se identifican los objetos en el sistema y se diseñan sus detalles. Aquí, el diseñador detalla la estrategia elegida durante el diseño del sistema. El énfasis se desplaza de los conceptos del dominio de la aplicación hacia los conceptos informáticos. Los objetos identificados durante el análisis se graban para su implementación con el objetivo de minimizar el tiempo de ejecución, el consumo de memoria y el costo general.
El diseño de objetos incluye las siguientes fases:
- Identificación de objeto
- Representación de objetos, es decir, construcción de modelos de diseño.
- Clasificación de operaciones
- Diseño de algoritmos
- Diseño de relaciones
- Implementación de control para interacciones externas
- Empaquetar clases y asociaciones en módulos
Identificación de objetos
El primer paso del diseño de objetos es la identificación de objetos. Los objetos identificados en las fases de análisis orientado a objetos se agrupan en clases y se refinan para que sean adecuados para la implementación real.
Las funciones de esta etapa son:
Identificar y refinar las clases en cada subsistema o paquete
Definición de vínculos y asociaciones entre las clases
Diseñar las asociaciones jerárquicas entre las clases, es decir, la generalización / especialización y las herencias.
Diseñando agregaciones
Representación de objetos
Una vez identificadas las clases, es necesario representarlas mediante técnicas de modelado de objetos. Esta etapa implica esencialmente la construcción de diagramas UML.
Hay dos tipos de modelos de diseño que deben producirse:
Static Models - Describir la estructura estática de un sistema mediante diagramas de clases y diagramas de objetos.
Dynamic Models - Describir la estructura dinámica de un sistema y mostrar la interacción entre clases mediante diagramas de interacción y diagramas de gráficos de estado.
Clasificación de operaciones
En este paso, la operación a realizar sobre los objetos se define mediante la combinación de los tres modelos desarrollados en la fase OOA, a saber, modelo de objeto, modelo dinámico y modelo funcional. Una operación especifica qué se debe hacer y no cómo se debe hacer.
Las siguientes tareas se realizan con respecto a las operaciones:
Se desarrolla el diagrama de transición de estado de cada objeto del sistema.
Las operaciones se definen para los eventos recibidos por los objetos.
Se identifican los casos en los que un evento desencadena otros eventos en el mismo o en diferentes objetos.
Se identifican las suboperaciones dentro de las acciones.
Las principales acciones se expanden a diagramas de flujo de datos.
Diseño de algoritmos
Las operaciones en los objetos se definen mediante algoritmos. Un algoritmo es un procedimiento paso a paso que resuelve el problema planteado en una operación. Los algoritmos se centran en cómo se debe hacer.
Puede haber más de un algoritmo correspondiente a una operación determinada. Una vez que se identifican los algoritmos alternativos, se selecciona el algoritmo óptimo para el dominio del problema dado. Las métricas para elegir el algoritmo óptimo son:
Computational Complexity - La complejidad determina la eficiencia de un algoritmo en términos de tiempo de cálculo y requisitos de memoria.
Flexibility - La flexibilidad determina si el algoritmo elegido se puede implementar de manera adecuada, sin pérdida de idoneidad en varios entornos.
Understandability - Esto determina si el algoritmo elegido es fácil de entender e implementar.
Diseño de Relaciones
La estrategia para implementar las relaciones debe definirse durante la fase de diseño del objeto. Las principales relaciones que se abordan comprenden asociaciones, agregaciones y herencias.
El diseñador debe hacer lo siguiente con respecto a las asociaciones:
Identifique si una asociación es unidireccional o bidireccional.
Analice la ruta de las asociaciones y actualícelas si es necesario.
Implementar las asociaciones como un objeto distinto, en caso de relaciones de varios a varios; o como enlace a otro objeto en caso de relaciones uno a uno o uno a varios.
Con respecto a las herencias, el diseñador debe hacer lo siguiente:
Ajuste las clases y sus asociaciones.
Identifica clases abstractas.
Adopte disposiciones para que los comportamientos se compartan cuando sea necesario.
Implementación de Control
El diseñador de objetos puede incorporar mejoras en la estrategia del modelo de gráfico de estados. En el diseño de sistemas, se hace una estrategia básica para realizar el modelo dinámico. Durante el diseño de objetos, esta estrategia se embellece adecuadamente para una implementación adecuada.
Los enfoques para la implementación del modelo dinámico son:
Represent State as a Location within a Program- Este es el enfoque tradicional basado en procedimientos en el que la ubicación del control define el estado del programa. Una máquina de estados finitos se puede implementar como programa. Una transición forma una declaración de entrada, la ruta de control principal forma la secuencia de instrucciones, las ramas forman las condiciones y las rutas hacia atrás forman los bucles o iteraciones.
State Machine Engine- Este enfoque representa directamente una máquina de estado a través de una clase de motor de máquina de estado. Esta clase ejecuta la máquina de estado a través de un conjunto de transiciones y acciones proporcionadas por la aplicación.
Control as Concurrent Tasks- En este enfoque, un objeto se implementa como una tarea en el lenguaje de programación o el sistema operativo. Aquí, un evento se implementa como una llamada entre tareas. Conserva la concurrencia inherente de objetos reales.
Clases de empaque
En cualquier proyecto grande, la partición meticulosa de una implementación en módulos o paquetes es importante. Durante el diseño de objetos, las clases y los objetos se agrupan en paquetes para permitir que varios grupos trabajen cooperativamente en un proyecto.
Los diferentes aspectos del embalaje son:
Hiding Internal Information from Outside View - Permite que una clase se vea como una "caja negra" y permite cambiar la implementación de la clase sin requerir que ningún cliente de la clase modifique el código.
Coherence of Elements - Un elemento, como una clase, una operación o un módulo, es coherente si está organizado en un plan coherente y todas sus partes están intrínsecamente relacionadas para que sirvan a un objetivo común.
Construction of Physical Modules - Las siguientes pautas ayudan a construir módulos físicos -
Las clases de un módulo deben representar elementos o componentes similares en el mismo objeto compuesto.
Las clases estrechamente conectadas deben estar en el mismo módulo.
Las clases no conectadas o conectadas débilmente deben colocarse en módulos separados.
Los módulos deben tener una buena cohesión, es decir, una alta cooperación entre sus componentes.
Un módulo debe tener un acoplamiento bajo con otros módulos, es decir, la interacción o interdependencia entre módulos debe ser mínima.
Optimización del diseño
El modelo de análisis captura la información lógica sobre el sistema, mientras que el modelo de diseño agrega detalles para respaldar el acceso eficiente a la información. Antes de implementar un diseño, debe optimizarse para que la implementación sea más eficiente. El objetivo de la optimización es minimizar el costo en términos de tiempo, espacio y otras métricas.
Sin embargo, la optimización del diseño no debe ser excesiva, ya que la facilidad de implementación, el mantenimiento y la extensibilidad también son preocupaciones importantes. A menudo se ve que un diseño perfectamente optimizado es más eficiente pero menos legible y reutilizable. Por lo tanto, el diseñador debe encontrar un equilibrio entre los dos.
Las diversas cosas que se pueden hacer para la optimización del diseño son:
- Agregar asociaciones redundantes
- Omitir asociaciones no utilizables
- Optimización de algoritmos
- Guarde los atributos derivados para evitar el recálculo de expresiones complejas
Adición de asociaciones redundantes
Durante la optimización del diseño, se comprueba si la obtención de nuevas asociaciones puede reducir los costos de acceso. Aunque estas asociaciones redundantes pueden no agregar ninguna información, pueden aumentar la eficiencia del modelo general.
Omisión de asociaciones no utilizables
La presencia de demasiadas asociaciones puede hacer que un sistema sea indescifrable y, por lo tanto, reducir la eficiencia general del sistema. Por lo tanto, durante la optimización, se eliminan todas las asociaciones no utilizables.
Optimización de algoritmos
En los sistemas orientados a objetos, la optimización de la estructura de datos y los algoritmos se realizan de manera colaborativa. Una vez que el diseño de la clase está en su lugar, las operaciones y los algoritmos deben optimizarse.
La optimización de los algoritmos se obtiene mediante:
- Reordenamiento del orden de las tareas computacionales
- Inversión del orden de ejecución de los bucles del establecido en el modelo funcional
- Eliminación de caminos muertos dentro del algoritmo
Guardar y almacenar atributos derivados
Los atributos derivados son aquellos atributos cuyos valores se calculan en función de otros atributos (atributos base). El recálculo de los valores de los atributos derivados cada vez que se necesitan es un procedimiento que requiere mucho tiempo. Para evitar esto, los valores se pueden calcular y almacenar en sus formas calculadas.
Sin embargo, esto puede plantear anomalías de actualización, es decir, un cambio en los valores de los atributos básicos sin el correspondiente cambio en los valores de los atributos derivados. Para evitar esto, se toman los siguientes pasos:
Con cada actualización del valor del atributo base, el atributo derivado también se vuelve a calcular.
Todos los atributos derivados se vuelven a calcular y actualizar periódicamente en un grupo en lugar de después de cada actualización.
Documentación de diseño
La documentación es una parte esencial de cualquier proceso de desarrollo de software que registra el procedimiento de creación del software. Las decisiones de diseño deben documentarse para cualquier sistema de software no trivial para transmitir el diseño a otros.
Áreas de uso
Aunque es un producto secundario, una buena documentación es indispensable, particularmente en las siguientes áreas:
- Al diseñar software que está siendo desarrollado por varios desarrolladores
- En estrategias iterativas de desarrollo de software
- En el desarrollo de versiones posteriores de un proyecto de software.
- Para evaluar un software
- Para encontrar condiciones y áreas de prueba.
- Para el mantenimiento del software.
Contenido
Una documentación beneficiosa debe incluir esencialmente los siguientes contenidos:
High–level system architecture - Diagramas de procesos y diagramas de módulos
Key abstractions and mechanisms - Diagramas de clases y diagramas de objetos.
Scenarios that illustrate the behavior of the main aspects - Diagramas de comportamiento
Caracteristicas
Las características de una buena documentación son:
Conciso y al mismo tiempo inequívoco, coherente y completo
Trazable a las especificaciones de requisitos del sistema
Well-structured
Diagramático en lugar de descriptivo