¿Es mejor Show () + Hide () o SetVisible (bool visible)?

58

¿Qué es mejor y por qué? (Desde el punto de vista del diseño de la interfaz):

a) Tener dos funciones Show() y Hide()

b) Tener una función SetVisible(bool visible)

EDITAR: por ejemplo, algunos objetos tienen un estado de visibilidad y esta función se usa para cambiarlo.

c) Tener las tres funciones Show() , Hide() , SetVisible(bool visible)

    
pregunta user3123061 20.03.2014 - 17:00

10 respuestas

82

Prefiero SetVisible(bool visible) , porque me permite escribir código de cliente como este:

SetVisible(DetermineIfItShouldBeVisible());

en lugar de tener que escribir

if (DetermineIfItShouldBeVisible()) {
    Show();
} else {
    Hide();
}

El enfoque SetVisible también puede permitir una implementación más sencilla. Por ejemplo, si una clase concreta en particular simplemente delega el método a sus clases compuestas, entonces SetVisible significa un método menos para implementar.

void ButtonWithALabel::SetVisible(bool visible) {
    myButton.SetVisible(visible);
    myLabel.SetVisible(visible);
}
    
respondido por el Josh Kelley 20.03.2014 - 17:09
34

No estoy de acuerdo con todos los carteles, sugiriendo que múltiples funciones para hacer lo mismo es algo bueno. Si bien tres funciones en lugar de una no parecen demasiado infladas, recuerde que es probable que su clase termine con muchas de esas funciones (por ejemplo, setEnabled , enable , disable ) y, por lo tanto, este enfoque terminará con una < em> mucho interfaz de clase más grande. Además, es probable que termines con un montón de funciones / propiedades de sondeo similares en tu clase, y la multiplicación de funciones ocultará aún más cuál va con qué.

En los idiomas que admiten propiedades, estas deberían ser las preferidas, pero como no lo hacen ni Java ni C ++, supongo que es un punto discutible.

Creo que se debería preferir setVisible() por estos motivos:

  1. Es inmediatamente obvio cuál es la función inversa. Para revertir setVisible(false) , usted llama a setVisible(true) , mientras que lo contrario a hide() podría ser reveal() .
  2. Es programáticamente más sencillo cuando estás determinando qué estado debería tomar en el código, es decir, puedes llamar a setVisible(wantToSee) en lugar de usar una declaración if .
  3. Una vez que tenga varias funciones similares, el formato setX() se generaliza para que pueda tener un conjunto de funciones consistentes, mientras que el enfoque comprobado genera una gran cantidad de funciones que pueden ser difíciles de localizar si no sabe lo que está buscando. para. La consistencia en las API hace que sean mucho más fáciles de aprender y recordar.
respondido por el Jack Aidley 21.03.2014 - 00:08
18

Depende de lo que mostrar y ocultar significa en el contexto. Primero, querrá averiguar cuál es su "vía principal" y centrarse en desarrollarla:

  • Razones para elegir setVisible(bool)
    • Es solo un simple cambio de bit, o su objeto es principalmente el estado de espera
    • Su objeto pasará la mayor parte del tiempo en un marco CRUD
    • Hay mucho código fácil de compartir entre mostrar y esconder
  • Razones para elegir show() y hide()
    • Se están ejecutando una gran cantidad de efectos secundarios o mucha lógica, como cuando el objeto tiene que comprobar todos sus contenedores para el estado de visibilidad de su , o activa una animación de transición.
    • ¿Es parte de un modelo de dominio donde es importante expresar intención ?

Bien, ahora que ha codificado el núcleo "estándar de oro", debe averiguar si vale la pena agregar métodos de conveniencia delgados en el otro estilo, para hacer la vida más fácil para quien la use. tu objeto.

  • conveniencia de setVisible(bool)
    • Te permite evitar sentencias if que tienen condiciones triviales y solo afectan la visibilidad (por ejemplo, setVisible(a==b) )
    • Se puede conectar a ciertos marcos getter / setter, si es algo que espera que ocurra
  • Conveniencia de show() y hide()
    • Útil en un idioma con funciones de primera clase y devoluciones de llamada (por ejemplo, onSuccess(widget.show) )
    • Mucho más fácil de leer con trazas de pila y perfiles de rendimiento, ya que puede ver rápidamente lo que el programa estaba tratando de hacer

TLDR: Averigüe cuál es el más importante, aplíquelo y luego pregúntese si vale la pena agregar el otro estilo como métodos de conveniencia.

    
respondido por el Darien 20.03.2014 - 22:10
10

Yo diría "los tres".

Show() y Hide() tienden a ser más fáciles de asimilar que SetVisible(true) y SetVisible(false) . Sin embargo, cuando desea configurar la visibilidad de manera lógica, es mejor tener un método que tome un bool en lugar de construir un if alrededor de ese bool .

Puede admitir los tres sin duplicar la lógica y el mínimo de repetición:

void Show() {
    foo.Show();
    bar.Show();
}

void Hide() {
    foo.Hide();
    bar.Hide();
}

void SetVisible(bool visible) {
    if (visible) {
        Show();
    } else {
        Hide();
    }
}

Alternativamente, si las cosas que estás envolviendo tienen una API SetVisible -ish más:

void Show() {
    SetVisible(true);
}

void Hide() {
    SetVisible(false);
}

void SetVisible(bool visible) {
    foo.SetVisible(visible);
    bar.SetVisible(visible);
}
    
respondido por el Garry Shutler 20.03.2014 - 18:50
4

Prefiero mostrar () y ocultar (), de hecho, todos los métodos que reciben un booleano se pueden cambiar por dos métodos para expresar mejor la intención del API. Por ejemplo, Robert Martin en código limpio recomienda métodos preferidos con cero argumentos sobre métodos con un argumento.

Otro argumento importante para mí es la legibilidad, en mi opinión, un buen código puede leerse como prosa, su prosa realmente extraña algo como "main_window setVisible false" en lugar de "main_window hide", ¿escribes o hablas así normalmente? ¿Por qué? usa esta construcción de lenguaje extraño en programas de software cuando es perfectamente posible usar un lenguaje más natural?

    
respondido por el AlfredoCasado 20.03.2014 - 23:03
4

Creo que cuanto más expresivo sea el método, más legible y, en consecuencia, más fácil será mantener el código. Considere los siguientes dos casos:

Caso 1:

void showCustomerData(customerId){
  Customer customer = getCustomer(CustomerId);
  customerPanel.setVisible(customer.isCustomerEnabled());
}

Caso 2:

void showCustomerData(customerId){
  Customer customer = getCustomer(CustomerId);
  //always show customer panel
  customerPanel.setVisible(true);
}

En el primer caso, está claro qué hace la función "setVisible", pero si quieres leerla, dirías:

  

configura el panel del cliente como visible si el cliente está habilitado o lo configura   a oculto si el cliente está deshabilitado.

Si bien es más descriptivo decirlo:

  
  • verifique el estado del cliente:   
    • si el cliente está habilitado, muestre el panel del cliente
    •   
    • de lo contrario, escóndelo
    •   
  •   

que cambiará la función "Caso 1" a lo siguiente:

void showCustomerData(customerId){
  Customer customer = getCustomer(CustomerId);
  if(customer.isCustomerEnabled()){
    customerPanel.Show();
  }
  else{
    customerPanel.Hide();
  }
}

produce más código, pero es más legible.

El segundo caso tiene un defecto obvio, es que ya sabes que quieres mostrar el panel, ¿por qué no usar la función "Mostrar"?

No estoy diciendo que el uso de "setVisible" sea absolutamente incorrecto, pero se confunde cuando intentas leer el código que no escribiste a lo largo del tiempo y no cumple con la regla "Una función debe realizar solo una operación" .

    
respondido por el OKAN 21.03.2014 - 00:25
4

Creo que la alternativa Hide() / Show() es atractiva porque es más fácil entender lo que está pasando que con SetVisible(true) , mientras que es preferible tener una sola función porque evita muchos condicionales.

Si ese es el caso, sugiero usar una enumeración como entrada para SetVisible , para que obtengas SetVisible(Visibility.Visible) o SetVisible(Visibility.Hidden) . Tiene una sola función que puede leer instantáneamente qué acción se está realizando.

Al utilizar las convenciones de nomenclatura de Java, quizás tengas setVisible(Visibility.VISIBLE) o setVisible(Visibility.HIDDEN) .

    
respondido por el Gabe 23.03.2014 - 06:37
2

Sugeriría una interfaz ligeramente modificada:

Show();
Hide();
ToggleVisible();
ToggleVisible(bool visible);

Mejores nombres

Estos nombres de métodos ayudan al desarrollador a decidir qué método usar en función de lo que se necesita hacer. Mientras que SetVisible(bool visible) puede confundir a un desarrollador porque transmite el mismo significado semántico que Show() y Hide() , Toggle() implica la existencia de una condición que determina la acción. Por lo tanto, se vuelve intuitivo para el desarrollador cuándo usar cada método.

Redundancia de código reducida

El beneficio de tener múltiples métodos en su interfaz es que simplifica el código de llamada. Solo puedes exponer Show() y Hide() , pero:

  • Probablemente necesitarías algún tipo de método SetVisible() privado para hacer el trabajo real entre bambalinas (o escribir código redundante para Show() y Hide() ).
  • El código de llamada puede tener muchos redundantes si / else bloquea solo para elegir qué método usar. Esto infla el código en mi opinión.
  • Si yo fuera el consumidor, es probable que solo escribiera mi propia función de envoltura que hace lo que SetVisible() (o Toggle() ) ya hace para evitar la expansión de código (odio el código redundante). Por lo tanto, la duplicación de un método que probablemente ya existe como un método privado en la implementación.
respondido por el gilly3 21.03.2014 - 18:04
2

Estoy de acuerdo con la respuesta de Darien, pero quería agregar un punto de vista desde la perspectiva de los programadores de C #.

Cuando veo el código que dice 'setXXX', leí que para decir que está estableciendo un valor en una cosa, no espero que esto tenga efectos secundarios en esa cosa que no sea establecer ese valor, y espero que ser idempotente (es decir, puedo seguir configurándolo con el mismo valor y está bien). Es como acceder a un campo. En general, también esperaría ver un método 'getXXX' junto con un 'setXXX'.

No sé si esto es lo que esperas en Java y C ++, pero eso es lo que esperaría en C #, aunque en C # hay una mano corta para esto llamada Propiedades. Y aquí hay una buena guía sobre cómo usar las Propiedades ( enlace ).

Dada esta vista, entonces la interfaz que elegiría depende únicamente de si hay algún efecto secundario (aparte de cambiar el valor del campo):

Si realizar la acción tiene efectos secundarios, por ejemplo, muestra un cuadro de diálogo, entonces iría con "Mostrar ()" y "Ocultar ()".

Si no tiene efectos secundarios, diga que estoy configurando la visibilidad de un "widget" y otra cosa hace que ese widget, dependiendo de su estado, use setVisibility o setIsVisible. (Yo no lo llamaría SetVisible).

En C # (no estoy seguro acerca de Java) es bastante común adoptar un patrón de observador, donde el marco de la interfaz de usuario escuchará los cambios en los objetos y volverá a representar automáticamente la interfaz de usuario cuando cambie una propiedad como Visibility. Eso significa que establecer el valor llamando a setIsVisible aparece como si tuviera efectos secundarios, pero en mi definición no lo tiene. El contrato del widget se cumple estableciendo su valor de campo que representa "IsVisible".

Dicho de otra manera, está bien que alterne la visibilidad de una etiqueta en un formulario antes de que se muestre el formulario. Es decir, label.getIsVisible == true, pero el formulario no se muestra.

No está bien que llame a Ocultar () cuando no se muestra el formulario.

    
respondido por el Daniel James Bryars 22.03.2014 - 06:30
0

Sugeriría usar SetVisible(bool) si lo hubiera solo si alternar la visibilidad dos veces (mostrar y volver a ocultar, o esconder y volver a mostrar) dejaría las cosas prácticamente en el mismo estado que antes de la operación (está bien si mostrar y volver a ocultar algo o viceversa, los objetos que necesitan un redibujado, siempre que se pueda esperar que ocurra "automáticamente"). Si ocultar y mostrar un objeto no tendrá más efecto que cambiar un bit de estado, entonces tendría sentido que el código externo tenga algunos métodos que acepten un parámetro de visibilidad, y la escritura de dicho código se verá facilitada por SetVisible .

Si ocultar y volver a mostrar un objeto puede tener efectos secundarios, como cambiar el orden Z, es más probable que estas acciones se realicen mediante métodos separados. En tales casos, la utilidad de los métodos externos que aceptan un parámetro de "visibilidad" será limitada, y por lo tanto habrá poca ventaja para facilitarlos. Además, el método SetVisible sugerirá (erróneamente) que los cambios en la visibilidad de los objetos se pueden lograr sin efectos secundarios.

    
respondido por el supercat 23.03.2014 - 01:55

Lea otras preguntas en las etiquetas