Sintesis

¿Por qué?

  • Inefectividad, ineficacia y/o ineficiencia, del Proyecto Software

    • porque tiene malas variables en su economía:

      • ámbito incumplido y/o

      • tiempo incumplido y/o

      • coste incumplido;

    • porque tiene mala calidad del software, fiabilidad, usabilidad, interoperatividad, seguirdad, …​ (-ilities)

    • porque tiene mala mantenibilidad

      • viscoso, porque no se puede entender con facilidad y/o

      • rígido, porque no se puede cambiar con facilidad y/o

      • frágil, porque no se puede probar con facilidad y/o

      • inmovil, porque no se puede reutilizar con facilidad y/o

    • porque tiene complejidad arbitraria

davidProyectoImplantacionDiseñoMal

arbolNoMantenible

Diseño inspirado en el modelo del dominio no asegura un código calidad
  • Hay situaciones en las que una solución sugerida por el patrón Experto en la Información es indeseable, por lo general a causa de problemas en el acoplamiento y cohesión.

    • Estos problemas indican violación de un principio básico de diseño: separación de asuntos propios de sistemas complejos. El apoyo a una separación de las principales asuntos mejora de acoplamiento y la cohesión en un diseño.

    • Por tanto, el Modelo del Dominio con Expertos en la Información es una inspiránción en el vocabulario del mundo real para orientar al software pero éste nunca debe verse como que imita ni simula ni emula el mundo real. Es solo fuente de inspiracion para el software hasta que haya problemas en el software.

  • [red]_Por ejemplo: una aplicación de gestión educativa con la clase Alumno, que tenga interfaz de texto y gráfica, persistencia en base de datos, comunicaciones, …​ propone

    • la clase Alumno (experto en la información)

    • acoplado a tecnologías de interfaz, persistencia y comunicaciones,

    • con la responsabilidad del CRUD de los datos del alumno (alta, baja, modificación y consulta de las notas, datos personales, …​) y

    • mostrarse, persistir y comunicarse porque tiene la información para mostrarse, persistir y comunicarse!

    • Por tanto, muy acoplada a muchas clases, poco cohesiva con muchas responsabilidades y, por tanto, muy grande_

malDiseño
Viscoso Rigido Inmovil Frágil

Presencia de multitud de clases enormes con métodos enormes con acoplamientos cíclicos sin un nítido reparto de responsabiliades

Responsabilidades repartidas por multitud de clases que requieren modificaciónes si cambian los requisitos correspondientes.

Presencia de multitud de clases acopladas a multitud de clases de diversas tecnologías (GUI, comunicaciones, bases de datos, servicios, …​)

Ausencia de red de seguridad de pruebas unitarias por imposibilidad de realizar pruebas sobre las clases anteriores

¿Qué?

Diseño modular
  • Larry Constantine define la métrica de cohesión en la década de 1960

  • Parnas en Sobre los criterios que se utilizarán en la descomposición de sistemas en módulos en 1972

  • Larry Constantine, Ed Yourdon y Wayne Stevens publican Diseño Estructurado en 1974

  • Ed Yourdon y Larry Constantine publican Diseño Estructurado en 1979

  • incorpora tres criterios que debe cumplir todo módulo (método, clase y/o paquete):

    • Alta cohesión

    • Bajo Acoplamiento

    • Tamaños pequeños

malModular

buenModular

Cohesión

Definición Contraejemplo
La cohesión, o más específicamente, la cohesión funcional, es una medida de cómo de fuerte están relacionadas y enfocadas las responsabilidades que son de un elemento. Estos elementos incluyen sistemas, paquetes, clases y métodos.
— Larman
UML y Patrones

Si una persona no integra a sus colaboradores (partes, agregados, asociados y/o usos) consume su canal cognitivo, capacidad cuantitativa mental, al responsabilizarse de diversos asuntos, no de uno único

Alta cohesión Baja cohesión
  • Responsabilidades muy relacionadas y que no hace una enorme cantidad de trabajo

    • Asignanado una única responsabilidad para que la cohesión sigue siendo alta delegando a otros otras responsabilidades

    • Una clase con alta cohesión tiene un número relativamente pequeño de métodos, con una funcionalidad muy relacionadas, y no hace demasiado trabajo. Colabora con otros objetos para compartir el esfuerzo si la tarea es grande

  • Responsabilidades poco relacionadas y/o que sí hace una enorme cantidad de trabajo

    • Asignando un "grano muy grande" de abstracción o han asumido responsabilidades que deberían haber sido delegadas a otros

    • Cohesión moderada, una clase tiene responsabilidades ligeras y únicas en unas pocas áreas diferentes que están lógicamente relacionadas con el concepto de la clase, pero no entre sí.

  • Calidad del Software:

    • Fluidez porque es fácil de comprender

    • Flexible porque es fácil de modificar

    • Reusable porque es fácil de reutilizar

    • Robusta porque no está constantemente afectada por el cambio

  • Calidad del Software:

    • Viscosidad porque es difícil de comprender

    • Rígidez porque es difícil de modificar

    • Inmovilidad porque es difícil de reutilizar

    • Frágilidad porque está constantemente afectada por el cambio

Compromisos. Pocos casos en los que se justifica la aceptación de una cohesión menor:
  • Clases de Utilidad: agrupación de responsabilidades o código en una clase o componente para simplificar el mantenimiento de una persona aunque se advierte que tal agrupación también puede hacer el mantenimiento peor.

  • Servidores distribuidos: debido a las implicaciones generales y de rendimiento asociados con objetos remotos y la comunicación a distancia, a veces es deseable crear menos y más grandes objetos servidores, menos cohesivos que proporcionan una interfaz para muchas operaciones.

  • la clase System en Java.

  • la fachada de un servicio REST complejo.

La cohesión es un objetivo fundamental para considerar en todas las decisiones de diseño
— Larman
UML y Patrones
  • Se realiza a través de la capacidad cualitativa de modularizar los sistemas

  • Asume la separación de asuntos de los sistemas complejos

Acoplamiento

Definición Contraejemplo

El acoplamiento es una medida de la fuerza con un elemento está conectado a, tiene conocimiento de, o se basa en otros elementos. Estos elementos incluyen sistemas, paquetes, clases y métodos.

Si una persona interactúa con demasiadas clases de colaboradores (partes, agregados, asociados y/o usos) colapsa al superar su canal cognitivo, capacidad cuantitativa mental

Bajo acoplamiento Alto acoplamiento
  • No es dependiente de muchos elementos

  • Sí es dependiente de muchos elementos

  • Asignación de una responsabilidad de forma que su colocación no aumente el acoplamiento a un nivel tal que conduce a los resultados negativos que el alto acoplamiento puede producir.

  • Asignación de una responsabilidad de forma que su colocación sí aumente el acoplamiento a un nivel tal que conduce a los resultados negativos que el alto acoplamiento puede producir.

  • Calidad del Software:

    • Fluidez porque es fácil de comprender

    • Flexible porque es fácil de modificar

    • Reusable porque es fácil de reutilizar

    • Robusta porque no está constantemente afectada por el cambio

  • Calidad del Software:

    • Viscosidad porque es difícil de comprender

    • Rígidez porque es difícil de modificar

    • Inmovilidad porque es difícil de reutilizar

    • Frágilidad porque está constantemente afectada por el cambio

Acoplamiento directo Acoplamiento indirecto
  • de un Tipo X a un Tipo Y incluyen:

    • Tipo X tiene un atributo que hace referencia a una instancia Tipo Y.

    • Tipo X tiene un método que hace referencia a una instancia de Tipo Y, por cualquier medio. Estos suelen incluir un parámetro o variable local de tipo Tipo Y, o el objeto de retorno de un mensaje es una instancia de Tipo Y.

    • Un objeto Tipo X pide a los servicios (método estáticos) de un objeto Tipo Y.

    • Tipo X es una clase derivada de Tipo Y.

      • Existe una tensión entre los conceptos de acoplamiento y herencia: las clases débilmente acopladas son deseables; y la herencia, la cual acopla parejas de superclases y sus subclases, nos ayuda a explotar el factor común entre las abstracciones.

  • de un Tipo X a un Tipo Z será cuando el primero envía mensajes a objetos de Tipo Z que devuelvan los objetos de Tipo Y por un acoplamiento directo

import p.Y;

class X {
  private Y y;
  public void m(){
    y.getZ().m();
  }
}

class Y {
  public Z getZ(){
    ...
  }
}
Grafo de acoplamientos
  • Acoplamiento aferente de una clase es el conjunto de clases que dependen de dicha clase, reusabilidad de la clase

acoplamientoAyEferente
  • Acoplamiento eferente de una clase es el conjunto de clases de las que depende de dicha clase

Alto Acoplamiento Grado moderado de acoplamiento Bajo acoplamiento
  • con elementos estables y generalizados rara vez es un problema. El alto acoplamiento per se no es el problema

    • Por ejemplo, una aplicación Java J2EE de forma segura se puede acoplar a las bibliotecas de Java (java.util, y así sucesivamente), porque son estables y generalizadas

  • es el acoplamiento a elementos que son inestables en alguna dimensión, como su interfaz, su implementación, o su mera presencia.

  • es normal y necesario para la creación de un sistema orientado a objetos en el que las tareas se cumplen por una colaboración entre los objetos conectados

    • Métrica: 7+-2 clases como máximo

  • especialmente en las clases que son inherentemente de naturaleza muy genéricas, y con una alta probabilidad para su reutilización.

  • Se puede añadir flexibilidad, encapsular datos e implementaciones y diseñar en general con bajo acoplamiento en muchas áreas del sistema. Pero si ponemos esfuerzos en “posibles futuros" o bajando el acoplamiento en algún punto en el que, de hecho, no hay motivación realista, esto no será un tiempo bien empleado.

  • Los diseñadores tienen que elegir sus batallas en la reducción de acoplamiento y centrarse en los puntos de alta inestabilidad o evolución realista.

El acoplamiento es un objetivo fundamental para considerar en todas las decisiones de diseño
— Larman
UML y Patrones
  • Se realiza a través de la capacidad cualitativa de jerarquizar los sistemas

  • Asume la jerarquía de los sistemas complejos

Interrelación Causa Consecuencia
  • Bajo Acoplamiento y Alta cohesión se retroalimentan en un círculo virtuoso

    • El nivel de acoplamiento por sí solo no puede considerarse en forma aislada de otros principios como el Experto y Alta Cohesión, un compromiso.

  • Reduciendo el acoplamiento, responsabilizando a otros elementos,

  • habitualmente aumenta la cohesión

  • Aumentanto la cohesión, asumiendo menos responsabilidades,

  • habitualmente reduce el acoplamiento

Tamaño

Elemento Cota Cantidad Elemento

Paquete

Máximo

[12 .. 20]

Clases

Clase

Media

3

Atributos

Máximo

5

Atributos

Máximo

[20 .. 25]

Métodos

Máximo

[200 .. 500]

Líneas

Método

Media

1,2

Parámetros

Máximo

[2 .. 3]

Parámetros

Máximo

[10 .. 15-25]

Líneas de Código

Máximo

3

Sentencias anidadas

Máximo

[10 .. 15]

Complejidad Ciclomática de McCabe, número de diferentes posibles caminos en tiempo de ejecución

Línea

Máximo

80 | 120

Caracteres

¿Para qué?

  • Efectividad, eficacia y eficiencia, del Proyecto Software

    • porque tiene buenas variables en su economía:

      • ámbito cumplido y

      • tiempo cumplido y

      • coste cumplido;

    • porque tiene buena calidad del software, fiabilidad, usabilidad, interoperatividad, seguirdad, …​ (-ilities)

    • porque tiene buena mantenibilidad

      • fluido, porque se puede entender con facilidad y/o

      • flexible, porque se puede cambiar con facilidad y/o

      • fuerte, porque se puede probar con facilidad y/o

      • reusable, porque se puede reutilizar con facilidad y/o

    • porque tiene complejidad inherente

davidProyectoImplantacionDiseño

arbolMantenible

Fluido Flexible Resuable Robusto

Presencia de multitud de clases pequeñas con métodos pequeños con pequeños acoplamientos acíclicos que puedo recorrer de arriba abajo (top/down o bottom/up), jerarquía de composición y/o clasificación de clases pequeñas, sin ciclos!

Reparto de responsabilidades equilibrado y centralizado en clases que requiere modificarse únicamente si cambian los requisitos correspondientes, jerarquías de clases con alta cohesión, sin ciclos!

Presencia de multitud de clases pequeñas, cohesivas y poco acopladas a tecnologías, algoritmos, …​!

Presencia de red de seguridad de pruebas unitarias por posibilidad de realizar pruebas sobre las clases anteriores …​ jerarquía equilibrada de clases pequeñas con alta cohesión y bajo acoplamiento!

  • Es difícil hacer cualquier mosaico con fichas grandes de varios colores (baja cohesión) y con formas irregulares (alto acoplamiento)

  • Es fácil hacer cualquier mosaico con fichas pequeñas de un solo color (alta cohesión) y con formas cuadradas (bajo acoplamiento)

height32

¿Cómo?

Índice
  • Modularidad

    • Número de Módulos

    • Distribución de Responsabilidad

  • Jerarquización

  • Abstracción de la Interfaz

  • Diseño por Contrato

  • Encapsulación de la Implantación

    • Cohesión

    • Acoplamiento

    • Granularidad

  • Patrón de Indirección

    • Patrón de Invención Pura

    • Patrón Vista Separada

    • Patrón Controlador

    • Patrón Creador

Modularidad

Número de módulos

  • Costes de la modularización, es un compromiso, un equilibrio, entre:

    • el coste de desarrollo de cada módulo, pocos muy grandes es más costoso que muchos muy pequeños

    • el coste de integración de todos los módulos, muy pocos cuesta poco y muchos cuesta mucho

compromisos

  • Se parte un problema para ser efectivos, eficaces y eficientes, resolviendo problemas más pequeños pero cuando el problema requiere partirse y no más!

Aplicación mediana (100.000 LOC) Muchos módulos Número equilibrado de módulos Pocos módulos

Costes de Desarrollo

Reducido

Equilibrado

Disparado

Costes de Integración

Disparado

Equilibrado

Reducido

Costes Totales

Disparado

Equilibrado

Disparado

Distribución de Responsabilidades

  • Distribución de Responsabilidades, también de forma equilibrada, con una media y una desviación típica reducidas de la carga relativa de la responsabilidad total

    • Hay que partir el problema, no trasladarlo!

repartoResponsabilidades

Jerarquización

- Diseño descendente (top/down) - Diseño ascendente (bottom/up)
hood
  • Se comienza con las clases básicas (hojas en las jerarquías) adivinando la responsabilidad necesaria para las superiores

  • Se continúa con clases intermedias (basadas en las hojas de las jerarquías) adivinando la responsabilidad necesaria para las superiores

  • Se repite el paso segundo hasta llegar a la clase principal del sistema, sin superiores.

  • En cualquier caso, en cada momento estás centrado en una clase, en un nivel de la jerarquía, sin ciclos, con un número limitado de elementos colaboradores

Comparativa Diseño descendente Diseño ascendente

Reparto de responsabilidades

Muy sencillo bajo demanda de clases anteriores pero cualquier error de diseño implica revisar las clases anteriores de la jerarquía de dependencias

Muy complejo adivinando la responsabilidad, requiere mucha experiencia en desarrollo del software y en el dominio de la aplicación

Pruebas

Imposible realizar pruebas unitarias hasta llegar a la implantación de las clases hoja de las jerarquías a no ser que se desarrollen "sustitutos" (mocks) para todas las clases en cada prueba

Se pueden realizar pruebas unitarias/familiares desde la primera clase

Interfaz

Código Sucio por Clases Alternativas con Interfaces Diferentes

Sinónimos Synonyms Libro Autor

Clases Alternativas con Diferentes interfaces

Alternative Classes with Different Interfaces

Smell Code (Refactoring)

Martin Fowler

Justificación

Solución

  • Complejidad innecesaria

  • Renombra los métodos que hacenlo mismo pero tienen nombre diferentes sin la oportuna sobrecarga.

  • Mueve los métodos a clases padre o como poco a la interfaz

  • Mueve responsabilidades de las clases hasta que los métodos hacen lo mismo y tienen el mismo nombre: homogenizar el código

Principios del Menor Compromiso y la Menor Sorpresa

Antónimos Antonyms Libro Autor

Comportamiento obvio no está implementado

Obvious Behavior Is Unimplemented

Smell Code (Clean Code)

Robert Martin

Responsabilidad fuera de lugar

Misplaced Responsibility

Smell Code (Clean Code)

Robert Martin

Principio del menor compromiso, a través del cual la interfaz de un objeto proporciona su comportamiento esencial, y nada más
— Abelsony Sussman
Principio de la menor sorpresa, a través del cual una abstracción captura todo el comportamiento de un objeto, ni más ni menos, y no ofrece sorpresas o efectos secundarios que van más allá del ámbito de la abstracción
— Booch

Interfaz Suficiente, Completa y Primitiva

Sinónimos Synonyms Libro Autor

Los nombresde las funciones deberían decirlo que hacen

Function Names Should Say What They Do

Smell Code (Clean Code)

Robert Martin

Suficiente Completa Primitiva
  • la clase o módulo captura suficientes características de la abstracción para permitir una interacción significativa y eficiente. De otra manera el componente será inútil.

    • En la práctica, violaciones de esta característica se detectan muy temprano; tales deficiencias se levantan casi cada vez que construimos un cliente que debe utilizar esta abstracción.

  • la interfaz de la clase o módulo de captura todas las características significativas de la abstracción. Considerando que la suficiencia implica una interfaz mínima, una interfaz completa es una que cubre todos los aspectos de la abstracción. Una clase o módulo completo es, pues, una cuya interfaz es lo suficientemente general como para ser comúnmente utilizable para cualquier cliente.

    • La completitud es una cuestión subjetiva, y puede ser exagerada. Proporcionar todas las operaciones significativas para una abstracción particular, abruma al usuario y en general es innecesaria, ya que muchas operaciones de alto nivel pueden estar compuestas por las de bajo nivel.

  • Una operación es indiscutiblemente primitiva si podemos implementarla sólo a través del acceso a la representación subyacente.

    • Una operación que podría implementarse sobre las operaciones primitivas existentes, pero a costa de muchos más recursos computacionales, es también un candidato para su inclusión como una operación primitiva.

  • Una clase conjunto de elementos, si ofrece eliminar un elemento deberá contemplar añadir un elemento

  • La clase cadena de caracteres contempla todas y cada una de las operaciones previsibles: esPalíndromo, esEmail, invertir, rimas, …​

  • En la clase conjunto de elementos, añadir un elemento es una operación primitiva pero añadir 4 elementos para un cliente particular no sería una operación primitiva porque podría apoyarse eficientemente en la anterior.

Diseño por Contrato

Principio Error lógico Error excepcional
  • Un software fiable debe diseñar cada componente de un sistema de modo que se proteja a sí mismo tanto como sea posible

  • La corrección, la capacidad del software de ejecutar de acuerdo con sus especificaciones, de los posibles errores lógicos se cubre generalmente:

    • inadecuadamente con Programación defensiva y

    • adecuadamente con Aserciones

  • La robustez, la capacidad del software de reaccionar a casos no incluidos en la especificación, de los posibles errores excepcionales se cubre generalmente con excepciones.

    • abrir un fichero no existente o sobre un soporte dañado, envío y recepción de datos sin conexión en red o con la base de datos, uso inadecuado de una biblioteca, …

- Programación Defensiva - Aserciones
  • La solución es que cada componente (método) compruebe la viabilidad de operar con if-then-else. Pero:

    • No basta con informar por pantalla del error lógico porque no se puede acoplar dicho componente a la vista con tecnologías alternativas (consola, gráfica, móvil, web, …) y porque habrá que avisar al cliente para que tome las medidas oportunas ante el error

    • No basta con un código de error cuando no es posible acordar un valor particular de error (0 ó -1) si toda la gama es una posible solución

  • En caso optar por la Programción Defensiva tanto el componente como su cliente aumentarán innecesariamente su complejidad con sentencias if-then-else tanto para confirmar la viablidad del progreso del componente como para comprobar en todos y cada uno de los clientes la ausencia de error generada por el componente, lo cual además produce código duplicado.

  • Es una sentencia del lenguaje que permite comprobar las suposiciones del estado del programa en ejecución, involucrada en algunas entidades del software que establece una propiedad que estas entidades deben satisfacer en ciertos estados en la ejecución del programa

    • Cada aserción contiene una expresión lógica que se supone cierta cuando se ejecute la sentencia. En caso contrario, el sistema finaliza la ejecución del programa y avisa del error detectado

    • Estas aserciones se pueden usar:

      • En producción, para documentar formalmente (compilables) los límites del ámbito del componente sin efecto sobre la ejecución; o

      • En pre-producción, para compobraciones automáticas durante la ejecución y, en caso de error, elevar una excepción que termina la ejecución e informa claramente de lo que sucedió

Diseño por Contrato

Definición

Objetivos

Protocolo

  • Considerar las relaciones entre una clase y sus cientes como un contrato formal expresando los derechos y las obligaciones de cada parte.

    • La vista exterior de cada objeto define un contrato sobre aquellos objetos que pueden depender de él y

    • el cual a su vez debe llevar a cabo en la vista interna del propio objeto, a menudo colaborando con otros. Este contrato establece todas las asunciones que un objeto cliente puede hacer sobre el comportamiento de un objeto servidor.

  • Producir software correcto desde el principio porque es diseñado para ser correcto

  • Obtener mucha mejor compresión del problema y sus eventuales soluciones

  • Facilitar la tarea de documentación del software

  • Conjunto entero de operaciones que un cliente puede realizar sobre un objeto junto con las “consideraciones legales” en los que pueden ser invocadas.

    • Para cada operación asociada con un objeto, se pueden definir precondiciones y postcondiciones: {P} A {Q}, donde

      • A denota una operación;

      • P y Q son aserciones sobre las propiedades de varias entidades involucradas; P es llamada precondición y Q postcondición.

    • Cualquier ejecución de A, comienza en un estado que cumple P y terminará en un estadoque cumple Q

    • Si la precondición es violada, significa que un cliente no ha satisfecho su parte del contrato y el servidor no puede proceder con fiabilidad.

    • Si una postcondición es violada significa que un servidor no ha llevado a cabo suparte del contrato y sus cliente no pueden confiar en el comportamiento del servidor

    • La pareja precondición/postcondición de una rutina describen el contrato que la rutina, servidor de un cierto servicio, define para sus usuarios, clientes del servicio.

Precondiciones Postcondiciones
  • Atan al cliente con las restricciones sobre el estado de los parámetros y del objeto servidor que se deben cumplir para una llamada legítima a la operación y que funcione apropiadamente. Son una obligación para el cliente y un beneficio para el servidor.

    • Precondiciones fuertes exigen más al cliente para solicitar una tarea y facilitan el trabajo del servidor restringiendo las condiciones de partida

    • Precondiciones débiles exigen menos al cliente para solicitar una tarea pero complican el trabajo del servidor ante más amplitud en la condiciones de partida

  • Atan al servidor con las restricciones sobre el estado del valor devuelto y del objeto servidor que se deben cumplir tras el retorno de la operación para que el cliente progrese adecuadamente. Son una obligación para el servidor y un beneficio para el cliente:

    • Postcondiciones fuertes exigen más al servidor que debe de cumplir dicha condición y facilitan al cliente con un resultado más restringido

    • Postcondiciones débiles exigen menos al servidor que debe de cumplir dicha condición y complican al cliente con un resultado más abierto

Obligacion Beneficiario

Cliente

Satisfacer las precondiciones

No necesita comprobar valores de salida porque el resultado garantiza el cumplimiento de la postcondicion

Servidor

Satisfacer las postcondiciones

No necesita comprobar los valores de entrada porque la entrada garantiza el cumplimiento de la precondicion

Invariante de Clase Clase correcta
  • Es una aserción expresada como una restricción general de la consistencia a aplicar a cada objeto de la clase como un todo.

    • Es diferencte de las precondiciones y postcondiciones caracterizadas a rutinas individuales sobre sus parámetros de entrada y sus resultados respectivamente junto con el estado del objeto. La invariante solo involucra el estado del objeto.

    • Añadir Invariantes de Clase fortalece o mantiene como poco las precondiciones y postcondiciones

    • Facilita el trabajo del componente porque además de la precondición, se puede asumir que el estado inicial del objeto cumple la invariante, lo que restringe el conjunto de casos que se deben contemplar

    • Complica el trabajo del componente porque además de la postcondición, se debe cumplir que el estado final del objeto cumpla la invariante, lo que puede aumentar las acciones a realizar

  • Cada constructor de la clase, cuando se aplica satisfaciendo su precondición en un estado donde los atributos tienen sus valores por defecto, cuando termina satisface la invariante

    • {P} constructor {Q and I}

  • Cada operación de la clase, cuando se aplica satisfaciendo su precondición y su invariante, cuando termina satisface su postcondición y su invariante

    • {P and I} operación {Q and I}

Implemetación

Cohesión

Índice
  • Cohesión de Métodos

  • Principio de Única Responsabilidad

  • responsabilidad fuera de lugar

  • Código Sucio por Envidia de Características

  • Código Sucio por Clase de Datos

  • Código Sucio por Cambios Divergentes

  • sin clase para una responsabilidad

  • Código Sucio por Cirugía a Escopetazos

  • Código Sucio por Grupo de Datos

  • Código Sucio por Obsesión por Tipos Primitivos

  • clase sin responsabilidad

  • Código Sucio por Clases Perezosas

Cohesión de Métodos

Sinónimos Synonyms Libro Autor

La funciones deberían hacer una sola cosa

Functions Should Do One Thing

Smell Code (Refactoring)

Martin Fowler

Violaciones

Solución

Justificación

  • A menudo se intenta crear funciones que tienen multiples secciones que realizan una serie de operaciones.

  • La relacion entre las líneas de la implantación del método no son cohesivas porque persiguen distintos objetivos

    • Método que calcula la longitud de un Interval y muestra el resultado por pantalla. Cuando solo se necesitael cálculo, no es reutilizable, por el acomplamiento a la interfaz

  • Deberían ser convertidas varias funciones pequeñas que hacen una sola cosa

  • Evitar un acoplamiento temporal, lo que posibilita su reusabilidad por partes separadas

Principio de Única Responsabilidad

Cohesión

Principio de Única Responsabilidad

  • Definido por Robert Martin (Single Responsibility Principle -SRP) como uno de los principios SOLID

  • Está inspirado en los trabajos de De Marco y Page-Jones, denominado como cohesion: relación funcional de los elementos de un modulo. Pero desplaza un poco el significado y relaciona la cohesion con la causa de cambio de un modulo.

    • Define responsabilidad como una razón de cambio: si se puede pensar en más de un motivo de cambio para una clase, entonces la clase tiene más de una responsabilidad.

  • Una clase debería tener un único motivo de cambio

    • Es uno de los principios más sencillos y uno de los más difíciles de aplicar correctamente. Combinar responsabilidades es algo que hacemos de forma natural. Encontrar y separar esas responsabilidades entre sí es realmente mucho de lo que el diseño de software es en sí mismo.

    • Un eje de cambio es solo un eje de cambio si el cambio ocurre actualmente. No es prudente aplicar el SRP, o cualquier otro principio para el caso, si no hay ningún síntoma: YAGNI

Vilolaciones Solución
  • Si una clase tiene más de una responsabilidad entonces pueden llegar a acoplarse.

  • Los cambios de una responsabilidad pueden perjudicar o inhibir la capacidad de otras clases afectando a su funcionalidad

  • Esta clase de acoplamientos produce diseños frágiles que se rompen de forma inesperada.

  • Partir la funcionalidad en dos clases.

    • Cada clase maneja un única responsabilidad y en el futuro, si se necesita realizar algún cambio se realizará separadamente en la clase que lo maneje.

  • si una clase Board_es responsable de las fichas de los jugadores y ademásde presentarse por consola, cuando se cambie a un entorno gráfico puede afectar a la clase que crea el tablero porque tiene que suministrarlos aspectos gráficos necesarios para su nueva presentación

  • Si una entidad del dominio (Student, …) se autoguarda en la base de datos puede repercutir al cambiar las tecnologías de la capa de persistencia en aquellas clases que manejan la entidad

  • Separarla clase Board responsable de la gestión de las fichas de los jugadores de la clase BoardView responsable de su visualización colaborando con la clase anterior para obtener la información a presentar. Los cambios en las tecnologías de visualización afectarán únicamente a las clases de presentación

  • Separa la clase de entidad del dominio de las clases dedicadas a la grabación y recuperación de dicha entidad(patron DAO)

Código Sucio por Envidia de Características

Sinónimos Synonyms Libro Autor

Características de la envidia

Features Envy

Smell Code (Refactoring)

Martin Fowler

Violaciones Solución
  • Un mal olor clásico es un método que parece más interesado en una clase distinta de la que realmente es. El enfoque más común de la envidia son los datos. Multitud de veces se ve un método que invoca media docena de métodos para conseguir calcular un valor de otro objeto.

  • La clave de los objetos es una técnica para empaquetar datos con los procesos utilizados en esos datos.

  • El método claramente quiere estar en otro lugar. A veces sólo una parte del método adolece de envidia; en ese caso, extraer el método ponerlo en la clase adecuada.

  • Si se extrae información de objetos de varias clases combinadamente, colocar el método en la clase que más atributos aporta para el cálculo

Código Sucio por Clase de Datos

Sinónimos Synonyms Libro Autor

Clase de datos

Data Class

Smell Code (Refactoring)

Martin Fowler

Justificación Violaciones Solución
  • Las clases necesitan tomar alguna responsabilidad

  • Hay clases que tienen atributos, métodos get/set y nada más. Estas clases son soportes de datos tontos y es casi seguro que se manipulan con demasiado detalle por otras clases.

  • Buscar dónde se llaman los métodos get/set que son usados por otras clases. Intentar mover el comportamiento dentro de la clase de datos.

  • Después eliminar los métodos _get/set_innecesarios

Código Sucio por Cambios Divergentes

Sinónimos Synonyms Libro Autor

Cambio divergente

Divergent Change

Smell Code (Refactoring)

Martin Fowler

Justificación Violaciones Solución
  • Estructuramos nuestro software para hacer el cambio más fácil. Después de todo, el software está destinado a ser blando. Cuando hacemos un cambio queremos la ventaja de ser capaces de saltar a un solo punto en el sistema y hacer el cambio.

  • Ocurre cuando una clase se cambia frecuentemente de diferentes maneras, por diferentes razones. Si nos fijamos en una clase y dice: "Bueno, voy a tener que cambiar estos tres métodos cada vez que tengo una nueva base de datos, tengo que cambiar estos cuatro métodos cada vez que hay un nuevo instrumento financiero, …"

  • Es probable que tenga una situación en la que varios objetos son mejor que uno. De esta manera cada objeto sólo se cambia como resultado de un tipo de cambio. Por supuesto, a menudo se descubre esto sólo después de añadir un par de bases de datos o instrumentos financieros.

Código Sucio por Cirurgía a Escopetazos

Sinónimos Synonyms Libro Autor

Cirugía de escopeta

Shotgun Surgery

Smell Code ((Refactoring)

Martin Fowler

Justificación Solución
  • Cuando cada vez que se hace una especie de cambio, lo que se tiene que hacer es un montón de pequeños cambios en un montón de clases diferentes. Cuando los cambios son por todos lados son difíciles de encontrar y es fácil pasar por alto un cambio importante.

    • Un cambio que altera muchas clases. Idealmente, existe una relación de uno a uno entre los cambios comunes y las clases.

  • En este caso, hay que mover las responsabilidades entre las clases para evitarlo. Si no hay una clase actual que parezca una buena candidata, cree una.

Código Sucio por Grupo de Datos

Sinónimos Synonyms Libro Autor

Grupos de datos

Data Clumps

Smell Code (Refactoring)

Martin Fowler

Violaciones Solución
  • Si se encuentran los mismos dos, tres o cuatro elementos de datos juntos en muchos lugares: atributos en un par de clases, los parámetros de muchas cabeceras de métodos.

  • Los grupos de datos que se presentan juntos realmente deben componer su propio objeto.

  • Ante la duda, una buena comprobación sería preguntarse si quitando uno del grupo, ¿los demás tendrían sentido? Si la respuesta es no, forman un grupo de datos

Código Sucio por Obsesión por Tipos Primitivos

Sinónimos Synonyms Libro Autor

Obsesión primitiva

Primitive Obssesion

Smell Code (Refactoring)

Martin Fowler

Violaciones Solución
  • Las nuevos programadores orientados a objetos, por lo general, son reacios a utilizar objetos pequeños para pequeñas tareas

    • la clase Dinero que combinan cantidad y moneda,

    • clase Intervalo con límite superior e inferior

    • clases especiales de cadenas de caracteres como números de teléfono y códigos postales

  • Puede reemplazar un valor de tipo primitivo por una clase en incorporar su responsabilidad

  • En el caso de que no exista dicha responsabilidad asignable, puede crear un enumerado

Código Sucio por Clases Perezosas

Sinónimos Synonyms Libro Autor

Lazy Class

Clase perezosa

Smell Code (Refactoring)

Martin Fowler

Justificación Violaciones Solución
  • Cada clase que se crea cuesta dinero para mantenerla y entenderla.

  • Una clase que no está haciendo lo suficiente para justificar el coste por sí mismo debería ser eliminada.

    • A menudo, esto podría ser una clase que paga por su bagaje y se ha reducido con la refactorización.

    • O podría ser una clase que fue [red]#añadida a causa de los cambios que estaban previstos, pero nunca llegaron.

  • De cualquier manera, dejar que la clase muera con dignidad asignando su escasa responsabilidad a otra clase

  • Si hay subclases que no están haciendo lo suficiente, trate de contraer la jerarquía.

Resumen

Índice
  • Cohesión de Métodos

  • Principio de Única Responsabilidad

  • responsabilidad fuera de lugar

  • Código Sucio por Envidia de Características

  • Código Sucio por Clase de Datos

  • Código Sucio por Cambios Divergentes

  • sin clase para una responsabilidad

  • Código Sucio por Cirugía a Escopetazos

  • Código Sucio por Obsesión por Tipos Primitivos

  • Código Sucio por Grupo de Datos

  • clase sin responsabilidad

  • Código Sucio por Clases Perezosas

Acoplamiento

Inapropiada Intimidad

Sinónimos Synonyms Libro Autor

Intimidad Inapropiada

Inappropriate Intimacy

Smell Code ((Refactoring)

Martin Fowler

Justificación Solución
  • Una relación bi-direccional complica el desarrollo, las pruebas, la legibilidad, …

  • La sobre-intimidad necesita ser rota:

    • Debes arreglar relaciones bidireccionales por unidireccionales. Mueve métodos y atributos para separar las piezas que reduzcan la intimidad

    • Si las clases tienen interes es encomún, extrae en una nueva clase poniendo lo común a salvo y haz que las demás sean honestas sobre ella.

    • La herencia a menudo puede conducir a la sobre-intimidad. Las subclases van a conocer más de sus padres de lo que a sus padres les gustaría que ellos conocieran. Se puede sustituir por Delegación

Algunas clases llegan a alcanzar demasiada intimidad y gastan mucho tiempo ahondando en las partes privadas de otras clases. Nosotros pensamos que nuestras clases deberían ser estrictas con reglas puritanas
— Fowler
Refactoring. 1999

Leyes de Demeter

Sinónimos

Synonyms

Libro

Autor

No hablescon extraños

Do not talk to strangers

xxx

Lieberherr

Cadena de Mensajes

Chain of Message

Smell Code (Refactoring)

Martin Fowler

Justificación Solución
  • Controlar el bajo acoplamiento restringieno a qué objetos enviar mensajes desde un método

  • Enviar únicamente a:

    • this

    • Parámetros

    • Atributos

    • Objetos locales

  • No enviar nunca a otros objetos indirectos obtenidos como resultado de un mensaje a un objeto de conocimiento directo.

Código Sucio por Librería Incompleta

Sinónimos Synonyms Libro Autor

Clase de biblioteca incompleta

Incomplete Library Class

Smell Code ((Refactoring)

Martin Fowler

Justificación Solución
  • Los desarrolladores de clases de biblioteca son raramente omniscientes. No los culpamos por eso, después de todo, rara vez podemos imaginar un diseño hasta que su mayoría ha sido construida, así que los desarrolladores de la biblioteca tienen un trabajo muy duro.

  • El problema es que a menudo es de mala educación, y por lo general imposible, modificar una clase de biblioteca para hacer algo que te gustaría que hiciera.

  • Crea una clase con los métodos extra adecuados a tus necesidades

Tamaño

Código Sucio por Listas de Parámetros Largas

Sinónimos Synonyms Libro Autor

Lista de Parámetros Larga

Long Parameter List

Smell Code (Refactoring)

Martin Fowler

Demasiados Argumentos

Too Many Arguments

Smell Code (Clean Code)

Robert Martin

Justificación Solución Violaciones
  • Son difíciles de entender

  • Son difíciles de probar todas la combinaciones de argumentos

  • Eliminar el parámetro cuando puedes obtenerlo a partir de algún objeto que ya conoces

  • Eliminar varios parámetros suministrando un objeto que los facilite

  • Crear un objeto que agrupe varios parámetros y asigna responsabilidad a sus clase

  • Funciones deberán tener un número pequeño de argumentos.

    • Sin argumentos es lo mejor,

    • seguido por uno, dos.

    • Tres debería evitarse y más de tres es muy cuestionable y debe considerarse como un prejuicio.

Código Sucio por Métodos Largos

Sinónimos Synonyms Libro Autor

Métodos largos

Long Method

Smell Code (Refactoring)

Martin Fowler

Justificación Solución Violaciones
  • Desde los principios de la programación, los programadores se han dado cuenta de que cuanto más largo es un procedimiento, más difícil es de entender.

    • Los viejos lenguajes conllevaban una sobrecarga en las llamadas a subrrutinas, de tal forma que se persuadía de escribir métodos pequeños.

    • Los nuevos programadores orientados a objetos a menudo sienten que la computación no se hace en ninguna parte, que los programas son secuencias sin fin de delegación. Cuando has vivido con un programa como tal por unos años, aprendes cómo de valorable son todos esos pequeños métodos. Todos los costes de indirección –explicación, compartición y selección– son respaldadas por pequeños métodos

  • El 99% de las veces, se tiene que acortar un método extrayendo otro.

    • Buscar una parte del método que parezca ir bien junta y hacerlo un nuevo método

  • Una buena técnica es mirar los comentarios o líneas en blanco para separar partes. Son señales de esta clase de distancia semántica. Un bloque de código con un comentario dice que debes reemplazar el bloque con un método cuyo nombre está basado en el comentario

Código Sucio por Clases Grandes

Sinónimos Synonyms Libro Autor

Objeto gigante

Big Large Object(BLOB)

Antipatrónde Desarrollo

William H.Brown et al

Large Class

Clase grande

Smell Code (Refactoring)

Martin Fowler

Demasiada información

Too much Information

Smell Code (Clean Code)

Robert Martin (Uncle Bob)

Justificación Violaciones Solución
  • Los archivos pequeños son generalmente más fáciles de entender que archivos de gran tamaño.

  • Cuando una clase está tratando de hacer demasiado, a menudo aparece con demasiadas variables de instancia.

    • En tal caso, el código duplicado no puede estar muy lejos.

  • Descomponer la clase otorgando grupos de atributos relacionados a otras clases

  • Si es una clase de interfaz separa los datos y cálculos del dominio en una clase de entidad

Código Sucio por Atributos Temporales

Sinónimos Synonyms Libro Autor

Campos temporales

Temporary Fields

Smell Code (Refactoring)

Martin Fowler

Justificación Violaciones Solución
  • A veces se ve un objeto en el que una variable de instancia se establece sólo en ciertas circunstancias. Tratar de entender por qué una variable está allí cuando no parece ser usada puede crear complejidad innecesaria.

    • Tal código es difícil de comprender porque tu esperas que un objetos necesite todas sus variables.

  • Un caso común de atributo temporal se produce cuando un algoritmo complicado necesita varias variables. Debido a que el ejecutor no quería pasar una lista de parámetros enorme, se ponen en atributos.

    • Pero los atributos son válidas sólo durante el algoritmo; en otros contextos son simplemente confusos.

  • En este caso, se puede extraer en una clase los atributos y los métodos que lo requieran.

    • El nuevo objeto es un objeto método [Beck]

Patrón de Indirección

Problema Solución
  • Desacoplar objetos para que se fomente el bajo acoplamiento y que el potencial de reutilización siga siendo el más elevado

  • Asignar la responsabilidad a un componente intermedio para mediar entre otros componentes o servicios para que no se acoplen directamente.

    • El intermediario crea una indirección entre los otros componentes.

La mayoría de los problemas en las Ciencias de la Computación pueden ser resueltos con otro nivel de indirección! La mayoría de los problemas de rendimiento pueden ser resueltos eliminando otro nivel de indirección
— Dennis DeBruler
Justificación Violaciones
  • Permitir compartir la lógica. Un sub-métodoinvocadoen dos lugares diferentes o un métodoen una clase base compartida por todos las derivadas

  • Explicar la intención e implementar separadamente. Elegir los nombres de cada clase y cada método da la oportunidadde explicar las intenciones. En el interior de una clase o método explican cómo las intenciones se realizan. Si el interior también se escribe en términos de intencion con piezas todavía más pequeñas, se puede escribir códigoque comunicala mayoríade la información importantesobre su estructura

  • Aislar cambios. Si se una un objeto en dos lugares, se quiere cambiar el comportamientoen unode ellos y cambiarel objeto produce cambios en los dos, se puede hacer una subclase y referirse a ella en el casodel cambio. Se puede modificarla clase sin arriesgarsea cambiar inadvertidamentea cambiar otros casos

  • Codificar la lógica condicional. Los objetos tienen un mecanismo fabuloso, paso de mensajes polimórficos, para, de forma flexible pero clara, expresar lógica condicional. Al cambiar explícitamente los condicionales por mensajes, se puede reducir la duplicación, añadir claridad e incrementar la flexibilidad al mismo tiempo

  • Si se encuentran métodos que se usaron para servir un propósito pero no llegó a llevarse a cabo;

  • si se encuentra un componente que se esperaba compartir o ser polimórfico pero sólo se usa en un sitio;

  • … cuando se encuentre indirecciones parasitarias, quítalas.

Patrón de Invención Pura

Problema Solución Ejemplos
  • Hay muchas situaciones en las que la asignación de responsabilidades solamente a las clases de software de la capa de dominio da lugar a problemas en cuanto a la escasa cohesión, elevado acoplamiento o de bajo potencial de reutilización

  • Asignar un conjunto altamente cohesivo de responsabilidades a una clase artificial o de conveniencia que no representa un concepto, algo dominio del problema, para apoyar alta cohesión, bajo acoplamiento, y reutilización

  • “cadena de caracteres poética” con responsabilidades sobre las rimas que no se desean asignar a la “cadena de caracteres” general;

  • “formateador de intervalos” para distintas presentaciones; …​

Patrón Vista Separada

Problema Solución Beneficios

¿Quién debe ser responsable de capturar entradas generado por un agente externo – personas mediante el teclado o el ratón - o máquinas mediante señales de un sensor o tramas de red-?

  • Asegurar que cualquier código que manipula la presentación, solo manipula la presentación despalazando toda la lógica del dominio y de datos en áreas separadas del programa.

    • Sub-patron del Principio de Única Responsabilidad, SRP de SOLID

  • El resultado de su aplicación serán Vistas que se responsabilizan de:

    • Gestionar sus controles de interfaz: botones, listas, … paneles, diálogos, ..

    • Gestionar su Estado: referido a los datos actuales mostrados en la interfaz

    • Gestionar su Lógica: para manipular los controles de interfaz

    • Gestionar su Sincronización: coordinando su estado con el estado de los objetos de datos y de negocio en memoria y/o persistencia

Aplicaciones

Patrón Controlador

Problema Solución Beneficios
  • ¿Quién debe ser responsable de manejar un evento de sistema de entrada generado por un agente externo – personas mediante el teclado o el ratón - o máquinas mediante señales de un sensor o tramas de red-?

  • Asignar la responsabilidad de recibir o manejar un mensaje de eventos del sistema a una clase que representa una de las siguientes opciones:

    • Representa el sistema, dispositivo o subsistema en general.

    • Representa un caso de uso dentro del cual se produce el evento del sistema, a menudo llamado <UseCaseName>Controller. Utilice la misma clase controlador para todos los eventos del sistema del mismo caso de uso.

      • Son objetos asociados con operaciones del sistema como mensajes, métodos.

      • Las clases de la interfaz no deberían contener tareas asociadas con los eventos, típicamente los reciben y delegan a un controlador

  • Un controlador no es un objeto de interfaz de usuario responsable de recibir o manejar un evento del sistema. Un controlador define el método para la operación del sistema asociada al evento.

    • Tenga en cuenta que clases “Window", "Widget "," View" y “Document" no están en esta lista: estas clases no deben cumplir con las tareas asociadas a los eventos del sistema, suelen recibir estos eventos y delegarlos a un controlador.

  • Normalmente, un controlador debe delegar a otros objetos el trabajo que hay que hacer; coordina o controla la actividad. No hace mucho el trabajo en sí.

mvc
mvcJerarquico
Aplicaciones

Patrón Creador

Problema Solución Beneficios
  • ¿Quién debería ser el responsable de crear un nueva instancia de alguna clase?

    • La creación de objetos es una de las actividades más comunes en un sistema orientado a objetos. Consecuentenemente, es útil tener un principio general para asignar la responsabilidad de creación.

  • A menudo, la creación requiere una complejidad significativa, como reciclar instancias por razones de rendimiento, creación condicional de una instancia de una familia de clases similares basándose en el valor de alguna propiedad externa, etc.

  • La clase B es un creador de objetos de la clase A, si uno o más de las siguientes condiciones es cierta:

    • B contiene/agrega objetos de A

    • B registra instancias de objetos de A

    • B usa estrechamente objetos de A

    • B tiene los datos de inicialización a ser pasados cuando es creado A

    • entonces B es un experto en la creación de A

  • Bajo acoplamiento implica dependencias de mantenimiento más bajos y mayores oportunidades para la reutilización.

    • El acoplamiento probablemente no se incrementa porque la clase creada es probable que ya sea visible a la clase Creador, debido a las asociaciones existentes que motivaron su elección como Creador

Resumen

Índice
  • Modularidad

    • Número de Módulos

    • Distribución de Responsabilidad

  • Jerarquización

  • Abstracción de la Interfaz

  • Diseño por Contrato

  • Encapsulación de la Implantación

    • Cohesión

    • Acoplamiento

    • Granularidad

  • Patrón de Indirección

    • Patrón de Invención Pura

    • Patrón Vista Separada

    • Patrón Controlador

    • Patrón Creador

Sintesis

Sintesis

Bibliografía

Obra, Autor y Edición Portada Obra, Autor y Edición Portada
  • The Unified Modeling Language User Guide

    • Booch, Jacobson, Rumbaugh

    • Pearson Education, 2005

height32

  • UML Distilled. A Brief Guide to the Standard Object Modeling Language

    • Fowler, Scott

    • Addison-Wesley, 2003

height32

  • Object Oriented Analysis and Design with Applications

    • Grady Booch

    • Addison-Wesley; (2011)

height32

  • Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development

    • Larman Craig

    • Prentice Hall; (2004)

height32

  • Object-Oriented Software Construction

    • Bertrand Meyer

    • Prentice Hall; (1997)

height32

  • Eiffel : The Language (PRENTICE HALL OBJECT-ORIENTED SERIES)

    • Bertrand Meyer

    • Prentice Hall; (1991)

height32

  • Code Complete

    • Steve McConnell

    • Microsoft Press; (2004)

height32

  • Clean Code. A Handbook of Agile Software Craftsmanship

    • Robert C. Martin

    • Prentice Hall; (2008)

height32

  • An Introduction to Object-Oriented Programming

    • Timothy A. Budd

    • Addison-Wesley; (2001)

height32

  • Agile Software Development, Principles, Patterns and Practices

    • Robert-C Martin

    • Pearson; (2006)

height32

  • The Mythical Man Month. Essays on Software Engineering

    • Frederick P. Brooks

    • Prentice Hall; (1995)

height32

  • Object Solutions. Managing the Object Oriented Project

    • Grady Booch

    • Addison-Wesley; (1789)

height32

  • Refactoring. Improving the Design of Existing Code

    • Martin Fowler,Kent Beck,John Brant,William Opdyke,Don Roberts

    • Addison Wesley; (1999)

height32

  • Extreme Programming Explained. Embrace Change. Embracing Change

    • Kent Beck,Cynthia Andres

    • Addison-Wesley; (2004)

height32

  • C++ Programming Language

    • Stroustrup Bjarne

    • Addison Wesley; (2013)

height32

  • The Clean Coder: A Code of Conduct for Professional Programmers

    • Robert C. Martin

    • Addison-Wesley; (2011)

height32

  • Desarrollo ágil esencial: Vuelta a las raíces

    • Robert C. Martin

    • Anaya; (2020)

height32

Ponente

  • Luis Fernández Muñoz

setillo

  • Doctor en Inteligencia Artificial por la UPM

  • Ingeniero en Informática por la UMA

  • Diplomado en Informática por la UPM

  • Profesor Titular de ETSISI de la UPM