1 00:00:00,680 --> 00:00:01,800 Hola. 2 00:00:01,960 --> 00:00:04,640 Hoy vamos a hablar de mensajes. 3 00:00:04,800 --> 00:00:08,800 Verás por qué tener muchos mensajes y métodos pequeños es bueno. 4 00:00:08,960 --> 00:00:11,520 Contrariamente a lo que muchos desarrolladores creen. 5 00:00:12,640 --> 00:00:16,120 Esta diapositiva ilustra una secuencia de diseño. 6 00:00:16,640 --> 00:00:18,920 Esto es válido no solo para Pharo, 7 00:00:19,080 --> 00:00:22,280 sino para el diseño en cualquier lenguaje orientado a objetos. 8 00:00:23,800 --> 00:00:27,240 Como sabes, los mensajes enviados son lugares 9 00:00:27,400 --> 00:00:30,640 donde podemos definir el comportamiento. 10 00:00:30,840 --> 00:00:35,680 Los desarrolladores a menudo dicen que les gustan los métodos grandes porque 11 00:00:35,840 --> 00:00:37,760 son fáciles de entender. 12 00:00:37,920 --> 00:00:41,480 Lees las lineas y entiendes el código. 13 00:00:41,640 --> 00:00:44,320 Pero en esta sesión te mostraré 14 00:00:44,480 --> 00:00:46,720 que esto no es tan bueno. 15 00:00:46,880 --> 00:00:50,080 En general, los métodos grandes significan un mal diseño. 16 00:00:51,280 --> 00:00:53,120 Una jerarquía de clases 17 00:00:53,280 --> 00:00:56,280 y un mismo método implementado en varias clases, 18 00:00:56,440 --> 00:00:58,480 es un medio de definir elecciones. 19 00:00:59,000 --> 00:01:02,960 Si tomo una clase gorda con muchas operaciones, 20 00:01:03,120 --> 00:01:07,320 y tengo que elegir una operación según el estado, 21 00:01:07,480 --> 00:01:11,240 mi código dirá:"Si estoy en este estado, Hago esta operación 22 00:01:11,400 --> 00:01:13,960 "Si estoy en ese estado, Yo hago esa operación ". 23 00:01:14,120 --> 00:01:16,680 Tendrás código grande 24 00:01:16,840 --> 00:01:19,360 con IFs por todos lados. 25 00:01:19,520 --> 00:01:22,520 Esto significa que cuando desees agregar nuevos casos, 26 00:01:22,680 --> 00:01:25,040 tendrás que modificar métodos en todas partes. 27 00:01:25,400 --> 00:01:28,400 En la versión a la derecha, 28 00:01:29,200 --> 00:01:33,880 la operación para cada caso se divide en una clase específica. 29 00:01:34,240 --> 00:01:38,040 Todo lo que tienes que hacer es enviar un mensaje de operación 30 00:01:38,320 --> 00:01:41,280 a un objeto para crear un IF. 31 00:01:41,440 --> 00:01:45,320 El IF no necesita ser escrito por el programador. 32 00:01:46,640 --> 00:01:50,480 Se hace automáticamente a través del principio de polimorfismo. 33 00:01:50,640 --> 00:01:55,920 En las siguientes diapositivas, te mostraré cómo mejorar un ejemplo 34 00:01:56,080 --> 00:01:58,120 cambiando pequeñas partes por vez. 35 00:01:58,640 --> 00:02:01,760 Aquí hay un método grande que no es fácil de entender 36 00:02:01,920 --> 00:02:03,480 y que hace muchas cosas. 37 00:02:03,640 --> 00:02:05,560 Esto es lo que queremos hacer. 38 00:02:06,280 --> 00:02:07,640 En una subclase, 39 00:02:07,800 --> 00:02:11,840 queremos dar esta variable aquí un valor diferente. 40 00:02:12,800 --> 00:02:14,720 Como está armado, 41 00:02:14,880 --> 00:02:18,000 la única forma de hacer eso es crear la subclase, 42 00:02:18,160 --> 00:02:20,920 luego duplicar todo el código, 43 00:02:21,080 --> 00:02:24,080 agregando la pequeña modificación que queremos hacer. 44 00:02:24,920 --> 00:02:27,480 En lenguajes como Java 45 00:02:27,640 --> 00:02:29,160 que usan "private", 46 00:02:29,320 --> 00:02:32,560 si los atributos usados por el método son privados, 47 00:02:32,720 --> 00:02:34,760 lo que acabo de hacer es imposible. 48 00:02:35,000 --> 00:02:39,040 Si el método usa variables de instancia que son privadas, 49 00:02:39,200 --> 00:02:42,520 las subclases no pueden duplicar el código. 50 00:02:42,880 --> 00:02:46,960 Pero en cualquier caso, duplicar no es una buena práctica, 51 00:02:47,480 --> 00:02:50,120 porque la duplicación también copia errores. 52 00:02:50,280 --> 00:02:54,560 Si tengo un error en mi versión original, Tendré un error en mis copias. 53 00:02:55,800 --> 00:03:00,640 Y si modifico una copia, Tengo que modificar todas las duplicaciones. 54 00:03:01,520 --> 00:03:03,760 Es trabajo extra para el desarrollador 55 00:03:03,920 --> 00:03:07,200 y debes recordar que hay varias copias 56 00:03:08,760 --> 00:03:11,960 La solución real es enviar mensajes. 57 00:03:12,320 --> 00:03:16,560 En un método, cuando envías un mensaje en lugar de escribir 58 00:03:16,720 --> 00:03:20,160 el contenido del método correspondiente directamente en el interior, 59 00:03:20,320 --> 00:03:22,920 las subclases pueden cambiar el comportamiento. 60 00:03:24,160 --> 00:03:26,640 Si miramos el método bar, 61 00:03:26,800 --> 00:03:28,680 envía foo a self. 62 00:03:28,840 --> 00:03:30,960 En A, foo devuelve 10, 63 00:03:31,120 --> 00:03:33,880 pero las subclases puede cambiar este valor 64 00:03:34,040 --> 00:03:36,600 y reemplazarlo por 42, por ejemplo. 65 00:03:37,240 --> 00:03:40,720 Entonces, ¿cómo podemos mejorar el código que acabas de ver 66 00:03:40,880 --> 00:03:44,360 y beneficiarnos del mecanismo de herencia 67 00:03:44,520 --> 00:03:46,320 sin usar duplicación? 68 00:03:46,480 --> 00:03:50,520 Voy a extraer esta parte aquí y enviar un mensaje en su lugar. 69 00:03:50,680 --> 00:03:54,200 Se realiza mediante una función de refactorización llamada 'Extract Method'. 70 00:03:54,360 --> 00:03:58,080 Tienes herramientas para transformar este código en este código de aquí. 71 00:03:59,200 --> 00:04:01,960 El código que seleccioné en la diapositiva anterior 72 00:04:02,120 --> 00:04:06,240 fue transferido en un nuevo método llamado ratio. 73 00:04:07,800 --> 00:04:12,320 Y aquí donde se escribió el código, ahora tenemos un envio de mensaje. 74 00:04:13,240 --> 00:04:15,880 Esto significa que en las subclases, 75 00:04:17,000 --> 00:04:20,360 puedo cambiar este comportamiento 76 00:04:20,520 --> 00:04:22,440 Cambiarlo por completo 77 00:04:22,600 --> 00:04:26,640 o recuperar el comportamiento de la superclase y hacer una modificación. 78 00:04:26,800 --> 00:04:28,560 Eso es lo que estoy haciendo aquí. 79 00:04:28,720 --> 00:04:30,720 Envío un mensaje ratio a super 80 00:04:30,880 --> 00:04:34,760 para ejecutar el código tal como es en la superclase, 81 00:04:34,920 --> 00:04:37,720 y agrego 10, que es mi objetivo. 82 00:04:39,880 --> 00:04:44,760 Otro método posible es extraer esta parte aquí, 83 00:04:44,920 --> 00:04:49,440 para que las subclases puedan cambiar este comportamiento. 84 00:04:50,360 --> 00:04:53,160 Extraigo esta pieza de código 85 00:04:53,320 --> 00:04:55,640 en un metodo específico. 86 00:04:56,200 --> 00:04:59,440 Y en el método primario, envío un mensaje. 87 00:05:02,120 --> 00:05:03,240 En este caso, 88 00:05:03,480 --> 00:05:07,520 la clase para la que queremos una variable de instancia está fija. 89 00:05:07,680 --> 00:05:11,400 Esto significa que si las subclases quieren cambiar esta clase, 90 00:05:11,560 --> 00:05:14,160 para obtener potencialmente una subclase de UINode, 91 00:05:14,320 --> 00:05:17,280 tendrán que duplicar todo el método. 92 00:05:17,440 --> 00:05:19,600 Aquí podemos usar el mismo proceso 93 00:05:19,760 --> 00:05:23,440 y extraer la clase en un método, 94 00:05:23,600 --> 00:05:27,040 para que las subclases puedan cambiar la variable de instancia. 95 00:05:27,200 --> 00:05:28,840 Eso es lo que estoy haciendo aquí. 96 00:05:29,000 --> 00:05:32,440 Extraigo la parte que me interesa en un metodo, 97 00:05:34,720 --> 00:05:36,760 y envío un mensaje. 98 00:05:36,920 --> 00:05:40,560 Enviar un mensaje habilita las subclases para cambiar el comportamiento. 99 00:05:40,920 --> 00:05:43,760 Como dije antes, ciertos programadores 100 00:05:43,920 --> 00:05:46,440 no están de acuerdo con este enfoque. 101 00:05:47,120 --> 00:05:51,520 Les resulta difícil leer muchos pequeños métodos dispersos. 102 00:05:51,680 --> 00:05:54,280 Prefieren leer un gran método línea por línea. 103 00:05:54,440 --> 00:05:58,200 Esta no es una buena práctica, porque leer código línea por línea 104 00:05:58,360 --> 00:06:01,400 no funcionará si la aplicación es muy grande. 105 00:06:01,560 --> 00:06:05,640 No puedes leer línea por línea. y entender lo que está pasando. 106 00:06:05,800 --> 00:06:10,440 Aquí es donde las abstracciones son útiles y extraer trozos de comportamiento 107 00:06:10,600 --> 00:06:13,040 o expresiones de métodos tiene sentido. 108 00:06:13,200 --> 00:06:17,320 Puedes leer un método globalmente sin comprender todos los detalles. 109 00:06:18,040 --> 00:06:21,520 Así que los pequeños métodos son buenos, deberías usarlos en todas partes. 110 00:06:22,400 --> 00:06:24,920 Vamos a seguir. 111 00:06:26,160 --> 00:06:30,240 Aquí vemos que el valor 55 aparece fijo 112 00:06:30,400 --> 00:06:31,800 en el codigo de metodo. 113 00:06:31,960 --> 00:06:36,000 Esto significa que en las subclases no se puede cambiar a 100, por ejemplo. 114 00:06:36,160 --> 00:06:40,480 Entonces extraeremos este valor como hicimos anteriormente, 115 00:06:41,800 --> 00:06:46,600 y lo ponemos en un método separado para que las subclases pueden cambiar el valor. 116 00:06:47,440 --> 00:06:50,120 Otra ventaja es que anteriormente 117 00:06:50,280 --> 00:06:52,520 el valor 55 se escribió aquí. 118 00:06:52,680 --> 00:06:54,720 Ahora se llama self averageRatio. 119 00:06:54,880 --> 00:06:58,560 Esto significa que reemplazamos un valor numérico por un nombre, 120 00:06:58,720 --> 00:07:02,200 y ahora sé a lo que el valor 55 corresponde. 121 00:07:02,360 --> 00:07:07,440 Sé que significa averageRatio y cuando leo el código lo entiendo. 122 00:07:07,600 --> 00:07:11,240 Entonces, teniendo muchos pequeños métodos ayuda a leer el código. 123 00:07:11,680 --> 00:07:14,800 Crear un método averageRatio para retornar 55 124 00:07:14,960 --> 00:07:17,720 habilita a todas las subclases para cambiar valores. 125 00:07:17,880 --> 00:07:21,640 ¿Pero cómo podemos dejar que los usuarios de clase cambien también su valor? 126 00:07:22,000 --> 00:07:23,360 Lo que podemos hacer, 127 00:07:23,520 --> 00:07:25,840 es usar una variable de instancia. 128 00:07:26,640 --> 00:07:30,600 El método averageRatio usado en la diapositiva anterior 129 00:07:30,760 --> 00:07:33,920 devolverá el valor de la variable de instancia, 130 00:07:34,080 --> 00:07:38,480 si contiene un valor. De lo contrario, devuelve el valor predeterminado. 131 00:07:38,800 --> 00:07:40,920 El valor predeterminado era 55. 132 00:07:41,640 --> 00:07:45,120 Y los usuarios de un objeto de nodo 133 00:07:45,280 --> 00:07:48,080 pueden programar cualquier valor que les guste dentro. 134 00:07:48,240 --> 00:07:49,680 Con este diseño, 135 00:07:49,840 --> 00:07:54,520 las subclases pueden sobreescribir defaultAverageRatio 136 00:07:55,000 --> 00:07:56,320 y cambia el valor. 137 00:07:56,480 --> 00:08:01,120 Y los usuarios pueden establecer un valor ejecutando el programa. 138 00:08:01,640 --> 00:08:04,360 Eso se llama programación orientada a gruyere. 139 00:08:05,400 --> 00:08:09,440 Un programa orientado a objetos, un método GANADOR, 140 00:08:09,600 --> 00:08:12,200 contiene agujeros 141 00:08:12,360 --> 00:08:15,960 que se pueden rellenar con subclases. 142 00:08:16,800 --> 00:08:18,320 Como conclusión, 143 00:08:18,480 --> 00:08:22,280 el código puede ser reutilizado y refinado en subclases. 144 00:08:22,440 --> 00:08:25,280 Cada vez que enviamos un mensaje, 145 00:08:25,440 --> 00:08:29,240 las subclases pueden cambiar el comportamiento de la superclase: 146 00:08:29,400 --> 00:08:31,600 Refinarlo o cámbiarlo por completo. 147 00:08:32,560 --> 00:08:37,760 Los métodos pequeños son excelentes porque dan nombres a trozos de expresiones, 148 00:08:38,080 --> 00:08:42,560 y porque dan a las subclases la libertad de cambiar el comportamiento.