1 00:00:07,120 --> 00:00:12,760 Hola. Durante este curso, principalmente hablaremos de concepción orientada a objetos 2 00:00:13,480 --> 00:00:17,320 y aprenderemos sobre la esencia del (dispatch) 3 00:00:17,480 --> 00:00:20,560 y de la evaluación perezosa (late binding) en lenguajes orientados a objetos. 4 00:00:20,720 --> 00:00:24,880 Entonces, este curso usa a Pharo como ejemplo. 5 00:00:25,040 --> 00:00:27,880 Está bien que Pharo haya estado bien implementado 6 00:00:28,040 --> 00:00:32,040 En la próxima clase, hablaremos sobre sus muchas posibilidades de generalización. 7 00:00:32,200 --> 00:00:33,960 Vamos a empezar. 8 00:00:34,720 --> 00:00:36,160 Echemos un vistazo a los booleanos. 9 00:00:37,520 --> 00:00:38,680 Booleanos en Pharo 10 00:00:38,840 --> 00:00:42,920 son de hecho las cosas más básicas. 11 00:00:43,080 --> 00:00:47,720 Operadores como &, |, not, (eager) 12 00:00:47,880 --> 00:00:52,040 operadores como or:, and:, (lazy) con evaluación de argumentos cuando sea necesario, 13 00:00:52,200 --> 00:00:57,320 también los condicionales que veremos en otro curso. 14 00:00:57,480 --> 00:01:02,600 Entonces está bien implementado pero no hay nada fantástico ni específico 15 00:01:02,760 --> 00:01:05,920 La semana pasada, le pedí realizar algunos ejercicios 16 00:01:06,080 --> 00:01:07,920 Hubo tres preguntas. 17 00:01:08,080 --> 00:01:10,400 Cómo implementar Not, 18 00:01:10,560 --> 00:01:12,000 cómo implementar Or, 19 00:01:12,160 --> 00:01:15,760 y la mas importante: ¿Cuál es el objetivo de estos ejercicios? 20 00:01:16,560 --> 00:01:20,400 Responderé a las dos primeras preguntas; y en el próximo curso, 21 00:01:20,560 --> 00:01:24,000 responderé a la última pregunta. 22 00:01:25,880 --> 00:01:28,080 El ejercicio realmente es ... 23 00:01:28,240 --> 00:01:32,560 Si envía el mensaje not a false, volverá a ser true. 24 00:01:32,720 --> 00:01:35,240 Si envia el mensaje not a true, devolverá false. 25 00:01:35,400 --> 00:01:38,600 Mediante objetos ¿Cómo se implementa esto? 26 00:01:38,760 --> 00:01:41,000 Primero le daré algunos consejos. 27 00:01:41,160 --> 00:01:43,720 La solución no usa condicionales. 28 00:01:44,280 --> 00:01:46,960 En general encuentra una solución utilizando una condición 29 00:01:47,120 --> 00:01:50,960 Pero le digo que mi solución, implementada por Pharo, 30 00:01:51,120 --> 00:01:53,440 no contiene ninguna condición 31 00:01:54,600 --> 00:01:55,960 ni condicionales. 32 00:01:56,120 --> 00:01:58,640 Entonces no se utiliza if en la solución. 33 00:02:00,600 --> 00:02:04,800 Piense un poco para ver si tiene alguna idea. 34 00:02:04,960 --> 00:02:09,960 Normalmente, este tipo de sugerencia realmente no funciona. 35 00:02:10,120 --> 00:02:13,840 La segunda pista: La solución usa tres clases. 36 00:02:14,360 --> 00:02:17,240 Tiene la clase Boolean 37 00:02:17,400 --> 00:02:19,440 que es abstracta. 38 00:02:19,600 --> 00:02:22,760 Tiene la clase True y la clase False. 39 00:02:22,920 --> 00:02:28,400 El objeto booleano true es la única instancia de True. 40 00:02:28,560 --> 00:02:30,480 ¿Ve la diferencia? 41 00:02:31,040 --> 00:02:35,200 La instancia true comienza con una minúscula 42 00:02:35,360 --> 00:02:40,920 y la clase False comienza con una mayúscula F. 43 00:02:41,080 --> 00:02:44,000 Y false es la única instancia (singleton) de False 44 00:02:44,160 --> 00:02:46,200 Si lo visualizamos en un diagrama, 45 00:02:46,360 --> 00:02:50,160 podemos ver true es instancia de True, y false de False. 46 00:02:50,320 --> 00:02:55,000 En teoría, con esta pista, la solución debería ser obvia. 47 00:02:55,160 --> 00:02:57,520 No estoy seguro de que pueda verlo. 48 00:02:57,680 --> 00:03:00,520 Le dejaré pensar más al respecto. 49 00:03:00,680 --> 00:03:03,520 La solución al final ... 50 00:03:04,720 --> 00:03:07,600 No se lo diré en este momento ... Vamos a pensarlo. 51 00:03:07,760 --> 00:03:11,320 ¿Cómo expresamos una elección? en los lenguajes orientados a objetos? 52 00:03:12,400 --> 00:03:14,920 Una opción se expresa definiendo clases 53 00:03:15,080 --> 00:03:18,920 con interfaces compatibles, es decir, métodos, 54 00:03:19,080 --> 00:03:21,360 y enviando un mensaje a una instancia. 55 00:03:21,520 --> 00:03:25,720 Ese es mi ejemplo Cuando escribo x abrir, 56 00:03:27,240 --> 00:03:29,920 Elijo el método correcto asociado con x. 57 00:03:30,080 --> 00:03:33,720 Significa que si es un archivo, se abrirá un archivo; si es una ventana, una ventana; 58 00:03:33,880 --> 00:03:35,720 si es una herramienta, una herramienta 59 00:03:35,880 --> 00:03:40,800 Entonces se seleccionará el método basado en la clase de x. 60 00:03:41,800 --> 00:03:46,520 Entonces, ¿cómo encontramos la solución? con esta sugerencia 61 00:03:48,400 --> 00:03:50,280 Lo implementaremos así. 62 00:03:51,400 --> 00:03:56,320 Significa que implemento el método not en la clase False; 63 00:03:56,480 --> 00:03:58,560 en este caso, devolverá true. 64 00:03:58,720 --> 00:04:03,480 Implemento el método not en la clase True; devolverá false 65 00:04:04,440 --> 00:04:06,440 En un diagrama, se ve así. 66 00:04:08,200 --> 00:04:11,840 Puede ver que esta solución no tiene condiciones explícitas 67 00:04:12,000 --> 00:04:14,760 No uso ningún if en este caso. 68 00:04:14,920 --> 00:04:16,200 ¿Como funciona? 69 00:04:17,040 --> 00:04:20,160 Funciona así. Cuando envío el mensaje not, 70 00:04:21,520 --> 00:04:25,600 ¿Dónde busco el método? Lo busco en la clase receptora. 71 00:04:25,760 --> 00:04:27,640 true es instancia de True. 72 00:04:27,800 --> 00:04:30,640 Entonces este método se ejecutará aquí, 73 00:04:30,800 --> 00:04:33,400 y el resultado será false. Funciona. 74 00:04:33,560 --> 00:04:37,640 Ahora envío un mensaje a la instancia false 75 00:04:37,800 --> 00:04:40,040 ¿Dónde me veo? En la clase False. 76 00:04:40,200 --> 00:04:42,760 Esto no se ejecuta, y vuelve true. 77 00:04:42,920 --> 00:04:46,760 He implementado mis booleanos, 78 00:04:46,920 --> 00:04:49,680 la negación booleana con dos métodos 79 00:04:51,560 --> 00:04:53,640 sin el uso de condicionales. 80 00:04:54,960 --> 00:04:58,800 También podemos ver la implementación de la superclase 81 00:04:58,960 --> 00:05:00,840 La clase booleana es abstracta. 82 00:05:01,000 --> 00:05:04,720 Tiene dos subclases que implementan los operadores necesarios. 83 00:05:04,880 --> 00:05:06,600 En Pharo, 84 00:05:06,760 --> 00:05:10,080 not expresa un método abstracto en Boolean 85 00:05:10,240 --> 00:05:13,040 mediante el uso de self subclassResponsibility. 86 00:05:13,200 --> 00:05:17,440 Solo quería contarle sobre Pharo para ser completo 87 00:05:18,400 --> 00:05:21,000 Por ahora, debe haber entendido 88 00:05:21,160 --> 00:05:23,520 cómo expresar el comportamiento de Or. 89 00:05:23,680 --> 00:05:25,960 Le daré tiempo para expresar esto. 90 00:05:26,120 --> 00:05:28,560 La idea aquí es definir un método 91 00:05:28,720 --> 00:05:31,280 que utilizará un argumento adicional. 92 00:05:31,440 --> 00:05:33,560 Dependiendo de su valor, 93 00:05:33,720 --> 00:05:37,240 Le seguirá el resultado correcto. 94 00:05:38,000 --> 00:05:41,240 A menudo piensa que con usar una condición es suficiente: 95 00:05:41,400 --> 00:05:42,720 No. Eso es lo que pasa. 96 00:05:42,880 --> 00:05:47,360 Una vez más, no necesita condicionales para implementar Or. 97 00:05:47,520 --> 00:05:51,280 Le daré 10 segundos para pensar en ello 98 00:05:51,440 --> 00:05:54,160 Se suponía que debia haber preparado esto. 99 00:05:55,720 --> 00:05:58,960 Definiré or en la clase Boolean abstracta 100 00:05:59,120 --> 00:06:01,640 como un método abstracto. Muy bien. 101 00:06:02,800 --> 00:06:06,800 Luego en la clase False: lo puede ver 102 00:06:06,960 --> 00:06:10,280 El receptor pertenece a False. Que devuelvo 103 00:06:11,240 --> 00:06:15,600 Cuando es true devuelve true, cuando es false devuelve false, cuando es cualquier cosa devuelve cualquier cosa. 104 00:06:15,760 --> 00:06:17,880 Entonces, significa que devuelve el argumento. 105 00:06:18,600 --> 00:06:22,840 Entonces, aquí, la implementación de Or en la clase False 106 00:06:23,000 --> 00:06:25,400 se trata de devolver el argumento. 107 00:06:25,560 --> 00:06:27,240 Eso es exactamente lo que hicimos. 108 00:06:29,320 --> 00:06:30,600 Igualmente, 109 00:06:31,960 --> 00:06:34,720 si miramos la clase True, se explica 110 00:06:37,200 --> 00:06:38,800 Se explica aquí. 111 00:06:38,960 --> 00:06:43,640 Cuando envío or al receptor true, 112 00:06:43,800 --> 00:06:45,360 Devuelvo el receptor. 113 00:06:45,520 --> 00:06:46,840 Entonces retorno true. 114 00:06:48,360 --> 00:06:51,440 Como puede ver aquí, nuevamente, no uso condicionales, 115 00:06:51,600 --> 00:06:53,240 acabo de usar mensajes de mensajes. 116 00:06:55,000 --> 00:06:59,240 Entonces, de una manera más limpia, ¿Cómo está escrito en Pharo? 117 00:06:59,400 --> 00:07:03,480 Sabemos que true es el receptor del mensaje; 118 00:07:03,640 --> 00:07:06,200 así que en lugar de escribir true, podemos escribir self. 119 00:07:06,360 --> 00:07:09,680 Si lee la definición, puede ver self y decir: 120 00:07:09,840 --> 00:07:12,480 que tiene sentido. Como el receptor es true, 121 00:07:12,640 --> 00:07:15,800 es exactamente lo mismo. 122 00:07:18,680 --> 00:07:21,560 Una vez más, vamos a visualizarlo. 123 00:07:21,720 --> 00:07:26,960 Cuando envío el mensaje or con algo 124 00:07:27,120 --> 00:07:29,400 al objeto true, 125 00:07:29,560 --> 00:07:33,080 busco esta definición de or aquí, 126 00:07:33,240 --> 00:07:35,680 y volverá self, por lo tanto, true. 127 00:07:35,840 --> 00:07:39,720 Cuando envío el mensaje or con algo, 128 00:07:39,880 --> 00:07:42,640 busco en la clase False que es false 129 00:07:42,800 --> 00:07:47,280 Entonces termino con esta implementación, y devuelvo alpha. 130 00:07:47,440 --> 00:07:51,040 Es la tabla booleana que estaba intentando implementar. 131 00:07:53,440 --> 00:07:55,360 Lo que tiene que recordar es: 132 00:07:55,520 --> 00:07:59,480 la solución que hemos implementado no usa ningún condicional 133 00:08:00,160 --> 00:08:03,120 o cualquier instrucción condicional 134 00:08:03,280 --> 00:08:05,640 tal como un bucle explícito; 135 00:08:05,800 --> 00:08:08,480 deje que el receptor decida. 136 00:08:08,640 --> 00:08:12,400 Significa que le digo al objeto booleano que recibe el mensaje 137 00:08:12,560 --> 00:08:14,680 para encontrar la solución correcta 138 00:08:14,840 --> 00:08:18,920 No estoy aqui para dictar lo que hay que decidir 139 00:08:19,080 --> 00:08:21,480 Este principio se encuentra también en otros lugares. 140 00:08:21,640 --> 00:08:24,520 Es un principio fundamental de la OOP. 141 00:08:24,680 --> 00:08:28,560 Es la heurística que mencioné Al comienzo de esta lección: 142 00:08:28,720 --> 00:08:30,160 No preguntar, contar. 143 00:08:30,320 --> 00:08:33,400 Significa que no quiero expresar cualquier condicional; 144 00:08:33,560 --> 00:08:35,240 Solo quiero dar una orden. 145 00:08:35,400 --> 00:08:39,680 Esa es una de las claves importantes de OOP. 146 00:08:39,840 --> 00:08:42,640 La otra es dejar que el receptor decida. 147 00:08:42,800 --> 00:08:46,760 Le doy una orden al receptor: quien debe encapsular su conocimiento 148 00:08:46,920 --> 00:08:48,840 y tomar las decisiones correctas.