Descarga la aplicación para disfrutar aún más
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
Compartir