if statement - and - Refactorización de cadenas if en Smalltalk sin explosión de clase
conditionals smalltalk (4)
Como Smalltalk desalienta el uso de caseOf :, ¿qué alternativas existen para implementar la siguiente situación sin explosión de clases?
self condition1
ifTrue: [ self actionForCondition1 ]
ifFalse: [
self condition2
ifTrue: [ self actionForCondition2 ]
ifFalse: [
self condition3
ifTrue: [ self actionForCondition3 ]
ifFalse: [ .... ] ] ]
Si te desplazas hacia casi el final de
http://www.desk.org:8080/CampSmalltalk/control%20flow
encontrarás la oración
"Hay cuatro formas de expresar una declaración de caso en Smalltalk".
seguido por enlaces a ejemplos.
El texto se encuentra en el medio de una serie de páginas ligeramente más largas y hace referencias ocasionales al tutor hipotético y a los estudiantes en un curso de Smalltalk con fines de ilustración; puedes ignorar eso para los propósitos de tu pregunta)
Depende de cómo se ven exactamente tus condiciones?
Si sus condiciones son pruebas de tipo
anObject isKindOf: aClass
puede enviar en la clase, eso significa que llama a un método de acción en un
anObject
.Si sus condiciones son pruebas de igualdad
anObject = anotherObject
puede usar un diccionario con el objeto como clave y la acción como un bloqueo de bloque.
Como último restablecimiento y si nada más lo ayuda, es posible que desee volver a escribir el código propuesto para evitar el anidamiento innecesario:
self condition1 ifTrue: [ ^ self actionForCondition1 ]. self condition2 ifTrue: [ ^ self actionForCondition2 ]. self condition3 ifTrue: [ ^ self actionForCondition3 ]. ...
Creo que, en el momento en que tenga que escribir este código, me preguntaría por qué tengo que escribir tantas condiciones para seguir adelante con un solo paso en mi algoritmo. Tal vez es hora de pensar qué le pasa a la modelo? Especialmente, si considera que una semántica de búsqueda de mensaje es en realidad una declaración de caso:
selector = selector1 ifTrue: [ invoke method1 ]
ifFalse: [ selector= selector2 ifTrue: [ invoke method2 ]
ifFalse: [...] ]]].
Por lo tanto, debe intentar convertir esto en su ventaja: use la declaración de cambio de VM en lugar de escribir propia.
Al aplicar un principio simple: no preguntar (el objeto es Algo si es Verdadero: [autohacerAlgo)] pero decir (objeta hacer Algo), puedes evitar tener muchas ramas en el código. Por supuesto, a veces no es aplicable y depende en gran medida de la situación, pero a menudo prefiero tener envío de mensajes adicionales, en lugar de otra rama en el código.
Deberías echarle un vistazo al despacho doble . Dependiendo de cómo se implementen las pruebas y las acciones, es posible que pueda utilizar el doble despacho con gran ventaja.
Desea terminar con un código que se parece a lo siguiente:
auto conditionAction performAction.
o
self conditinAction performAction: actionArgs
El método #conditionAction tendría que devolver una instancia única de un objeto para cada condición única (sin usar declaraciones de casos en sí :).
No querrá forzar el problema creando clases solo para evitar "declaraciones de casos", pero en el mundo real puede que ya tenga algunas clases únicas que puede aprovechar.