Hola.
Hoy vamos a hablar de mensajes.
Verás por qué tener muchos mensajes y métodos pequeños es bueno.
Contrariamente a lo que muchos desarrolladores creen.
Esta diapositiva ilustra una secuencia de diseño.
Esto es válido no solo para Pharo,
sino para el diseño en cualquier lenguaje orientado a objetos.
Como sabes, los mensajes enviados son lugares
donde podemos definir el comportamiento.
Los desarrolladores a menudo dicen que les gustan los métodos grandes porque
son fáciles de entender.
Lees las lineas y entiendes el código.
Pero en esta sesión te mostraré
que esto no es tan bueno.
En general, los métodos grandes significan un mal diseño.
Una jerarquía de clases
y un mismo método implementado en varias clases,
es un medio de definir elecciones.
Si tomo una clase gorda con muchas operaciones,
y tengo que elegir una operación según el estado,
mi código dirá:"Si estoy en este estado, Hago esta operación
"Si estoy en ese estado, Yo hago esa operación ".
Tendrás código grande
con IFs por todos lados.
Esto significa que cuando desees agregar nuevos casos,
tendrás que modificar métodos en todas partes.
En la versión a la derecha,
la operación para cada caso se divide en una clase específica.
Todo lo que tienes que hacer es enviar un mensaje de operación
a un objeto para crear un IF.
El IF no necesita ser escrito por el programador.
Se hace automáticamente a través del principio de polimorfismo.
En las siguientes diapositivas, te mostraré cómo mejorar un ejemplo
cambiando pequeñas partes por vez.
Aquí hay un método grande que no es fácil de entender
y que hace muchas cosas.
Esto es lo que queremos hacer.
En una subclase,
queremos dar esta variable aquí un valor diferente.
Como está armado,
la única forma de hacer eso es crear la subclase,
luego duplicar todo el código,
agregando la pequeña modificación que queremos hacer.
En lenguajes como Java
que usan "private",
si los atributos usados por el método son privados,
lo que acabo de hacer es imposible.
Si el método usa variables de instancia que son privadas,
las subclases no pueden duplicar el código.
Pero en cualquier caso, duplicar no es una buena práctica,
porque la duplicación también copia errores.
Si tengo un error en mi versión original, Tendré un error en mis copias.
Y si modifico una copia, Tengo que modificar todas las duplicaciones.
Es trabajo extra para el desarrollador
y debes recordar que hay varias copias
La solución real es enviar mensajes.
En un método, cuando envías un mensaje en lugar de escribir
el contenido del método correspondiente directamente en el interior,
las subclases pueden cambiar el comportamiento.
Si miramos el método bar,
envía foo a self.
En A, foo devuelve 10,
pero las subclases puede cambiar este valor
y reemplazarlo por 42, por ejemplo.
Entonces, ¿cómo podemos mejorar el código que acabas de ver
y beneficiarnos del mecanismo de herencia
sin usar duplicación?
Voy a extraer esta parte aquí y enviar un mensaje en su lugar.
Se realiza mediante una función de refactorización llamada 'Extract Method'.
Tienes herramientas para transformar este código en este código de aquí.
El código que seleccioné en la diapositiva anterior
fue transferido en un nuevo método llamado ratio.
Y aquí donde se escribió el código, ahora tenemos un envio de mensaje.
Esto significa que en las subclases,
puedo cambiar este comportamiento
Cambiarlo por completo
o recuperar el comportamiento de la superclase y hacer una modificación.
Eso es lo que estoy haciendo aquí.
Envío un mensaje ratio a super
para ejecutar el código tal como es en la superclase,
y agrego 10, que es mi objetivo.
Otro método posible es extraer esta parte aquí,
para que las subclases puedan cambiar este comportamiento.
Extraigo esta pieza de código
en un metodo específico.
Y en el método primario, envío un mensaje.
En este caso,
la clase para la que queremos una variable de instancia está fija.
Esto significa que si las subclases quieren cambiar esta clase,
para obtener potencialmente una subclase de UINode,
tendrán que duplicar todo el método.
Aquí podemos usar el mismo proceso
y extraer la clase en un método,
para que las subclases puedan cambiar la variable de instancia.
Eso es lo que estoy haciendo aquí.
Extraigo la parte que me interesa en un metodo,
y envío un mensaje.
Enviar un mensaje habilita las subclases para cambiar el comportamiento.
Como dije antes, ciertos programadores
no están de acuerdo con este enfoque.
Les resulta difícil leer muchos pequeños métodos dispersos.
Prefieren leer un gran método línea por línea.
Esta no es una buena práctica, porque leer código línea por línea
no funcionará si la aplicación es muy grande.
No puedes leer línea por línea. y entender lo que está pasando.
Aquí es donde las abstracciones son útiles y extraer trozos de comportamiento
o expresiones de métodos tiene sentido.
Puedes leer un método globalmente sin comprender todos los detalles.
Así que los pequeños métodos son buenos, deberías usarlos en todas partes.
Vamos a seguir.
Aquí vemos que el valor 55 aparece fijo
en el codigo de metodo.
Esto significa que en las subclases no se puede cambiar a 100, por ejemplo.
Entonces extraeremos este valor como hicimos anteriormente,
y lo ponemos en un método separado para que las subclases pueden cambiar el valor.
Otra ventaja es que anteriormente
el valor 55 se escribió aquí.
Ahora se llama self averageRatio.
Esto significa que reemplazamos un valor numérico por un nombre,
y ahora sé a lo que el valor 55 corresponde.
Sé que significa averageRatio y cuando leo el código lo entiendo.
Entonces, teniendo muchos pequeños métodos ayuda a leer el código.
Crear un método averageRatio para retornar 55
habilita a todas las subclases para cambiar valores.
¿Pero cómo podemos dejar que los usuarios de clase cambien también su valor?
Lo que podemos hacer,
es usar una variable de instancia.
El método averageRatio usado en la diapositiva anterior
devolverá el valor de la variable de instancia,
si contiene un valor. De lo contrario, devuelve el valor predeterminado.
El valor predeterminado era 55.
Y los usuarios de un objeto de nodo
pueden programar cualquier valor que les guste dentro.
Con este diseño,
las subclases pueden sobreescribir defaultAverageRatio
y cambia el valor.
Y los usuarios pueden establecer un valor ejecutando el programa.
Eso se llama programación orientada a gruyere.
Un programa orientado a objetos, un método GANADOR,
contiene agujeros
que se pueden rellenar con subclases.
Como conclusión,
el código puede ser reutilizado y refinado en subclases.
Cada vez que enviamos un mensaje,
las subclases pueden cambiar el comportamiento de la superclase:
Refinarlo o cámbiarlo por completo.
Los métodos pequeños son excelentes porque dan nombres a trozos de expresiones,
y porque dan a las subclases la libertad de cambiar el comportamiento.