Download - Principios de diseño
● Introducción● DRY + SOLID + IoC + COC● GRASP● Inmutabilidad y Funciones● Closure
Agenda
Introducción
● Rigidez○ Dificultad para implementar cambios
● Fragilidad○ Tendencia a romperse con cada cambio
● Inmovilidad○ Inhabilidad de reutilizar el código
● Viscosidad○ Del Diseño: los hacks son muy sencillos○ Del Ambiente: lento e ineficiente
Síntomas de un Diseño Podrido
● Cambios en los Requerimientos○ Inicialmente no contemplados
● Administración de Dependencias○ Es la arquitectura de dependencias la que
se va degradando
Causas que Aceleran la Entropía
y Principios Relacionados
SOLID
● Cualquier funcionalidad existente en un programa debe existir de forma única
● Anti-principios:○ WET: Write Everything Twice○ WETTT: Write Everything Ten Throusand
Times○ Copy & Paste
DRY (Don't Repeat Yourself)
● Todo componente debe tener una única responsabilidad
● Una clase, al tener una única responsabilidad, sólo debe ser alterada a través de un cambio en dicha responsabilidad
● No debe existir más de una razón para cambiar una clase
SRP (Single Responsibility)
● Abierto a la Extensibilidad● Cerrado a las Modificaciones● Debemos poder añadir nueva
funcionalidad a la aplicación sin tener que alterar el código ya construido
OCP (Open-Closed Principle)
● Las clases hijas deben poder ser tratadas como las clases padre
● Diseño por Contrato (interfaces)● Un usuario de una clase base debe
continuar funcionando apropiadamente en el sistema independientemente de qué clase derivada se utilice
● Podremos cambiar comportamiento creando una nueva clase hija y sobreescribiendo comportamiento
LSP (Liskov Substitution)
● Una clase cliente A que tiene una dependencia con la clase B no debe verse forzada a depender de métodos de la clase B que no vaya a usar jamás
● Es preferible muchas interfaces con pocos métodos a pocas interfaces con muchos métodos
● Las interfaces son el contrato del comportamiento (son declarativas)
ISP (Interface Segregation)
● El control de la construcción de los objetos no recae en el desarrollador, sino que es otra clase o conjunto de clases las que se encargan de construir los objetos que necesitamos
● Al trabajar con interfaces y no crear las implementaciones, invertimos el control de ejecución del código
● En camino a un Diseño Declarativo
IOC (Inversion of Control)
● Los componentes deben depender de abstracciones, no de implementaciones concretas
● Las dependencias que una clase tiene no deben ser asignadas por ella misma sino por un agente externo (Contenedor)
● Inyección de Dependencia● Reflection, Spring, EJB, CDI
DIP (Dependency Inversion)
● Don't call us, we'll call you● Relacionado con IoC y DIP● Favorece el Bajo Acoplamiento● Favorece la Alta Cohesión
Principio de Hollywood
● Antes de abordar el desarrollo, un programador puede declarar una serie de convenciones que le permiten asumir una configuración por defecto del sistema
● Configuración por default● Rapid Development● Ruby on Rails, Seam, Spring Roo
COC (Convention Over Config)
● SRP: Single Responsibility Principle● OCP: Open-Closed Principle● LSP: Liskov Substitution Principle● ISP: Interface Segregation Principle● DIP: Dependency Inversion Principle
SOLID
General Responsibility AssignmentSoftware Principle
GRASP
● Information Expert● Creator● Indirection● Low Coupling● High Cohesion● Controller● Polymorphism● Protected Variations● Pure Fabrication
GRASP
● Asignar la responsabilidad a la clase que conoce toda la información necesaria
● Dada una responsabilidad, ¿qué clase debería cumplirla?
● Favorece el Encapsulamiento, ya que los objetos utilizan su propia información para llevar a cabo sus tareas
● Recordar SRP
Experto en Información
● ¿Quién debe crear el objeto X?○ Quien tenga la información necesaria para
realizar la creación del objeto○ Quien usa directamente las instancias
creadas del objeto○ Quien almacena o maneja varias instancias
de la clase○ Quien contiene o agrega la clase
● Patrón Factory, DIP, IOC
Creador
● ¿Cómo minimizar las dependencias entre módulos?
● Cuando una clase, paquete o módulo depende de otro, se dice que ambos están acoplados
● Tener los módulos lo menos ligados entre sí que se pueda
Bajo Acoplamiento
● La información que almacena una clase debe de ser coherente y debe estar relacionada con la clase
● ¿Qué tan fuertemente relacionadas y enfocadas son las responsabilidades de una clase?
● Recordar SRP y Information Expert
Alta Cohesión
● Dada una UI y una capa de negocio, ¿quién tiene la responsabilidad de recibir los pedidos de la UI y comunicarse con el negocio?
● Sirve como intermediario entre una determinada interfaz y el algoritmo que la implementa, separando la lógica de presentación de la lógica de negocio
● Relacionado con MVC
Controller
● Siempre que se tenga que llevar a cabo una responsabilidad que dependa del tipo
● Cuando el comportamiento varían según el tipo
● Para crear componentes conectables● Recordar OCP y LSP● Anti-principio:
○ instanceof
Polimorfismo
● Se da en las clases que no representan un ente u objeto real del problema
● Es una clase "inventada" que mejora estructuralmente el sistema
● Ejemplos:○ DDD: clases Service○ JPA: EntityManager
● Anti-principio:○ Clases Función o Algoritmo, con un solo
método
Fabricación Pura
● ¿Cómo desacoplo dos clases? ¡Pues agregando una clase intermedia!
● Objeto Mediador● Patrón Delegation● Puede ser útil por ejemplo para
encapsular una API externa y proteger a nuestra aplicación de futuros cambios de esa API
Indirección
● Para protegernos del cambio, nada mejor que trabajar con interfaces
● Diseño por Contrato● Usando el Polimorfismo, podemos
extender el sistema simplemente creando otra implementación
● Recordar OCP y LSP● También podemos protegernos con la
Indirección y el patrón Delegation
Variaciones Protegidas
y Side-Effect Free Functions
Inmutabilidad
Objetos Indep. del Contexto● Objetos Inmutables
○ Todos sus atributos son Read-Only● Objetos Stateless
○ No tiene atributos● Objetos con Estado Independiente del
Contexto○ El estado es compartido por todos○ Ningún contexto puede modificar su estado○ Ejemplo: Una clase de Configuración
● Read-only● No se les puede cambiar el estado● No pueden ser corrompidos● Thread-Safe por naturaleza● En DDD es ideal que los ValueObject sean
implementados como Objetos Inmutables● Overhead por cantidad de objetos:
¡Despreciable! (sino Flyweight Pattern)
Objetos Inmutables
● No proveerás setters● Todos los atributos serán privados y final● No permitirás a subclases sobreescribir
métodos (la clase será final o el constructor privado y métodos factory)
● Si el objeto inmutable debe contener la referencia a un objeto mutable, entonces...
Reglas de Inmutabilidad para Java
● No escribirás métodos que modifiquen el objeto mutable
● No compartirás referencias del objeto mutable
● Crearás copias y guardarás referencias a esas copias
● Crearás copias de tu objeto mutable interno cuando tengas que devolverlo en algún getter
Para Referencias a Obj Mutables
● Se dice que una función o expresión está libre de efectos colaterales o secundarios si ésta no modifica el estado de su entorno, independientemente del valor que devuelva
Side-Effect Free Functions (1)
● Operaciones○ Comandos: introducen un cambio en el
sistema (Ej: los setters)○ Consultas: obtienen info del sistema sin
modificarlo (Ej: los getters)● Las funciones devuelven un resultado sin
producir un efecto secundario● Las funciones idempotentes están libres
de efectos secundarios por definición
Side-Effect Free Functions (2)
● Las funciones son más fáciles de probar que los comandos
● Las funciones implican menor riesgo● Best Practice: Mantener separados los
comandos de las consultas● Best Practice: Siempre que se pueda,
devolver un objeto inmutable como resultado de un cálculo
Side-Effect Free Functions (3)
● Todas las operaciones de un objeto inmutable deberían ser funciones
Side-Effect Free Functions (4)
... inventáramos un lenguaje donde sólo se pudieran crear funciones y no existieran los estados?
¿Qué tal si...
Más allá de la ProgramaciónOrientada a Objetos
Otros Mundos
Paradigmas de Programación● Imperativo (Ej: Pascal, C, Basic)● Orientado a Objetos (Ej: Smalltalk, Ruby,
Java, C++)● Funcional (Ej: Haskell, Scheme, Lisp)● Lógico (Ej: Prolog)● Declarativo (Ej: DSL: HTML, Logo,
Matlab, SQL)
● Entorno privado de variables cuya existencia se propaga a lo largo de todas las ejecuciones de un bloque de código
● Puede ser usada para asociar una función con un conjunto de variables privadas que persisten en las invocaciones de la función
Closure (1)
● Entorno cerrado de variables● Java brinda Closures a través de:
○ Clases Anónimas Internas○ La API de Reflection
● JavaScript y otros Lenguajes proveen Closures con una sintaxis más natural (más nativa)
● En JavaScript, si se declara una función dentro de otra => Closure
Closure (2)
Más allá de los Principios de Diseño
Conclusión
KISS (Keep It Simple, Stupid)
● Patrones de Diseño● Patrones de Arquitectura● Patrones de Aplicaciones Enterprise● Domain-Driven Design● Atributos de Calidad● Domain Specific Languages● ¡Ponete un ArgenChino y Dejá de Robar!
Ideas para Próximas Charlas
● Robert C. Martin (Uncle Bob) - SOLID● http://lostechies.
com/derickbailey/2009/02/11/solid-development-principles-in-motivational-pictures/
● Craig Larman - GRASP● http://www.arquitecturajava.com/● http://www.slideshare.net/snmgian/grasp-
principles● Wikipedia● JavaScript Closures for Dummies (post)
Bibliografía
https://github.com/elfrasco/design-principles
Código Fuente