patrones utiles para solid

58
noviembre de 2011 Patrones útiles para los principios SOLID Dept. Tecnologias Corporativas José Miguel Torres Area I+D+i

Upload: jose-miguel-torres

Post on 07-Jul-2015

233 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Patrones utiles para solid

noviembre de 2011

Patrones útiles para los principios SOLID

Dept. Tecnologias Corporativas

José Miguel TorresArea I+D+i

Page 2: Patrones utiles para solid

• Básicos• Fundamentos• Principios• Patrones

• Aspectos• Acoplamiento• Cohesión• Encapsulamiento

• Principios SOLID• SRP• OCP• LSP• DIP• ISP

• Reflexión

Agenda

Page 3: Patrones utiles para solid
Page 4: Patrones utiles para solid
Page 5: Patrones utiles para solid
Page 6: Patrones utiles para solid
Page 7: Patrones utiles para solid
Page 8: Patrones utiles para solid
Page 9: Patrones utiles para solid
Page 10: Patrones utiles para solid
Page 11: Patrones utiles para solid
Page 12: Patrones utiles para solid
Page 13: Patrones utiles para solid

Acoplamiento

Cohesión

Encapsulamiento

Page 14: Patrones utiles para solid

Principios SOLID

SRP - Single Responsibility Principle

OCP - Open Closed Principle

LSP - Liskov Substitution Principle

DIP - Dependency Inversion Principle

ISP - Interface Segregation Principle

Page 15: Patrones utiles para solid
Page 16: Patrones utiles para solid

Principio de Responsabilidad Únicapublic class Factura

{

public string _codigo;

public DateTime _fechaEmision;

public decimal _importeFactura;

public decimal _importeIVA;

public decimal _importeDeducir;

public decimal _importeTotal;

public ushort _porcentageDeduccion;

//método que calcula el Total de la factura

public void CalcularTotal()

{

//Calculamos la deducción_importeDeducir = (_importeFactura*_porcenDeduccion)

/100;

//Calculamos el IVA

_importeIVA = _importeFactura * 0.16m;

//calculamos el total

_importeTotal = (_importeFactura - _importeDeducir)

+ _importeIVA;

}

}

Page 17: Patrones utiles para solid

Principio de Responsabilidad Única

Una clase debe tener una y sólo una única causa por la cual puede ser modificadaRobert C. Martin

Page 18: Patrones utiles para solid

Principio de Responsabilidad Única//clase IVA que calcula el iva en base a un importe

public class IVA {

public readonly decimal _iva = 0.16m;

public decimal CalcularIVA(decimal importe){

return importe*_iva;}

}

//clase deduccion que calcula la deducción en base a un importepublic class Deduccion {

public readonly decimal _deduccion;

public Deduccion(ushort porcentage){

_deduccion = porcentage; }

public decimal CalcularDeduccion(decimal importe){

return (importe*_deduccion)/100;}

}

Page 19: Patrones utiles para solid

Principio de Responsabilidad Únicapublic class Factura{

public string _codigo;public DateTime _fechaEmision;

public decimal _importeFactura;public decimal _importeIVA;public decimal _importeDeducir;public decimal _importeTotal;public ushort _porcentageDeduccion;

public void CalcularTotal(){

//calculamos el IVAIVA iva = new IVA();_importeIVA = iva.CalcularIVA(_importeFactura);

//calculamos la deducción a aplicarDeduccion deduccion = new Deduccion(_porcentageDeduccion);_importeDeducir = deduccion.CalcularDeduccion(_importeFactura);

//calculamos el total_importeTotal = (_importeFactura - _importeDeducir) + _importeIVA;

}}

Page 20: Patrones utiles para solid

Principio de Responsabilidad Única

interface Modem{void dial(int pNumber);void hangup();void send(char[] data);char[] receive();

}

Page 21: Patrones utiles para solid

Patrón Software

Page 22: Patrones utiles para solid

Patrón Software

Page 23: Patrones utiles para solid
Page 24: Patrones utiles para solid

Principio Open/Closedpublic void Finalizar()

{

switch (_estadoTarea)

{

case TareasEstadosEnum.Pendiente:

//finalizamos

break;

case TareasEstadosEnum.Finalizada:

throw new

ApplicationException

("Ya esta finalizada");

case TareasEstadosEnum.Cancelada:

throw new

ApplicationException

("Imposible finalizar. Tarea cancelada");

default:

throw new ArgumentOutOfRangeException();

}

}

Page 25: Patrones utiles para solid

Principio Open/Closed

public void Finalizar()

{

switch (_estadoTarea)

{

case TareasEstadosEnum.Pendiente:

//finalizamos

break;

case TareasEstadosEnum.Finalizada:

throw new ApplicationException("Ya esta finalizada");

case TareasEstadosEnum.Cancelada:

throw new ApplicationException("Imposible finalizar. Tarea cancelada");

case TareasEstadosEnum.Pospuesta:

throw new ApplicationException("Imposible finalizar. Tarea no completada");

default:

throw new ArgumentOutOfRangeException();

}

Page 26: Patrones utiles para solid

Principio Software

Page 27: Patrones utiles para solid

Principio Software

Page 28: Patrones utiles para solid

Principio Open/Closed

Una clase debe estar abierta a extensiones pero cerrada

a las modificaciones.Dr. Bertrand Meyer

Page 29: Patrones utiles para solid

Fundamentos OO Encapsulamiento

class EstadosTareas

{

public virtual void Finalizar(EstadoTareasEnum estadoTareasEnum)

{

switch (estadoTareasEnum) {

case EstadoTareasEnum.Pendiente:

//finalizamos

case EstadoTareasEnum.Pospuesta:

throw new ApplicationException("Imposible finalizar. Tarea no completada");

. . . .default:

throw new ArgumentOutOfRangeException();

}

}

public virtual void Cancelar(EstadoTareasEnum estadoTareasEnum)

{

switch (estadoTareasEnum){

. . . .//cancelamos

}

}

public virtual void Posponer(EstadoTareasEnum estadoTareasEnum)

{

switch (estadoTareasEnum){

. . . .//posponemos

}

}

}

Page 30: Patrones utiles para solid

Fundamentos OO Polimorfismo

abstract class EstadosTareasBase {

protected Tareas _tarea;

public abstract void Finalizar();

public abstract void Cancelar();

public abstract void Posponer();

}

class EstadoTareaPendiente : EstadosTareasBase {

public override void Finalizar()

{

//finalizamos

}

public override void Cancelar()

{

//cancelamos

}

public override void Posponer()

{

//posponemos

}

}

Page 31: Patrones utiles para solid

Fundamentos OO Polimorfismo

class Tareas

{

private EstadosTareasBase _estadosTareas;

public Tareas()

{

_estadosTareas = new EstadoTareaPendiente();

}

public void Finalizar()

{

_estadosTareas.Finalizar();

}

public void Cancelar()

{

_estadosTareas.Cancelar();

}

public void Posponer()

{

_estadosTareas.Posponer();

}

}

Page 32: Patrones utiles para solid

Patrón Software

Page 33: Patrones utiles para solid

Patrón Software

Page 34: Patrones utiles para solid
Page 35: Patrones utiles para solid

Principio de Substitución de Liskovclass Ciclomotor: Vehiculo

{

public string ObtenerNumLicencia()

{

//devuelve num licencia

}

}

class Coche: Vehiculo

{

public string ObtenerMatricula()

{

//devuelve matricula

}

}

class Impuestos

{

public void CalcularImpuesto(Vehiculo vehiculo)

{

string matricula = ((Coche) vehiculo).ObtenerMatricula();

ServicioCalculoImpuestos(matricula, vehiculo.Cilindrada);

}

}

Page 36: Patrones utiles para solid

Principio de Substitución de Liskov

Si por cada objeto o1 del tipo S existe un objeto o2 del tipo T

tal que para todos los programas P definidos en términos de T y el comportamiento de P

permanece invariable cuando o1 es sustituido por o2, entonces S es un subtipo de T.

Barbara Liskov

Page 37: Patrones utiles para solid

Principio de Substitución de Liskov

public void CalcularImpuesto(Vehiculo vehiculo)

{

string matricula = string.Empty;

if (vehiculo.GetType().Name == "Coche")

matricula = ((Coche) vehiculo).ObtenerMatricula();

else if (vehiculo.GetType().Name == "Ciclomotor")

matricula = ((Ciclomotor)vehiculo).ObtenerNumLicencia();

ServicioCalculoImpuestos(matricula, vehiculo.Cilindrada);

}

Page 38: Patrones utiles para solid

Principio de Substitución de Liskovpublic class Cuadrado : Rectangulo

{

public override int Ancho

{

get

{

return base.Ancho;

}

set

{

base.Ancho = value;

base.Alto = value;

}

}

public override int Alto

{

get

{

return base.Alto;

}

set

{

base.Ancho = value;

base.Alto = value;

}

}

}

public class Rectangulo

{

public virtual int Ancho { get; set; }

public virtual int Alto { get; set; }

}

Page 39: Patrones utiles para solid

Principio de Substitución de Liskov[Test]

public void AreaRectangulo()

{

Rectangulo r =

new Cuadrado

{

Ancho = 5,

Alto = 2

};

// Fallará pues cuadrado establece

// a 2 el ancho y el alto

Assert.IsEqual(r.Ancho*r.Alto, 10); // false

}

Page 40: Patrones utiles para solid

Patrón Software

Page 41: Patrones utiles para solid

Diseño por Contratos

[Test]

public void AreaRectangulo()

{

Rectangulo r = new Cuadrado {Ancho = 5, Alto = 2};

// Fallará pues cuadrado establece

// a 2 el ancho y el alto

Assert.IsEqual(r.Ancho*r.Alto, 10); // false

}

Page 42: Patrones utiles para solid
Page 43: Patrones utiles para solid

Principio Inyección Dependencias

Page 44: Patrones utiles para solid

Principio Inyección Dependencias

public class EstacioMeteorologica

{

public void MostrarDatos()

{

Barometro barometro = new Barometro();

Termometro termometro = new Termometro();

int presion = barometro.Valor;

int temperatura = termometro.Valor;

Console.WriteLine(

string.Format("Datos a {0} \nTemperatura: {1}\nPresión:{2}",DateTime.Now, temperatura, presion));

}

}

Page 45: Patrones utiles para solid

Principio Inyección Dependencias

•Las clases de alto nivel no deberían depender sobre las clases de bajo nivel. Ambas deberían

depender de las abstracciones.•Las abstracciones deberían no depender de los detalles. Los detalles deberían depender de las abstracciones.

Robert C. Martin

Page 46: Patrones utiles para solid

Principio Inyección Dependencias

Page 47: Patrones utiles para solid

Principio Inyección Dependencias

public class EstacioMeteorologica

{

private IMeteoReferencia __dispo;

public EstacioMeteorologica(

IMeteoReferencia dispositivo)

{

_ __dispo = dispositivo;

}

public void MostrarDatos()

{

Console.WriteLine(

string.Format("Fecha/Hora {0}", DateTime.Now));

Console.WriteLine(_ __dispo());

}

}

Page 48: Patrones utiles para solid

Inversión Del Control (IoC)

Page 49: Patrones utiles para solid

Patrón Software

Page 50: Patrones utiles para solid
Page 51: Patrones utiles para solid

Principio Segregación Interfaces

Page 52: Patrones utiles para solid

Principio Segregación Interfacesclass Modelo2002 : ImpresoraMultifuncional {

public override void Imprimir()

{

Impresion.EnviarImpresion();

}

public override void Escanear()

{

Escaner.DigitalizarAFormatoPng();

}

public override void Cancelar()

{

Impresion.CancelarImpresion();

}

public override void EnviarFax()

{

throw new System.NotImplementedException();

}

public void EnviarEMail() {

//enviamos por correo electrónico}

}

Page 53: Patrones utiles para solid

Principio Segregación Interfaces

Los clientes no deben ser forzosamente dependientes de las interfaces que no utilizan.

Robert C. Martin

Page 54: Patrones utiles para solid

Principio Segregación Interfacespublic interface IImprimible

{

void Imprimir();

}

public interface IFotocopiable

{

void Fotocopiar();

}

public interface IEscaneable

{

void Escanear();

}

public interface IFaxCompatible

{

void EnviarFax();

void RecibirFax();

}

public interface ITcpIpCompatible

{

void EnviarEMail();

}

class Modelo1998 : IImprimible, IEscaneable, IFaxCompatible

{... }class Modelo2000 : IImprimible, IEscaneable, IFaxCompatible, IFotocopiable

{...}

class Modelo2002 : IImprimible, IEscaneable, IFotocopiable, ITcpIpCompatible

{...}

Page 55: Patrones utiles para solid
Page 56: Patrones utiles para solid

Patrón Software

Page 57: Patrones utiles para solid

Principios OO

• Encapsular aquellas partes susceptibles devariaciones

• Más composición, menos herencia

• Programa interfaces, no implementaciones

• Aboga por el bajo acoplamiento

• Ábrete a extensiones, ciérrate a modificaciones.

• Depende de abstracciones, no de clases concretas

• Sólo habla a “tus amigos”.

• “No nos llames; nosotros lo haremos”

• Una clase debe tener una única razón de cambio.

• Analiza el tamaño de los métodos. Los if/switch noshablan.