Logo Studenta

DD-Evitando Código Prodedural

¡Este material tiene más páginas!

Vista previa del material en texto

Evitando Código Prodedural: 
Double Dispatching
Contexto
-3/5 + 14/27
Fraction>>+ aFraction 
^Fraction numerator: numerator * aFraction denominator + 
(aFraction numerator * denominator) 
denominator: denominator * aFraction denominator
Fraction>>+ aNumber 
Number
FloatFractionInteger
Solución procedural
• Código que recupera información para luego 
tomar una decisión en base a esa información
• En los lenguajes procedurales se usan if-then-
else o sentencias switch
Solución procedural en Smalltalk
Fraction>>+ aNumber
aNumber isFraction
ifTrue:[^Fraction numerator: numerator * aNumber denominator + 
(aNumber numerator * denominator) 
denominator: denominator * aFraction denominator
]
aNumber isInteger
ifTrue:[^Fraction numerator: aNumber * denominator + numerator
denominator: denominator
]
aNumber isFloat
ifTrue:[ ??????
]
………………………
Observaciones:
• El código depende del parámetro!!!!!
• Si en OO fuera conveniente escribir este 
código ….. 
¿Porqué Smalltalk no implementa una 
sentencia Switch?
Solución OO clasica
Usando polimorfismo
 Simplemente diciéndole al 
objeto, del cuál depende 
el cómputo, que lo haga 
el mismo
Confiar en que cada 
objeto implementa ese 
cómputo de acuerdo a sus 
propias características
Dar a los objetos 
responsabilidades y hacer 
que sean responsables de 
ejecutar la acción
Number
FloatFractionInteger
+ + +
Solución OO con Polimorfismo
• 1º versión
Fraction>>+ aNumber
aNumber sumWith: self
– El self hace falta porque 
muchas veces se necesita pasar 
el contexto 
…. Sin embargo esto no 
funciona…
Number no sabría de que 
clase es el parámetro del 
#sumWith
Number
+sumWith()
Float
+sumWith()
Fraction
+sumWith()
Integer
+
Solución OO con Double Dispatching
• Double Dispatching
– El primer objeto (receptor) le dice al segundo 
objeto (parámetro) que le diga qué hacer
Fraction>>+ aNumber
aNumber sumFromFraction: self
Double Dispatching (1)
• 2º versión
Fraction>>+ aNumber
aNumber sumFromFraction: self
Integer>>+ aNumber
aNumber sumFromInteger: self
Float>>+ aNumber
aNumber sumFromFloat: self
Double Dispatching (2)
• En la clase Integer
sumFromFraction: aFraction
^Fraction
numerator: aFraction numerator + 
(self * aFraction denominator)
denominator: aFraction denominator
sumFromFloat: aFloat
^aFloat + self asFloat
sumFromInteger: aNumber
………….
Number
+sumFromInteger()
+sumFromFraction()
+SumFromFloat()
Integer
+sumFromInteger()
+sumFromFraction()
+SumFromFloat()
Fraction
+sumFromInteger()
+sumFromFraction()
+SumFromFloat()
Float
Double Dispatching (3)
+
OTRO EJEMPLO
Cabinas de peaje 
problema: ¿cuánto se debe cobrar de peaje?
Vehículo
Automóvil MotoCamiónTrasportePasajeros
Cabina>>montoACobrarA: unVehículo
“calcula el monto a cobrar a unVehículo”
Distinto 
precio 
dependiendo 
de la cabina
Cabina
CabinaManual CabinaAutomática
Cabina
CabinaManual CabinaAutomática
problema: ¿cuánto se debe cobrar de peaje?
Vehículo
Automóvil MotoCamiónTrasportePasajeros
Cabina>>montoACobrarA:unVehículo
“procesa un vehículo”
Distinto 
proceso
Cobra y 
mantiene el 
crédito del 
vehículo
Cobra el 
precio de 
cada 
vehículo
Distinto 
precio 
dependiendo 
de la cabina
Automóvil
Transporte 
Pasajeros
Camión Moto
Cabina 
manual
4/cantidad 
de 
integrantes
11.10 6.30 1.15
Cabina 
automática
$1.90 -7% idem 1.00
unaCabina: Cabina
montoCobrarA(unVehiculo)
unVehiculo: Vehiculo
qué hacer 
depende del tipo 
de cabina y del 
tipo de vehículo
Cabina
CabinaManual CabinaAutomática
unaCabina: CabinaAutomática
montoCobrarA(unVehiculo)
unVehiculo: Vehiculo
Cuando es Cabina Automática
•Calcular el monto a 
cobrar (depende del tipo 
de vehículo)
•decrementar el crédito del 
vehículo
+montoCobrarA()
+montoCobrarA()
+montoCobrarA()
Cuando es Cabina Automática y el vehículo es Moto
+montoCobrarA(entrada unVehiculo : Vehiculo)
Cabina
Vehiculo
+montoCobrarA()
CabinaManual
+montoCobrarA()
CabinaAutomatica MotoCamionTransportePasajerosAutomovil
unaCabina: CabinaAutomática
montoCobrarA(unVehiculo)
unVehiculo: Moto
•Calcular el monto a cobrar
•El monto a cobrar de una 
moto para una cabina 
automática es de $1
•decrementar el crédito de la 
moto
Cabina
CabinaManual CabinaAutomática
+montoCobrarA()
+montoCobrarA()
+montoCobrarA()
Cuando es Cabina Automática y el vehículo es 
Moto
unaCabina: CabinaAutomática
montoCobrarA(unVehiculo)
unVehiculo: Moto
montoCobrarCA: unaCabina
montoCobrar
^1
montoCobrarCAutomatica(unaCabina)
Cuando es Cabina Automática y el vehículo es Moto
unaCabina: CabinaAutomática
montoCobrarA(unVehiculo)
unVehiculo: Moto
montoCobrarCA: unaCabina
montoCobrar
decrementarCredito:moto en:montoCobrar
montoCobrarCAutomatica(unaCabina)
decrementarCredito(unVehiculo, montoCobrar)
Diagrama de Clases completo
-credito
Vehiculo
+montoCobrarCA()
+montoCobrarCM()
Moto
+montoCobrarCA()
+montoCobrarCM()
Camion
+montoCobrarCA()
+montoCobrarCM()
TransportePasajeros
+montoCobrarCA()
+montoCobrarCM()
Automovil
^1
^6.30
Cabina
CabinaManual CabinaAutomática
+montoCobrarA()
-decrementarCredito()
+montoCobrarA() +montoCobrarA()
Ejercicio
1. Implementar todos los métodos
2. Resolver el mensaje 
#decrementarCredito
NOTA: Si hiciera falta completar el diagrama de 
clases

Continuar navegando