Patrones de GRASP

5
102565

Patrones de GRASP

Un proceso de desarrollo sirve para normalizar quien hace que cosa en cada
momento y como debe realizarse esta cosa.

En el mundo de las nuevas tecnologías todo avanza muy deprisa por lo que es
probable que todavía no hallamos alcanzado un grado de madurez lo
suficientemente elevado como para poder normalizar actividades, fundamentalmente
porque éstas cambian de semana en semana.

Normalizando un proceso de desarrollo de software, lo que queremos ganar
(porque cuando hacemos algo normalmente es por ganar algo) pueden ser distintas
cosas:

  • Capacidad de predecir el coste futuro de la ejecución del siguiente
    proyecto
  • Evitar riesgos con tareas no planificadas.
  • Eliminar dependencias a personas por producir piezas de un modo
    estandarizado y documentado.
  • Aumentar la confianza en los sistemas desarrollados y reducir sus errores.
  • Favorecer la reutilización de piezas (con la consiguiente reducción de
    costes)
  • y muchas cosas más …. 

Uno de los procesos más reconocidos, es el denominado Proceso Unificado
de  Jacobson, Booch y Rumbaugh.

Este proceso se dice que es «dirigido por casos de uso, centrado en
la arquitectura, iterativo e incremental
«. Si recurrimos al libro (ISBN
0-201-57169-2, El proceso unificado de desarrollo de software
), me
parece francamente bueno pero ….. siempre hay un pero ….. para realizar
correctamente la ejecución de un proyecto, es necesario complementarlo con
otras fuentes. Si esta centrado en la arquitectura, esta debe ser lo más
robusta posible por lo que debemos profundizar en este punto.

Existe otro libro, llamado UML y Patrones (Craig Larman,
ISBN-84-205-3438-2
) que nos puede ayudar
en la primera fase del diseño, la identificación de las clases en base a su
responsabilidad). Es una obra muy buena pero puede ser un poco densa para
usuarios principiantes ….. aunque la primera mitad no tiene desperdicio.

Para comprender bien el libro anterior y que nuestros diseños sean completos, nos hacen falta unos cuantos libros
más sobre patrones de diseño (Coad, GoF, etc.) que, por suerte, podemos hasta encontrar,
de algunos de ellos, su versión electrónica en
Internet  (Thinking
in Patterns, Design
Patterns, Core J2EE
patterns) y, aunque profundizaremos en otros tutoriales en el uso de estos
patrones, comprobareis que no pueden vivir unos sin los otros …. e incluso, en
algunos casos se pueden decir que son los mismos …… descritos en otro ámbito.

Un patrón es una descripción de un problema bien conocido que suele
incluir:

  • Descripción
  • Escenario de Uso 
  • Solución concreta
  • La consecuencias de utilizar este patrón
  • Ejemplos de implementación
  • Lista de patrones relacionados 

Patrones hay muchos (muchas familias) … de momento vamos a ver como nos pueden ayudar los primeros (GRASP).

GRASP es el acrónimo de General Responsibility Assignment
Software Patterns. Una de las cosas más
complicadas en Orientación a Objeto consiste en elegir las clases adecuadas y
decidir como estas clases deben interactuar. Incluso cuando utilizamos
metodologías rápidas como programación extrema (extreme programming) y centramos
el proceso en el desarrollo continuo, es inevitable elegir cuidadosamente las
responsabilidades de cada clase en la primera codificación y, fundamentalmente,
en la refactorización (continual) de nuestro programa.

En su obra, Larman intenta definir un enfoque sistemático a la creación de
clases y métodos.

Para obtener más
información sobre el primer autor que ha documentado los patrones de GRASP (y
entrar en depresión por la cantidad de cosas que nos queda a todos por aprender) poder
visitar su Web (Craig Larman)
.

Lo patrones de GRASP, no compiten con los patrones de diseño….. los
patrones de GRASP, nos guían para ayudarnos a encontrar los patrones de
diseño (que son más concretos)…..

Vamos a ver el catálogo de patrones y algunas recomendaciones (como muchas
son de mi cosecha, podéis
escribirme para aportar críticas constructivas
):

Patrón Descripción

Bajo Acoplamiento

Debe haber pocas dependencias entre las clases. Si todas las clases
dependen de todas ¿cuanto software podemos extraer de un modo
independiente y reutilizarlo en otro proyecto?.

Para determinar el nivel de acoplamiento de clases, son muy buenos
los diagramas de colaboración de UML.

————–

Uno de los principales síntomas de
un mal diseño y alto acoplamiento es una herencia muy profunda.
Siempre hay que considerar las ventajas de la delegación respecto de
la herencia.

Como ejemplo (de mal diseño), en muchos diseños Web se
puede ver como se crea un servlet base con capacidades de paginación y
se hereda de él para construir los demás. La paginación es un servicio
que se podría usar en aplicaciones no Web, por lo que es más adecuado
mantener estas capacidades en clases externas.

Otro ejemplo clásico
se produce cuando se pasan los objetos relacionados con la capa de
presentación a la capa de negocio (HttpRequest, HttpResponse).

Alta Cohesión

Cada elemento de nuestro diseño debe realizar una labor única dentro
del sistema, no desempeñada por el resto de los elementos y
auto-identificable.

—————

Ejemplos de una baja cohesión son clases que hacen demasiadas
cosas.

En todas las metodologías se considera la refactorización. Uno de
los elemento a refactorizar son las clases saturadas de métodos.

Ejemplos de buen diseño se producen cuando se crean los denominados
«paquetes de servicio» o clases agrupadas por funcionalidades que son
fácilmente reutilizables (bién por uso directo o por herencia).

—————-

En java, pensar en interfaces nos fuerza a que nuestros sistemas
sigan los principios de alta cohesión. En algún sitio leí que
una aplicación con menos de 8 interfaces no utiliza correctamente los
conceptos de orientación a objeto … y estoy de acuerdo ….

Experto

La responsabilidad de realizar una labor es de la clase que tiene
o puede tener los datos involucrados (atributos) . Una clase, contiene toda la información necesaria
para realizar la labor que tiene encomendada.

————

Hay que tener en cuenta que esto es aplicable mientras
estemos considerando los mismos aspectos del sistema:

  • Lógica de negocio
  • Persistencia a la base de datos
  • Interfaz de usuario

No tiene sentido considerar que una clase se debe escribir a si
misma en base de datos o formatearse para presentarse en una página
HTML por el hecho de poseer los datos. Estos son elementos
estructuralmente distintos y deben considerarse desde una perspectiva
distinta.

Creador

Se asigna la responsabilidad de que una clase B
cree un Objeto de la clase A solamente cuando

  1. B contiene a A
  2. B es una agregación (o composición) de  A
  3. B almacena a A
  4. B tiene los datos de inicialización de A (datos que requiere su
    constructor)
  5. B usa a A.

————–

El hecho de crear objetos tiene casuísticas particulares:

  • Pool de Objetos
  • Caches
  • Instancias únicas

Estos casos son candidatos para la utilización de otros patrones
más concretos (de diseño).

————

A la hora de crear objetos en distintos lenguajes hay
que tener en cuenta sus peculiaridades. En Java por ejemplo:

  • No confundir referencias y el valor referenciado a
    la hora de retornar objetos desde métodos.

  • Conocer la peculiaridad de las String (cadenas
    constantes)

  • Identificar problemáticas del recolector de basura y
    el uso de recursos del sistema

  • Conocer el ámbito y naturaleza de distintos tipos de componentes

    • En servlets y JSPs pueden descargarse y estar
      activos en más de una máquina virtual.

    • Los servlets y JSPs son multi-thread a priory.

    • Los tags son reciclados en JSP (ojo con valores
      anteriores de atributos de clase).

    • Los EJB se desactivan.

    • etc..

  • Y muchas cosas más… que la experiencia nos enseña
    ….

Controlador

Asignar la responsabilidad de
controlar el flujo de eventos del sistema, a clases específicas. Esto facilita la
centralización de actividades (validaciones, seguridad, etc.) . El
controlador no realiza estas actividades, las delega en otras clases con
las que mantiene un modelo de alta cohesión.

Un error muy común es
asignarle demasiada responsabilidad y alto nivel de acoplamiento con el
resto de los componentes del sistema.

———————

En UP (proceso unificado), al construir el modelo de
análisis, existen estereotipos predefinidos que favorecen la separación
de entidades, mecanismos de interfaz y mecanismos de control.

———————

En aplicaciones Web, se tiende a separación de la lógica de presentación
y de la lógica de negocio. Patrones bién conocidos como MVC o Fachada,
son de amplia utilización..

Hay otros muchos patrones relacionados sobre todo en entornos multi-capa
(Core J2EE patterns).

——————–

En el diseño de clases de negocio, cuando no tenemos claro a qué clase pertenece la responsabilidad de
realizar una determinada tarea, crear una clase controlador que se llame igual a
la tarea a desempeñar.

Polimorfismo

Cuando identificamos variaciones en un comportamiento, asignar la
clase (interfaz) al comportamiento y utilizar polimorfismo  para
implementar los comportamientos alternativos.

——————–

El implementar comportamiento alternativos con sentencias IF-ELSE,
no hace más que limitar la reutilización y crecimiento de la
aplicación. Imagine que una aplicación muestra mensajes distintos en
distintos idiomas…. con IF, al aumentar en uno el número de idiomas,
nos obligaría a añadir un nuevo IF. Con polimorfismo nos limitaríamos
a crear un objeto de una clase polimórfica nueva (bajo acoplamiento,
alta cohesión y potencial reutilización). 

Fabricación Pura

Cuando los problemas se complican, construir clases que se encarguen
de construir los objetos adecuados en cada momento (factorías) .

—————

Todo proyecto tiene numerosa factorías potenciales, para
intercambiar fácilmente comportamientos:

  • Look&Feel (decoradores y familias de componentes gráficos)
  • Sistemas de log
  • Clases de acceso a gestor a bases de datos
  • Sistemas multi-lenguaje
  • Privilegios en base al rol de usuario
  • Muchas más capacidades comunes

Indirección

Crear clases intermedias para desacoplar clientes de servicio y
servicios.

—————–

 Pensar en sistemas middleware y se verá la utilidad de un
modo inmediato.

No hables con extraños

Un método, solamente invocará a métodos de:

  • De si mismo (this)
  • De su área de parámetros
  • Un objeto creado en su propio ámbito
  • (los demás los doy por incluidos)

——————–

Un fallo común en la construcción de sistemas Web en la utilización
de variables globales (estáticas) o el acceso desde muchos puntos
desordenadamente a variables de sesión o aplicación (contexto).

 

Aunque pueden parecer muy evidentes los principios anteriormente
enumerados, estaréis de acuerdo conmigo que es muy complicado llevarlo a
cabo en proyectos reales. Hay varios factores que lo hace difícil:

  • La presión del día a día por producir resultados (aunque sean de poca
    calidad).
  • La planificación de proyectos a coste fijo (y a precios bajos) que
    quita las ganas de pararse a pensar (más con 50 horas semanales de
    trabajo)
  • La poca inversión en formación de muchas empresas (modelo de servicios
    puro, propiciado los últimos años)
  • Falta de personas de referencia (que nos enseñen y aprendamos juntos)
    en los equipos de desarrollo.

Aunque personalmente y siendo positivo, yo que me dedico ahora a la
formación, estoy viendo claramente un interés creciente por los responsables
de equipos en mejorar el conocimiento y la calidad del producto….
posiblemente motivado por demandas del cliente ( 🙁 ).

Por cierto (y aunque no tenga demasiado que ver )… visitando el Web de Peter Coad,
he visto una cosa (simple y de gran utilidad) que nos puede ayudar a identificar
visualmente la necesidad de aplicar algunos de los patrones anteriores 
….. la justificación (a través de uno de sus libros) de por qué es
conveniente la utilización de colores para la creación de modelos UML (a mi me
ha convencido a la primera).

http://pcoad.com/download/bookpdfs/jmcuch01.pdf

A medida que se profundiza en el conocimiento …. crece la
sensación de no tenerlo ……… pero no os preocupéis …….. creo que le
pasa a toda la humanidad.

Sobre el
Autor ..

5 COMENTARIOS

  1. a pesar de q ha pasado el tiempo desde q inicio el articulo, pero esta interesante, el link a la pagina de peter coad me manda a la pag d peter, pero tiene algo q ver con la biblia o algo asi, igual muchas gracias por sintetizar la info de patrones de esa manera.

  2. Lo de… A medida que se profundiza en el conocimiento …. crece la
    sensación de no tenerlo ……… pero no os preocupéis …….. creo que le
    pasa a toda la humanidad.
    Es en realidad el síndrome de Dunnig Kruger, o sea, que leo , miro aprendo y ya creo saberlo todo.. entonces, uno decide que hacer al respecto.. o me quedo con lo que se y no evoluciono (primer pico de la curva de este síndrome) o reconozco que lo que sé, no es del todo correcto y por ello tengo que «volver» a estudiarlo o leerlo y aprenderlo y entonces es cuando evolucionas a ser un verdadero profesional, cuando cuestionas, preguntas, COMPRUEBAS si sabes lo que sabes 🙂

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad