Hola. Durante este curso, principalmente hablaremos de concepción orientada a objetos
y aprenderemos sobre la esencia del (dispatch)
y de la evaluación perezosa (late binding) en lenguajes orientados a objetos.
Entonces, este curso usa a Pharo como ejemplo.
Está bien que Pharo haya estado bien implementado
En la próxima clase, hablaremos sobre sus muchas posibilidades de generalización.
Vamos a empezar.
Echemos un vistazo a los booleanos.
Booleanos en Pharo
son de hecho las cosas más básicas.
Operadores como &, |, not, (eager)
operadores como or:, and:, (lazy) con evaluación de argumentos cuando sea necesario,
también los condicionales que veremos en otro curso.
Entonces está bien implementado pero no hay nada fantástico ni específico
La semana pasada, le pedí realizar algunos ejercicios
Hubo tres preguntas.
Cómo implementar Not,
cómo implementar Or,
y la mas importante: ¿Cuál es el objetivo de estos ejercicios?
Responderé a las dos primeras preguntas; y en el próximo curso,
responderé a la última pregunta.
El ejercicio realmente es ...
Si envía el mensaje not a false, volverá a ser true.
Si envia el mensaje not a true, devolverá false.
Mediante objetos ¿Cómo se implementa esto?
Primero le daré algunos consejos.
La solución no usa condicionales.
En general encuentra una solución utilizando una condición
Pero le digo que mi solución, implementada por Pharo,
no contiene ninguna condición
ni condicionales.
Entonces no se utiliza if en la solución.
Piense un poco para ver si tiene alguna idea.
Normalmente, este tipo de sugerencia realmente no funciona.
La segunda pista: La solución usa tres clases.
Tiene la clase Boolean
que es abstracta.
Tiene la clase True y la clase False.
El objeto booleano true es la única instancia de True.
¿Ve la diferencia?
La instancia true comienza con una minúscula
y la clase False comienza con una mayúscula F.
Y false es la única instancia (singleton) de False
Si lo visualizamos en un diagrama,
podemos ver true es instancia de True, y false de False.
En teoría, con esta pista, la solución debería ser obvia.
No estoy seguro de que pueda verlo.
Le dejaré pensar más al respecto.
La solución al final ...
No se lo diré en este momento ... Vamos a pensarlo.
¿Cómo expresamos una elección? en los lenguajes orientados a objetos?
Una opción se expresa definiendo clases
con interfaces compatibles, es decir, métodos,
y enviando un mensaje a una instancia.
Ese es mi ejemplo Cuando escribo x abrir,
Elijo el método correcto asociado con x.
Significa que si es un archivo, se abrirá un archivo; si es una ventana, una ventana;
si es una herramienta, una herramienta
Entonces se seleccionará el método basado en la clase de x.
Entonces, ¿cómo encontramos la solución? con esta sugerencia
Lo implementaremos así.
Significa que implemento el método not en la clase False;
en este caso, devolverá true.
Implemento el método not en la clase True; devolverá false
En un diagrama, se ve así.
Puede ver que esta solución no tiene condiciones explícitas
No uso ningún if en este caso.
¿Como funciona?
Funciona así. Cuando envío el mensaje not,
¿Dónde busco el método? Lo busco en la clase receptora.
true es instancia de True.
Entonces este método se ejecutará aquí,
y el resultado será false. Funciona.
Ahora envío un mensaje a la instancia false
¿Dónde me veo? En la clase False.
Esto no se ejecuta, y vuelve true.
He implementado mis booleanos,
la negación booleana con dos métodos
sin el uso de condicionales.
También podemos ver la implementación de la superclase
La clase booleana es abstracta.
Tiene dos subclases que implementan los operadores necesarios.
En Pharo,
not expresa un método abstracto en Boolean
mediante el uso de self subclassResponsibility.
Solo quería contarle sobre Pharo para ser completo
Por ahora, debe haber entendido
cómo expresar el comportamiento de Or.
Le daré tiempo para expresar esto.
La idea aquí es definir un método
que utilizará un argumento adicional.
Dependiendo de su valor,
Le seguirá el resultado correcto.
A menudo piensa que con usar una condición es suficiente:
No. Eso es lo que pasa.
Una vez más, no necesita condicionales para implementar Or.
Le daré 10 segundos para pensar en ello
Se suponía que debia haber preparado esto.
Definiré or en la clase Boolean abstracta
como un método abstracto. Muy bien.
Luego en la clase False: lo puede ver
El receptor pertenece a False. Que devuelvo
Cuando es true devuelve true, cuando es false devuelve false, cuando es cualquier cosa devuelve cualquier cosa.
Entonces, significa que devuelve el argumento.
Entonces, aquí, la implementación de Or en la clase False
se trata de devolver el argumento.
Eso es exactamente lo que hicimos.
Igualmente,
si miramos la clase True, se explica
Se explica aquí.
Cuando envío or al receptor true,
Devuelvo el receptor.
Entonces retorno true.
Como puede ver aquí, nuevamente, no uso condicionales,
acabo de usar mensajes de mensajes.
Entonces, de una manera más limpia, ¿Cómo está escrito en Pharo?
Sabemos que true es el receptor del mensaje;
así que en lugar de escribir true, podemos escribir self.
Si lee la definición, puede ver self y decir:
que tiene sentido. Como el receptor es true,
es exactamente lo mismo.
Una vez más, vamos a visualizarlo.
Cuando envío el mensaje or con algo
al objeto true,
busco esta definición de or aquí,
y volverá self, por lo tanto, true.
Cuando envío el mensaje or con algo,
busco en la clase False que es false
Entonces termino con esta implementación, y devuelvo alpha.
Es la tabla booleana que estaba intentando implementar.
Lo que tiene que recordar es:
la solución que hemos implementado no usa ningún condicional
o cualquier instrucción condicional
tal como un bucle explícito;
deje que el receptor decida.
Significa que le digo al objeto booleano que recibe el mensaje
para encontrar la solución correcta
No estoy aqui para dictar lo que hay que decidir
Este principio se encuentra también en otros lugares.
Es un principio fundamental de la OOP.
Es la heurística que mencioné Al comienzo de esta lección:
No preguntar, contar.
Significa que no quiero expresar cualquier condicional;
Solo quiero dar una orden.
Esa es una de las claves importantes de OOP.
La otra es dejar que el receptor decida.
Le doy una orden al receptor: quien debe encapsular su conocimiento
y tomar las decisiones correctas.