1 of 10

Agregando funcionalidades a un objeto

Fernando Dodino

Algoritmos 2

2 of 10

Decorator

  • Agrega funcionalidades por capas
  • en forma externa al objeto decorado, que no conoce que lo decoran,
  • se suele instanciar dinámicamente,
  • es molesto decorar un objeto con una interfaz grande,
  • es complejo

3 of 10

Template method en un objeto decorado

¿Qué pasa en este ejemplo?

>>class Producto

def double precioVenta() { costo * 2.5 + this.costoAlmacenamiento() }abstract def double costoAlmacenamiento()

>>class ProductoPropio extends Producto

def double costoAlmacenamiento() { 500 }

... otras subclases...

<<Decorator>>

class ProductoEnPromocion extends Producto {Producto productooverride precioVenta() { producto.precioVenta() * 0.8 }override costoAlmacenamiento() { 0 }}

Producto camperaSindical = new ProductoEnPromocion(new ProductoPropio(60))// 60 es el costo

Assert.assertEquals(120, camperaSindical.precioVenta)

4 of 10

Template method en un objeto decorado

¿Qué pasa en este ejemplo?

>>class Producto

def double precioVenta() { costo * 2.5 + this.costoAlmacenamiento() }abstract def double costoAlmacenamiento()

>>class ProductoPropio extends Producto

def double costoAlmacenamiento() { 500 }

... otras subclases...

<<Decorator>>

class ProductoEnPromocion extends Producto {Producto productooverride precioVenta() { producto.precioVenta() * 0.8 }override costoAlmacenamiento() { 0 }}

Producto camperaSindical = new ProductoEnPromocion(new ProductoPropio(60))// 60 es el costo

Assert.assertEquals(120, camperaSindical.precioVenta)

1

1

1

5 of 10

Template method en un objeto decorado

¿Qué pasa en este ejemplo?

>>class Producto

def double precioVenta() { costo * 2.5 + this.costoAlmacenamiento() }abstract def double costoAlmacenamiento()

>>class ProductoComun extends Producto

def double costoAlmacenamiento() { 500 }

... otras subclases...

<<Decorator>>

class ProductoEnPromocion extends Producto {Producto productooverride precioVenta() { producto.precioVenta() * 0.8 }override costoAlmacenamiento() { 0 }}

Producto camperaSindical = new ProductoEnPromocion(new ProductoComun(60))// 60 es el costo

Assert.assertEquals(120, camperaSindical.precioVenta)

1

1

2

2

6 of 10

Explorando otras variantes

  • Decorator + Strategy
  • Mixines
  • Delegated classes

7 of 10

Mixins

  • Los mixins son un mecanismo para compartir código similar a las clases
  • Es posible combinar varios mixins para que un objeto tenga comportamiento obtenido de diferentes lugares
  • ¿Es como la herencia múltiple? Sí, pero evita el “problema del diamante”, que vemos a continuación: cuando enviamos el mensaje open() a WindowDoor, ¿de dónde debe heredar?
  • Existen diferentes sabores en Scala, Groovy, Ruby, Python y Javascript...

8 of 10

Mixins en Wollok

Pero vamos a ver un ejemplo en Wollok

mixin SafeShop {

var property montoMaximoSafeShop = 50

method comprar(monto) {

if (monto > montoMaximoSafeShop) {

throw new Exception(message = "...")

}

super(monto)

}

}

9 of 10

Mixins en Wollok: Linearization

class ClienteConSafeShop inherits Cliente mixed with SafeShop {}

class ClienteMixto inherits Cliente mixed with SafeShop, Promocion { }

10 of 10

Delegated methods en Kotlin

class ClienteSafeShop(

val maximo: Int,

val cliente : Cliente) : Cliente by cliente {

override fun comprar(monto: Int) {

if (monto > maximo) throw RuntimeException("No puede comprar por más de " + monto)

cliente.comprar(monto)

}

}