¿Es mejor llamar a una función que no tiene efecto en ese punto, SI mejora la claridad del código?

60

Tengo tres vistas en mi programa (aplicación iOS). Solo uno de ellos está activo al mismo tiempo, así que configuro la visibilidad para dos de ellos y cambio la visibilidad cuando el usuario presiona los botones. Las vistas se inicializan como visibles, así que configuro la visibilidad en el código antes de que se muestre la vista principal.

puedo hacer

[view1 setAlpha:0.0f];
[view2 setAlpha:0.0f];

para dos de las vistas, pero ahora no se aborda la tercera (la que debería estar visible al inicio de la aplicación). Yo puse un

[view3 setAlpha:1.0f];

después de los dos primeros, porque creo que deja en claro que, de hecho, hay tres puntos de vista, no dos como uno podría pensar al ver el código. ¿Cómo hacen esto otros programadores? ¿Es pura preferencia o hay algunas convenciones?

Si la llamada es muy pesada, obviamente es mejor no llamar cuando eso no sea necesario, pero me preguntaba sobre cosas pequeñas como mi ejemplo.

Kevin
fuente

Respuestas:

134

Tienes un invariante:

Solo una vista única (de 3) está siempre activa (y visible).

Luego, le sugiero que proporcione una función para cambiar la actividad y la visibilidad de TODAS las vistas a la vez:

[setActiveView viewID:2]

Esta función:

  • comprobar si la vista ya está activa, evitando trabajos innecesarios
  • establecer la vista como activa y visible
  • establecer las otras 2 vistas como inactivas e invisibles

Tiene múltiples ventajas sobre una llamada sin procesar a setVisibility:

  • amigable: llamarlo innecesariamente no crea un problema de rendimiento
  • defensivo: su único parámetro es mucho más difícil de alterar, mientras setVisibilityque es más difícil recordar que el rango de valores es 0.0f - 1.0fy que solo uno debe establecerse en1.0f
  • resistente: el siguiente tipo no puede olvidar accidentalmente una de las vistas
  • adaptable: agregar / eliminar una vista no requiere examinar todo el código de la aplicación para encontrar dónde están los interruptores, una sola función (esta) necesita ser actualizada

Idealmente, para ayudar a hacer cumplir la invariante, ninguna otra función debería ser capaz de alterar esta configuración ...

Matthieu M.
fuente
Gran sugerencia Voy a hacer esto con mi ejemplo actual. Pero, ¿qué pasa cuando tal diseño no es posible / deseado? ¿O decides en el acto cuál es la mejor manera de manejarlo?
Kevin
44
@ Kevin: Depende realmente. A veces puede resolver el problema iterando sobre una colección, a veces no, pero el principio clave es evitar la duplicación y facilitar la preservación de los invariantes. Cuantas más acciones "manuales" deban recordarse para que las cosas funcionen correctamente, menos posibilidades tiene de que las cosas funcionen correctamente. Odio ser vago aquí, pero hay tantas situaciones diferentes que me temo que una regla "genérica" ​​simplemente te llevará por mal camino.
Matthieu M.
23
"facilitar la preservación de invariantes" es una regla genérica que vale la pena recordar.
Gusdor
1
@Tonny: No sé si alentar el uso de una variable global es "hacerlo bien", pero de hecho si sabes exactamente qué estaba activo antes, solo necesitas actualizar dos vistas. Otra solución es que cada vista recuerde su visibilidad y que setVisibilityno haga nada si la visibilidad ya es la solicitada, lo que reduce la responsabilidad.
Matthieu M.
1
@MatthieuM. Escribí a toda prisa, pero en realidad es lo que quise decir también. Si conoce el estado anterior, solo necesita actualizar 2 vistas como máximo. Cómo recordar ese estado es otro asunto ;-). En cuanto a mover la responsabilidad hacia abajo: si la clase de vista no proporciona eso, deberá envolver la clase en otro objeto solo para agregar esa propiedad. Esa es una solución limpia, pero tal vez un poco exagerada.
Tonny
12

Idea alternativa: si su objetivo es evitar que ocurran errores porque las personas olvidan que hay tres puntos de vista y hacen algo con solo dos de ellos que realmente deberían hacer con todos ellos, entonces hagan una función que haga imposible olvidar:

setViewVisibilities(0.0f, 0.0f, 1.0f)

Ahora tiene algo mucho más poderoso: el tiempo de compilación garantiza que no lo ha olvidado . Si olvida un parámetro, el compilador le gritará. Esto es mucho más útil que los comentarios o el código innecesario, ya que crea un protocolo con nombre estricto que hace cumplir la propiedad que le interesa.

Para el caso en que view3no necesita que haya cambiado la visibilidad, se puede añadir un poco de comportamiento, donde pasa un valor especial como -1.0o nil, o algo por el estilo significa "no cambiar la vista de la visibilidad en absoluto". Esto evita el problema de establecer visibilidades innecesariamente.

Jack
fuente
99
Si OP obtiene hasta más de 10 vistas, será imposible mantener un parámetro por vista. Su punto sobre los errores en tiempo de compilación es correcto, pero desafortunadamente esta es una solución muy difícil de mantener.
Chris Cirefice
3
@ChrisCirefice: si aumenta el número de vistas, puede crear algún tipo de objeto / clase "ViewState", que refuerza esta invariante. Luego use eso para cambiar, etc. Con tantas vistas, algún tipo de objeto administrador probablemente tenga sentido de todos modos.
sleske
8

Creo que agregar un comentario explicando que la llamada no es necesaria (y por qué) es lo mejor.

(tal vez, el hecho de que una llamada no sea necesaria, o que necesite un comentario al respecto, podría ser un olor a código)

Basile Starynkevitch
fuente
1
@Niall Si es posible, una afirmación sería incluso mejor que un comentario.
200_success
99
Los comentarios no son la solución para el código
inmanejable
2
@Kevin o podrías escribir código que sea perfectamente legible sin comentarios.
Jan
1
@Jan Los comentarios son más que simplemente explicar lo que hace el código .......
Kevin
2
@Kevin Yo diría que los comentarios nunca deberían existir para explicar lo que hace el código, sino para explicar por qué lo está haciendo. Y en tales situaciones, a menudo un refactor logrará la intención sin necesitar el comentario (que suena como el punto de Jan).
RJFalconer
4

En este caso particular, @Mattieu M. tiene la solución correcta.

En el caso más general, donde no hay una transformación similar, tienes que preguntarte: ¿hay alguna posibilidad de que un futuro programador pueda estropear esto?

La respuesta suele ser sí. Lo que significa que sí, debe agregar la llamada. Tal vez alguna versión futura del marco comience con todas las vistas DESACTIVADAS en lugar de ACTIVADAS.

Stig Hemmer
fuente