Principios de diseño

Post on 02-Aug-2015

1.584 views 0 download

Transcript of Principios de diseño

Principios de Diseño

adrianp@epidataconsulting.com

@aparedes82

http://elblogdelfrasco.blogspot.com

● 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