Clase 4 - Diseño Flashcards

1
Q

¿Cuales son los niveles que existen en el proceso de diseño?

A

En el proceso de diseño, poseemos tres niveles

  1. Diseño arquitectónico: identifica las componentes necesarias del sistema, su comportamiento y sus relaciones.
  2. Diseño de alto nivel: identifica cueles son los módulos necesarios para el sistema, que deben hacer y como se organizan / interconectan.
  3. Diseño detallado o diseño lógico: establecen como se implementan los módulos de modo que se satisfagan sus especificaciones, incluyendo detalles del procesamiento lógico y de las estructuras de datos.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

¿Qué criterios se utilizan para evaluar un diseño?

A

El diseño de un sistema es ****correcto******, si un sistema construido precisamente de acuerdo con el diseño satisface los requerimientos del sistema. Sin embargo, puede haber muchos diseños los cuales sean correctos pero la meta es encontrar aquel que sea el mejor posible de acuerdo a las limitaciones.

Para evaluar un diseño es necesario especificar propiedades y criterios para que estos puedan ser usados al comparar diseños, como siempre los criterios de calidad son a menudo subjetivos y no cuantificables, así que los criterios que presentaremos son simplemente reglas prácticas que nos ayudan a evaluar un diseño:

  1. **Corrección**: verifica si el diseño implementa los requerimientos y si es factible de desarrollar dada las restricciones.
  2. ****Eficiencia****: se centra en el uso apropiado de los recursos del sistema. Este criterio, debido al abaratamiento del **hardware**** toma un segundo plano, excepto para los sistemas de tiempo real donde es muy importante.
  3. ******Simplicidad: es un criterio que tiene un impacto directo en el mantenimiento dado a que que lo primero que debe realizarse al mantener un sistema es entenderlo y como el costo de mantenimiento es caro, un diseño simple y entendible contribuirá en gran medida al costo de mantenimiento.

<aside>
⚠️ El diseñador debe encontrar un balance entre la eficiencia y la simplicidad, ya que ********************************************no son independientes********************************************.

</aside>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

¿Cuales son los principios de diseño?

A

Se utiliza el principio básico de ******divide y vencerás******, donde el problema se divide en partes que sean manejables separadamente, es decir, que puedan ****modificarse**** y ******solucionarse****** de forma independiente. Sin embargo, estas partes no pueden ser totalmente independientes entre sí, dado a que deben poder comunicarse para solucionar el problema principal del sistema y esa comunicación agrega complejidad. Por lo que, a medida que aumenta la cantidad de particiones también lo hace el **********costo del particionado********** el cual incluye el costo de la comunicación que mencionamos anteriormente, por ende debemos parar de particionar cuando el costo supere el beneficio.

Tratar de mantener la **mayor independencia posible** entre módulos nos permite simplificar el diseño y facilitar el mantenimiento, pero además el particionado del problema determina una cierta jerarquía entre componentes en el diseño. La relación que se establece entre elementos en la jerarquía depende de los métodos usados para desarrollar el diseño, pero la más común es “es parte de”

La abstracción es una herramienta que nos permite considerar el comportamiento externo de una componente, son preocuparnos en los detalles internos que produce dicho comportamiento.

La partición es esencialmente determinar los componentes de un sistema, como estos componentes no están aislados totalmente deben de comunicarse con otros componentes y nosotros como diseñadores debemos especificar como una componente interacciona con otra, para que nos podamos concentrar en un solo componente a la vez es de suma importancia usar la abstracción de los componentes.

La abstracción se usa tanto en componentes existentes como en componentes en el proceso de diseño

  • Abstracción en componentes existentes
    • Se representa a las componentes como cajas negras, ocultando el detalle y provee solamente el comportamiento externo.
    • Tiene un rol muy importante en el mantenimiento dado a que nos ayuda a comprender sistemas existentes.
  • Abstracción durante el proceso de diseño
    • Como las componentes todavía no existen se debe hacer el particionado y para determinar como una componente interactúa con otra sólo el comportamiento externo es relevante.
    • Permite concentrarse en un componente a la vez.

Hay dos mecanismos de abstracción comunes

  • ********Abstracción funcional:******** un módulo se especifica por la función que realiza. ******************
  • ********Abstracción de datos:******** una entidad del mundo real provee servicios al entorno, en el caso de las entidades de datos esto es similar ciertas operaciones son requeridas para un objeto de datos. En este caso, los datos no se tratan simplemente como objetos, sino como objetos con operaciones pre-definidas que solo pueden ser realizadas en el objeto al cual están relacionadas y desde afuera el interior de un objeto se oculta solo es visible las operaciones que se pueden realizar sobre él.

Un sistema se considera **modular** si consiste de componentes discretos que pueden ser implementados de forma separada y un cambio en un componente tiene el mínimo impacto sobre el resto. La modularidad, ayuda al mantenimiento y al desarrollo del sistema.

Debe quedar claro que hacer un sistema modular no es simplemente dividirlo en módulos, sino que cada módulo necesita admitir una abstracción bien definida y tener una interfaz clara a través de la cual se pueda comunicar con otros módulos. En conclusión, la modularidad surge de la conjunción entre la abstracción y el particionado.

Un sistema consiste de componentes, que tienen sus propios componentes; es decir, un sistema es una jerarquía de componentes en donde, en el más alto nivel de esta jerarquía se encuentra el sistema completo. Para diseñar esta jerarquía hay dos posibles enfoques

  • **top-down****
    • Comienza desde el componente de más alto nivel de la jerarquía y procede hasta los niveles más bajos.
    • Empieza identificando los mayores componentes del sistema y los descompone en componentes de más bajo nivel, continuando de forma iterativa hasta lograr el nivel de detalle deseado.
    • Se aplica un ****refinamiento gradual****.
    • Es adecuado solo si las especificaciones del sistema se conocen claramente y el desarrollo del sistema es desde cero.
    • Enfoque más natural para manipular problemas complejos.
    • La factibilidad es desconocida hasta el final.
  • **bottom-up**
    • Comienza con los componentes de los niveles más bajos de la jerarquía y procede progresivamente hasta los componentes de los niveles más altos.
    • Empieza diseñando los componentes más básicos o primitivos y luego sigue con los que usan esos componentes de bajo nivel.
    • Es más adecuado para sistemas que se construyen a partir de un sistema que ya existe.

<aside>
💡 En general se usa una combinación de ambos.

</aside>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

¿Qué es el acoplamiento dentro del diseño orientado a funciones? ¿Y la cohesión? (Describa al menos 4 de los 7 niveles de cohesión en el orden correcto)

A

Objetivo: tener módulos tan débilmente acoplados como sea posible.

Dos ****módulos son independientes**** si cada uno puede funcionar completamente sin la presencia del otro. Si dos módulos son independientes entonces:

  • Los módulos se pueden modificar separadamente.
  • Se pueden implementar y testear independientemente.
  • Reduce el costo de programación.

<aside>
⚠️ Todos los módulos dentro de un sistema no pueden ser completamente independientes uno del otro, dado a que deben interactuar para producir el comportamiento esperado del sistema.

</aside>

Mientras más conexiones entre módulos más dependencia existe entre ellos, dado a que se necesita saber más sobre uno de los módulos para comprender o solucionar el otro.

El **********acoplamiento entre módulos********** es un concepto ******inter-modular****** que mide la fuerza de las interconexiones entre los módulos o la independencia de los mismos. Como los módulos son creados durante el diseño del sistema, el acoplamiento entre módulos se define a nivel de diseño arquitectónico y de alto nivel, por lo que **********no puede ser reducido durante la implementación************.

  • Tipo de conexiones entre módulos
  • Complejidad de las interfaces
    • Una interfaz es usada para pasar información desde o hacía otros módulos.
  • Tipo de flujo de información entre módulos
    • Dos tipos de información
      • Control: las acciones de los módulos dependen de la información.
      • Dato: los módulos pueden ser simplemente como funciones de entrada / salida.

El acoplamiento incrementa con la complejidad y la obscuridad de las interfaces entre módulos. Entonces, para mantener el acoplamiento bajo se deben minimizar el número de interfaces de por módulo y la complejidad de cada una. El acoplamiento se reduce si otros módulos solo utilizan la interfaz de entrada definida de un módulo (pej. usando exclusivamente parámetros para pasarle información a un módulo). En cambio, el acoplamiento aumentará si usamos interfaces indirectas o oscuras como usar directamente las partes internas de un módulo o usar variables compartidas.

La complejidad de cada interfaz también afecta al acoplamiento, por ejemplo, la complejidad de la interfaz de entrada de un procedimiento depende del número de elementos que se pasan como parámetros y de la complejidad de los elementos. Cierto nivel de complejidad es necesario para la comunicación entre módulos, pero a menudo se usa más que eso pasando registros completos en vez de pasar solamente los campos necesarios. Por eso, debemos ************mantener las interfaces de los módulos lo más simple y pequeñas posible************.

El ************tipo de información que fluye entre las interfaces************ también afecta al acoplamiento. Recibir información de control significa que la acción que realice el módulo depende de esa información de control, lo que hace que sea más difícil entender el módulo y proporcionarle abstracción. En cambio, la transferencia de información de datos significa que un módulo pasa como entrada algunos datos a otro módulo y obtiene a cambio algunos datos como salida, lo que permite que un módulo sea tratado como una simple función de entrada-salida que transforma datos. En general, interfaces que solo pasan datos resulta en un menor acoplamiento, seguido de las interfaces que solo pasan datos de control, sin embargo el acoplamiento se considera más alto si los datos que se pasan son híbridos.

Objetivo: tener módulos tan débilmente acoplados como sea posible.

Dos ****módulos son independientes**** si cada uno puede funcionar completamente sin la presencia del otro. Si dos módulos son independientes entonces:

  • Los módulos se pueden modificar separadamente.
  • Se pueden implementar y testear independientemente.
  • Reduce el costo de programación.

<aside>
⚠️ Todos los módulos dentro de un sistema no pueden ser completamente independientes uno del otro, dado a que deben interactuar para producir el comportamiento esperado del sistema.

</aside>

Mientras más conexiones entre módulos más dependencia existe entre ellos, dado a que se necesita saber más sobre uno de los módulos para comprender o solucionar el otro.

El **********acoplamiento entre módulos********** es un concepto ******inter-modular****** que mide la fuerza de las interconexiones entre los módulos o la independencia de los mismos. Como los módulos son creados durante el diseño del sistema, el acoplamiento entre módulos se define a nivel de diseño arquitectónico y de alto nivel, por lo que **********no puede ser reducido durante la implementación************.

  • Tipo de conexiones entre módulos
  • Complejidad de las interfaces
    • Una interfaz es usada para pasar información desde o hacía otros módulos.
  • Tipo de flujo de información entre módulos
    • Dos tipos de información
      • Control: las acciones de los módulos dependen de la información.
      • Dato: los módulos pueden ser simplemente como funciones de entrada / salida.

El acoplamiento incrementa con la complejidad y la obscuridad de las interfaces entre módulos. Entonces, para mantener el acoplamiento bajo se deben minimizar el número de interfaces de por módulo y la complejidad de cada una. El acoplamiento se reduce si otros módulos solo utilizan la interfaz de entrada definida de un módulo (pej. usando exclusivamente parámetros para pasarle información a un módulo). En cambio, el acoplamiento aumentará si usamos interfaces indirectas o oscuras como usar directamente las partes internas de un módulo o usar variables compartidas.

La complejidad de cada interfaz también afecta al acoplamiento, por ejemplo, la complejidad de la interfaz de entrada de un procedimiento depende del número de elementos que se pasan como parámetros y de la complejidad de los elementos. Cierto nivel de complejidad es necesario para la comunicación entre módulos, pero a menudo se usa más que eso pasando registros completos en vez de pasar solamente los campos necesarios. Por eso, debemos ************mantener las interfaces de los módulos lo más simple y pequeñas posible************.

El ************tipo de información que fluye entre las interfaces************ también afecta al acoplamiento. Recibir información de control significa que la acción que realice el módulo depende de esa información de control, lo que hace que sea más difícil entender el módulo y proporcionarle abstracción. En cambio, la transferencia de información de datos significa que un módulo pasa como entrada algunos datos a otro módulo y obtiene a cambio algunos datos como salida, lo que permite que un módulo sea tratado como una simple función de entrada-salida que transforma datos. En general, interfaces que solo pasan datos resulta en un menor acoplamiento, seguido de las interfaces que solo pasan datos de control, sin embargo el acoplamiento se considera más alto si los datos que se pasan son híbridos.

Como mencionamos el acoplamiento caracteriza el vínculo inter-modular por lo que, se redice minimizando las relaciones entre los elementos de los distintos módulos o maximizando las relaciones entre los elementos del mismo módulo.

La cohesión de un módulo, caracteriza el vínculo **intra-modular**, es decir, representa cuan fuertemente vinculados están los elementos de un módulo.

Objetivo: **alta** cohesión.

Dentro del diseño orientado a función existen varios niveles de cohesión

  1. Casual
    • La relación entre los elementos del módulo no tienen significado.
    • Ejemplos: el programa es “modularizado” cortándolo en pedazos o se crea un módulo simplemente para evitar código repetido.
  2. Lógica
    • Existe alguna relación lógica entre los elementos del módulo, es decir, los elementos realizan funciones dentro de la misma clase lógica.
  3. Temporal
    • Parecida a la cohesión lógica pero los elementos están relacionados en el tiempo y se ejecutan juntos.
    • Ejemplos: inicialización, finalización.
  4. Procedural
    • Contiene elementos que pertenecen a una misma unidad procedural.
    • Ejemplo: un ciclo o secuencia de decisiones.
  5. Comunicacional
    • Tiene elementos que están relacionados por una referencia al mismo dato.
    • Ejemplo: pedir los datos de una cuenta personal y devolver todos los datos del registro.
  6. Secuencial
    • Los elementos están juntos porque la salida de uno, corresponde a la entrada del otro.
    • Es una cohesión buena, relativamente fácil de mantener, pero difícil de rehusar.
    • Ejemplo: quiero pintar un fiat 600 de verde: (1) limpiar la chapa, (2) reparar defector, (3) lijar, (4) pintar.
  7. Funcional
    • Es el más fuerte de todas las cohesiones.
    • Todos los elementos del módulo están relacionados para llevar a cabo una sola función.

<aside>
💡 La **cohesión** y el **acoplamiento** están correlacionados. Usualmente, a mayor cohesión, menor acoplamiento.

</aside>

¿Cómo puedo determinar la cohesión de un módulo?

  1. Describir el propósito del módulo en una oración.
  2. Realizar el siguiente test
    • Si la oración es compuesta, tiene comas o más de un verbo.
      • El módulo probablemente está realizando más de una función.
      • Probablemente tenga cohesión secuencial o comunicacional.
    • Si la oración contiene palabras relacionadas con el tiempo
      • Probablemente el módulo probablemente tenga cohesión secuencial o temporal.
    • SI el predicado no contiene un único objeto específico, a continuación del verbo.
      • El módulo probablemente tenga cohesión lógica.
    • Palabras como inicializar y limpiar implican cohesión temporal.

Como mencionamos el acoplamiento caracteriza el vínculo inter-modular por lo que, se redice minimizando las relaciones entre los elementos de los distintos módulos o maximizando las relaciones entre los elementos del mismo módulo.

La cohesión de un módulo, caracteriza el vínculo **intra-modular**, es decir, representa cuan fuertemente vinculados están los elementos de un módulo.

Objetivo: **alta** cohesión.

Dentro del diseño orientado a función existen varios niveles de cohesión

  1. Casual
    • La relación entre los elementos del módulo no tienen significado.
    • Ejemplos: el programa es “modularizado” cortándolo en pedazos o se crea un módulo simplemente para evitar código repetido.
  2. Lógica
    • Existe alguna relación lógica entre los elementos del módulo, es decir, los elementos realizan funciones dentro de la misma clase lógica.
  3. Temporal
    • Parecida a la cohesión lógica pero los elementos están relacionados en el tiempo y se ejecutan juntos.
    • Ejemplos: inicialización, finalización.
  4. Procedural
    • Contiene elementos que pertenecen a una misma unidad procedural.
    • Ejemplo: un ciclo o secuencia de decisiones.
  5. Comunicacional
    • Tiene elementos que están relacionados por una referencia al mismo dato.
    • Ejemplo: pedir los datos de una cuenta personal y devolver todos los datos del registro.
  6. Secuencial
    • Los elementos están juntos porque la salida de uno, corresponde a la entrada del otro.
    • Es una cohesión buena, relativamente fácil de mantener, pero difícil de rehusar.
    • Ejemplo: quiero pintar un fiat 600 de verde: (1) limpiar la chapa, (2) reparar defector, (3) lijar, (4) pintar.
  7. Funcional
    • Es el más fuerte de todas las cohesiones.
    • Todos los elementos del módulo están relacionados para llevar a cabo una sola función.

<aside>
💡 La **cohesión** y el **acoplamiento** están correlacionados. Usualmente, a mayor cohesión, menor acoplamiento.

</aside>

¿Cómo puedo determinar la cohesión de un módulo?

  1. Describir el propósito del módulo en una oración.
  2. Realizar el siguiente test
    • Si la oración es compuesta, tiene comas o más de un verbo.
      • El módulo probablemente está realizando más de una función.
      • Probablemente tenga cohesión secuencial o comunicacional.
    • Si la oración contiene palabras relacionadas con el tiempo
      • Probablemente el módulo probablemente tenga cohesión secuencial o temporal.
    • SI el predicado no contiene un único objeto específico, a continuación del verbo.
      • El módulo probablemente tenga cohesión lógica.
    • Palabras como inicializar y limpiar implican cohesión temporal.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

¿Qué es un diagrama de estructura?

A
  • Presenta una notación gráfica para tal estructura.
  • Representa módulos y sus inter-conexiones.
  • La invocación de un módulo A a un módulo B se representa con una flecha.
  • Cada flecha se etiqueta con los items que pasan.

Tipos de módulos

Iteración y decisión

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

¿En qué consiste el diseño estructurado?

A

Objetivo: especificar módulos de funciones y sus conexione siguiendo una estructura jerárquica con bajo acoplamiento y alta cohesión.

Esta metodología de diseño estructurado ve al **software**** como una función de transformación que convierte una entrada dada en la salida esperada, para esto utiliza abstracción funcional y descomposición funcional.

Debemos pensar que los módulos con módulos subordinado no realizan mucha computación, la mayoría de la computación se realiza en los módulos subordinados y el módulo principal solo se encarga de la coordinación. Esta lógica se repite hasta hasta los módulos atómicos.

La factorización es el proceso de descomponer en un módulo de manera que el grueso de la computación se realice en los módulos subordinados. Por lo que, un sistema completamente factorizado realiza el procesamiento real en los módulos atómicos de nivel más bajo.

<aside>
💡 El SDM apunta a acercarse a una factorización completa.

</aside>

Pasos principales de esta metodología

  1. Reformular el problema como con DFD.
    • El diseño estructurado comienza con un DFD que capture el flujo de datos del sistema propuesto.
    • Este DFD debe ver el problema a muy alto nivel.
    • Enfatiza el flujo de datos a través del sistema.
    • Ignora aspectos procedurales.
    • Identificar las entradas, salidas, fuentes y sumideros del sistema y trabajar consistentemente desde la entrada haca la salida o al revés.
    • Identificar los transformadores que convierten las entradas en salidas.
  2. Identificar las entradas y salidas más abstractas.
    • Generalmente los sistemas realizan una función básica, pero usualmente no se realiza sobre la entrada directamente, es necesario primero transformar la entrada en un formato adecuado.
    • De manera similar, las salidas producidas por los transformadores principales también deben deben ser transformadas a las salidas físicas adecuadas.
    • Entonces, se requieren de varios transformadores para procesar las entradas y las salidas.
    • El objetivo de este paso es separar tales transformadores de los que realizan transformaciones reales.
    • A partir de lo anterior, se define las MAI (entradas más abstractas) y la MAO (salidas más abstractas)
      • MAI: elementos de datos en el DFD que están más distantes de la entrada real, pero que aún puede considerarse como una entrada.
        • Para ******encontrarlas****** se debe ir desde la entrada física en dirección a la salida hasta que los datos no pueden considerarse como entrantes.
      • MAO
        • Para ******encontrarlas****** se debe ir desde la salida física en dirección de la entrada hasta que los datos no puedan considerarse como salientes.
    • Las burbujas presentes entre MAI y MAO corresponden con los transformadores centrales, que son aquellos que realizan la transformación básica.
    • Este enfoque separa las distintas funciones que son: sub-sistema que realiza principalmente la entrada, sub-sistema que realiza principalmente las transformaciones y sub-sistema que realiza principalmente la presentación de la salida.
  3. Realizar el primer nivel de factorización.
    • Es el primer paso para obtener el diagrama de la estructura.
    • Especificar el módulo principal.
    • Especificar un módulo de entrada subordinado por cada ítem de dato de MAI cuyo propósito será enviarle al módulo principal los ítem de datos de la MAI.
    • Especificar un módulo de salida subordinado por cada ítem de dato de la MAO, igual que para la MAI.
    • Especificar un módulo transformador subordinado por cada transformador central.
    • Las entradas y salidas de estos módulos transformadores están especificadas en el DFD.
    • El primer nivel de factorización es sencillo
      • Él módulo principal es un modulo coordinador.
      • Algunos módulos subordinados son responsables de entregar las entradas lógicas que se pasan a los módulos transformadores para obtener las salidas lógicas, luego esas salidas son consumidas por los módulos de salida.
    • Eso divide el problema en ********tres problemas claramente separados********: el problema de las MAI, el problema de la MAO y el problema principal.
    • Estos tres módulos son independientes.
  4. Factorizar los módulos de entrada, de salida, y transformadores.
    • El transformador que produce el dato de MAI se trata ahora como un transformador central y se repite el proceso del primer nivel de factorización considerando al módulo de entrada como si fuera el módulo principal.
    • De nuevo, se crea un módulo subordinado por cada ítem de dato que llega a este nuevo transformador central y se crea un módulo subordinado para el nuevo transformador central.
    • Luego, los nuevos módulos de entrada se factorizan de la misma manera hasta llegar a la entrada física.
    • La factorización de la salida es simétrica.
    • Para factorizar los módulos transformadores no existen reglas, se usa el proceso de refinamiento top-down, teniendo como objetivo determinar los sub-transformadores que compuestos conforman el transformador y repetir el proceso para los nuevos transformadores encontrados. Y repetir hasta alcanzar módulos atómicos que idealmente serían los que realmente deberían trabajar.
  5. Mejorar la estructura (heurísticas, análisis de transacciones).
    • Los pasos anteriores no deben seguirse ciegamente.
    • La estructura obtenida podría modificarse si fuera necesario teniendo como objetivo siempre lograr bajo acoplamiento y alta cohesión.
    • Se utilizan heurísticas de diseño para modificar el diseño inicial.
      • Las heurísticas de diseño son un conjunto de “rules of thumb” que generalmente son útiles.
        • Tamaño del módulo: es un indicador de la complejidad que tiene un módulo.
          • Se deben examinar cuidadosamente aquellos módulos con muy pocas líneas o con más de 100 líneas.
        • Cantidad de flechas de entrada y la cantidad de flechas de salida
          • Las flechas de salida no deben exceder las 5 o 6 flechas.
          • Mientras que las flechas de llegada deberían maximizarse.
        • Alcance de efecto de un módulo
          • Los módulos afectados por una decisión en este módulo.
        • Alcance de control de un módulo
          • Todos los subordinados.
        • **Regla:** el alcance del efecto debe ser un subconjunto del de control.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

¿Cuales son algunas de las métricas usadas en el análisis orientado a funciones?

A

El tamaño del sistema siempre es una métrica, luego del diseño esta métrica puede ser ****estimada****** de una mejor manera. Por ejemplo usando

$$
\text{tamaño} = \text{cantidad de módulos} + \text{tamaño estimado de cada uno}
$$

Se enfoca en la ****estructura del diagrama de estructuras****; se considera un buen diagrama a aquel en el cual cada módulo tiene un sólo módulo invocador. Cuanto el diagrama más se desvíe de la forma de un árbol, más impuro es

$$
\text{impureza del grafo} = n-e-1
$$

donde $n$ son los nodos del grafo y $e$ son las aristas del grafo.

<aside>
💡 A medida que este valor se hace ****************más negativo****************, se **************************incrementa************************** la impureza.

</aside>

La estabilidad trata de capturar el impacto de los cambios en el diseño.

Objetivo: tener la **mayor estabilidad** posible.

La estabilidad de un módulo está dado por la cantidad de suposiciones por otros módulos sobre este, depende de la interfaz del módulo y del uso de datos globales.

Las métricas del flujo de información tienen en cuenta:

  • La complejidad de intra-módulo, que se estima con el tamaño del módulo LOC.
  • La complejidad inter-módulo que se estima con
    • **inflow.** flujo de información entrante del módulo.
    • **outflow:**** flujo de información saliente del módulo.

Entonces, la complejidad inter-módulo de un módulo C es}

$$
DC=\text{tamaño} * (\text{inflow}*\text{outflow})^2
$$

Dónde el producto de **inflow** por **outflow**** representa el total de combinaciones de entradas y salidas, el hecho de elevarlo al cuadrado es para representar la importancia de la inter-conexión entre los módulos con respecto a la complejidad interna.

<aside>
💡 La métrica anterior define la complejidad sólo en la cantidad de información que fluye hacia adentro y hacia afuera teniendo en cuenta también el tamaño de un módulo.

</aside>

Dado a la observación anterior y que en la métrica de red también es importante la cantidad de módulos desde y hacia donde fluye la info. Se considera el impacto del tamaño del módulo cada vez más insignificante. En base a esto, la complejidad del diseño del módulo C se puede definir como

$$
DC=\text{fan}_{\text{in}}\text{fan}_{\text{out}}+\text{inflow}\text{outflow}
$$

donde $\text{fan}{\text{in}}$ representa la cantidad de módulos qie llaman al módulo $C$ y $\text{fan}{\text{out}}$ a los llamados por $C$.

Para utilizar esta métrica se usa el promedio de la complejidad de los módulos y su desviación estándar para identificar los módulos complejos y los propenso a error. Decimos que

  • Un módulo es ******propenso a error si********
    • $DC>\text{complejidad}{\text{media}}+\text{desv}{\text{std}}$
  • Un módulo se considera ****complejo si******
    • $\text{complejidad}{media}<DC<\text{complejidad}{media}+\text{desv}_{std}$
  • Normal en caso contrario.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

¿Qué es la herencia y el polimorfismo en la Orientación a Objetos?

A

La ****herencia**** es una relación entre clases que nos permite definir e implementar una clase basada en las definiciones de las clases existentes. Es decir, cuando una clase $Y$ hereda de una clase $X$, $Y$ toma implícitamente todos los atributos y operaciones de $X$, luego $X$ se denomina ******superclase****** o ******clase base**** e $Y$ se denomina ****subclase**** o ******clase derivada******. En general, la subclase $Y$ debe tener dos partes: una ****parte derivada** (la parte heredada) y una **parte incremental**** (nuevo código definido en $Y$).

<aside>
💡 La relación de herencia crea otra relación “es-un” en donde un objeto de la clase derivada $Y$, es un objeto de la clase $X$ también.

</aside>

Una ****herencia**** puede ser de dos tipos

  • ****Herencia estricta:**** una subclase toma todas las características de su super-clase y añade características adicionales para especializarla.
  • Herencia no estricta: la **subclase** no tiene todas las características de la ****super-clase** o alguna de las características heredadas fue definida nuevamente.

Además, a las relaciones de herencia que poseen dos o más **super-clases** y una **subclase** se la denomina ********herencia múltiple******** de lo contrario se la considera una ******herencia simple******.

La relación de herencia entre clases forma una ****jerarquía**** entre clases que tiene un aspecto similar al siguiente

A si mismo, la relación de herencia induce el ******polimorfismo****** que le da a los objetos la capacidad de ser de diferentes tipos (o mejor dicho, clases) esto se da a la relación “es-un” que mencionamos anteriormente, dado a que un objeto que forma parte de una sub-clase, pertenece a esa **subclase** y a la ****superclase**** de la cual esta hereda.

Aparte, con el polimorfismo presente una entidad tiene un tipo estático y un tipo dinámico, donde el estático es aquel tipo que se le declara en el texto del programa y permanece sin cambiarse, el dinámico por otro lado puede cambiarse de vez en cuando y solo se conoce en el tiempo de referencia (pej. cuando un objeto tiene es de la clase $Y$, pero llama a un método de la clase $X$ entonces el tipo dinámico de ese objeto, es ese momento, es $X$). Este tipo de polimorfismo requiere de ****vinculación dinámica****, que permite que el código asociado a una llamada a procedimiento no es conocida hasta el momento de la llamada.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

¿A qué nos referimos con acoplamiento, cohesión y el principio de abierto - cerrado en el diseño orientado a objetos?

A

Objetivo: bajo acoplamiento

El ******acoplamiento****** es un concepto ******inter-modular******** que captura la fuerza de las interconexiones entre módulos. Mientras más fuertemente relacionados estén dos módulos, más dependiente es uno del otro y esto hace que sea más difícil entenderlos y modificarlos.

El grado de acoplamiento entre un módulo y otro depende de cuanta información es necesaria acerca del otro módulo para entender y modificar este módulo, y de cuan compleja o explícita sea esa información. El ********bajo acoplamiento******** sucede cuando la información es la más pequeña, simple y fácil de ver o identificar como sea posible.

Aunque el concepto entre diseño orientado a objetos y diseño orientado a funciones de acoplamiento sea al mismo, como se manifiesta en los sistemas orientados a objetos es diferente. En los sistemas orientados a objetos, hay tres tipos de acoplamiento

Acoplamiento por interacción

El ******acoplamiento por interacción******** sucede cuando una clase invoca a los métodos de otra clase.

******Alto acoplamiento si******

  • Los métodos acceden a partes internas de otros métodos.
  • Los métodos manipulan directamente variables de otras clases.
  • La información se pasa a través de variables temporales.

Bajo acoplamiento si

  • Los métodos se comunican directamente mediante parámetros con el menor número de parámetros posible y la menor cantidad de información posible (sólo información de datos).

Acoplamiento de componentes

El acoplamiento de componentes sucede cuando una clase $A$ tiene atributos de otra clase $C$, lo cual puede suceder en tres situaciones

  1. Si $A$ tiene variables de instancia del tipo $C$
  2. Si $A$ tiene parámetros de tipo $C$
  3. Si $A$ tiene un método con variables locales del tipo $C$.

Bajo acoplamiento si

  • En una clase $C$, las variables de clase $C$ en $A$ son, o bien atributos, o bien parámetros de un método.

<aside>
💡 Si $A$ está acoplado a una clase $C$, también está acoplado con todas sus sub-clases.

</aside>

Acoplamiento de herencia

En el ****acoplamiento de herencia**** decimos que dos clases están acopladas si una es sub-clase de la otra.

********Alto acoplamiento si********

  • La sub-clases modifican la signatura de un métodos de o eliminan un método.
  • La sub-clase conserva la signatura pero modifica el método.

********Bajo acoplamiento si********

  • La sub-clase solo agrega variables de instancia y métodos pero no modifica las existentes en la superclase.

Objetivo: alta cohesión.

La cohesión es un concepto **intra-modular** que se enfoca en cuán fuertemente relacionados están los elementos de un módulo. Que los elementos estén fuertemente relacionados hace que el módulo sea más fácil de entender y como capturan conceptos y abstracciones claras, son más fáciles de modificar.

En el diseño orientado a objetos existen tres tipos de cohesión

Cohesión de método

Se enfoca en por qué los elementos de un método están juntos en el mismo método.

******Alta cohesión si******

  • Cada método implementa una función claramente definida con todas las sentencias en el método contribuyendo a implementar esa función.

<aside>
💡 Puede servir como medida que en caso de tener un método con tales características entonces se debería poder definir en una oración lo que el método realiza.

</aside>

Cohesión de clase

Se enfoca en el por que los diferentes atributos y métodos están en la misma clase. Una clase debería representar un único concepto con todos sus elementos contribuyendo a este concepto.

******Baja cohesión si******

  • Una clase encapsula múltiples conceptos.

Un ejemplo de esto es cuando los métodos de una clase pueden separarse en diferentes grupos, donde cada grupo accede a distintos sub-conjuntos de atributos.

Cohesión de la herencia

Se enfoca en por que las clases están juntas en la misma jerarquía. En general, hay **********dos razones para definir********** sub-clases

  1. ******generalización - especialización.******
  2. re-uso.

Alta cohesión si

  • Si la jerarquía se produce como consecuencia de la generalización - especialización.

Las entidades de **software**** deben ser abiertas para extenderlas pero cerradas para modificarlas.

Lo que significa que el comportamiento debe poder ser extendido para acomodarlo a las nuevas demandas pero el código existente no debería modificarse, de modo que se minimiza el riesgo de romper la funcionalidad existente al añadir nuevos cambios, ahorrándonos tiempo en el re-testeo de esas funcionalidades también.

En los DOO este principio es satisfecho usando apropiadamente la herencia y el polimorfismo, dado a que la herencia nos da la posibilidad de crear nuevas clases extendiendo el comportamiento de las clases existentes sin cambiar la clase original.

Principio de Liskov

Un programa que utiliza un objeto $O$ con clase $C$ debería permanecer inalterado si $O$ se reemplaza por cualquier objeto de una subclase de $C$.

<aside>
💡 Si las jerarquías de un programa respetan este principio, entonces también respetan el principio de abierto - cerrado.

</aside>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

¿En que consiste la metodología de diseño OMT? ¿Para que sirve? describa sus 5 pasos.

A

El punto de partida del diseño orientado a objetos es el modelo obtenido durante el análisis orientado a objetos, en base a este se construye un modelo detallado del sistema final. Entonce, la metodología OMT para producir un DOO consiste se los siguientes pasos

  1. Producir el diagrama de clase.
    • Normalmente es realizado durante la fase de requerimientos.
    • Explica que pasa en el sistema.
  2. Producir el modelo dinámico y usarlo para definir operaciones en las clases.
    • Describe la interacción entre los objetos.
    • Explica cuando pasa.
  3. Producir el modelo funcional y usarlo para definir operaciones en las clases.
    • Describe la transformación de los datos.
    • Explica que pasa.
  4. Definir las clases y operaciones internas.
  5. Optimizar y empaquetar.

El diagrama de clase nos presenta una estructura estática del sistema, sin embargo esta no es suficiente para diseñar el sistema dado a que también nos interesa captar los efectos deseados de los eventos en el estado del sistema. Es por eso que se desarrolla un modelo dinámico del sistema, el cual se enfoca en especificar como el estado de varios objetos cambia con la ocurrencia de un evento determinado.

Un evento desde el punto de vista de un objeto es esencialmente una solicitud de operación. Una secuencia de eventos que ocurre en una ejecución particular del sistema conforma lo que llamamos un ****escenario****, los escenarios nos permiten identificar los diferentes eventos que realizan los objetos.

<aside>
💡 Todos los escenarios juntos pueden **caracterizar el comportamiento** de un sistema.

</aside>

Para realizar el modelo dinámico, primero debemos modelar los escenarios exitosos y luego los escenarios excepcionales, los distintos escenarios juntos nos permiten caracterizar el comportamiento completo del sistema. Luego, para cada escenario se deben identificar los eventos de los distintos objetos, que será información que usaremos para expandir el diagrama de clases. En general, para cada evento en el diagrama de secuencia habrá una operación en el objeto sobre el cual el evento es invocado.

En conclusión, un diagrama de secuencia nos permite refinar nuestra visión de un objeto y agregar las operaciones necesarias que pueden no haber sido identificadas previamente.

El ****modelo funcional**** describe los cómputos que tienen lugar en el sistema, especificando como los valores que entran en el sistema se transforman en las salidas esperadas sin tener en cuenta aspectos de control. Para realizar este tipo de modelados se utiliza el ya visto diagrama de flujo de datos (o DFD).

Sin embargo, como los procesos representan operaciones y en los sistemas orientados a objetos, la mayor parte del procesamiento se realiza mediante operaciones en clases, todos los procesos deben aparecer como operaciones entre clases. Por lo que, los transformadores del DFD representan esas operaciones y dependiendo el nivel de abstracción del DFD pueden aparecer como una sola operación o como múltiples operaciones en distintas clases.

Las clases que tenemos hasta ahora provienen del dominio del problema y los métodos son los necesarios para satisfacer todas las interacciones con el entorno o el usuario y soportar la funcionalidad deseada. Sin embargo, el diseño final debe ser un plano para la implementación del sistema, por lo que debemos considerar también cuestiones de implementación durante el diseño incluyendo optimización y algoritmos.

Primero, cada clase es críticamente evaluada para ver si es necesaria en su forma actual dentro del sistema (algunas clases pueden ser descartadas). Luego, se considera las implementaciones de las operaciones de cada clase, en algunos casos puede que se necesiten operaciones de más bajo nivel sobre clases auxiliares más simples y a estas clases se las denomina ********clases contenedoras********.

En esta metodología de diseño, la estructura básica proviene desde el análisis del problema donde el foco no está en la eficiencia. En este último paso, la eficiencia es considerada y algunas de las cuestiones que se desarrollan pueden ser

Añadir asociaciones redundantes

Las asociaciones dentro del diseño inicial pueden llegar a ser muy ineficientes para llevar a cabo algunas operaciones. En algunos casos, esas operaciones pueden ser hechas de forma más eficiente añadiendo algunas asociaciones.

Guardar atributos derivados

Cuando un atributo derivado es usado con mucha frecuencia o su cálculo es complejo, su valor se puede calcular y almacenar una vez para luego acceder a él más tarde. Para esto, es esencial mantener la consistencia entre el atributo derivado y el atributo base.

Uso de tipos genéricos

Permite la re-usabilidad del código, lo que reduce el tamaño del código.

Ajustar la herencia

A veces, la misma operación o una similar está definida en varias clases. Pero si modificamos la operación y la hacemos un más general (extendiendo su funcionalidad o su interfaz) podemos convertirla en una operación la cual podemos “subir” en la jerarquía de clases. Además, haciendo uso de las propiedades de la herencia podríamos “subir” la operación a una clase base y luego refinar la operación con funcionalidades específicas en las clases con lógica diferente.

Otra forma, es ver si es posible definir una clase abstracta sobre las clases existentes en la jerarquía de clases y luego considerar a algunas clases existentes como subclases de esta.

<aside>
💡 Además de estos aspectos, se deben aplicar los principios generales (acoplamiento, cohesión, y abierto-cerrado) con el fin de mejorar la calidad del diseño.

</aside>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly