web-dev-qa-db-fra.com

Est-ce mieux Show () + Hide () ou SetVisible (bool visible)?

Quoi de mieux et pourquoi? (Du point de vue de la conception de l'interface):

a) Pour avoir deux fonctions Show() et Hide()

b) Pour avoir une fonction SetVisible(bool visible)

EDIT: Par exemple, certains objets ont un état de visibilité et cette fonction est utilisée pour le changer.

c) Pour avoir les trois fonctions Show(), Hide(), SetVisible(bool visible)

59
user3123061

Je préfère SetVisible(bool visible), car cela me permet d'écrire du code client comme ceci:

SetVisible(DetermineIfItShouldBeVisible());

au lieu d'avoir à écrire

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

L'approche SetVisible peut également permettre une implémentation plus facile. Par exemple, si une classe concrète particulière délègue simplement la méthode à ses classes composites, alors SetVisible signifie une méthode de moins à implémenter.

void ButtonWithALabel::SetVisible(bool visible) {
    myButton.SetVisible(visible);
    myLabel.SetVisible(visible);
}
81
Josh Kelley

Je suis en désaccord avec toutes les affiches suggérant que plusieurs fonctions pour faire la même chose sont une bonne chose. Bien que trois fonctions au lieu d'une ne semblent pas trop lourdes, n'oubliez pas que votre classe risque de se retrouver avec de nombreuses fonctions de ce type (par exemple setEnabled, enable, disable) et ainsi cette approche se terminera avec une interface de classe beaucoup plus grande. De plus, il est probable que vous vous retrouviez avec un tas de fonctions/propriétés/quoi que ce soit dans votre classe et la multiplication des fonctions obscurcira davantage celle qui va avec quoi.

Dans les langages qui prennent en charge les propriétés, celles-ci devraient être préférées, mais comme ni Java ni C++ ne le font, je suppose que c'est un point discutable.

Je pense que setVisible() devrait être préféré pour ces raisons:

  1. Il est immédiatement évident quelle est la fonction inverse. Pour inverser setVisible(false) vous appelez setVisible(true) alors que l'opposé de hide() pourrait facilement être reveal().
  2. C'est plus simple par programmation chaque fois que vous déterminez quel état il doit prendre dans le code, c'est-à-dire que vous pouvez appeler setVisible(wantToSee) plutôt que d'utiliser une instruction if.
  3. Une fois que vous avez plusieurs fonctions similaires, le format setX() se généralise afin que vous puissiez avoir un ensemble de fonctions cohérentes tandis que l'approche verbée génère une multitude de fonctions qui peuvent être difficiles à localiser si vous ne savez pas ce que vous êtes à la recherche de. La cohérence des API les rend beaucoup plus faciles à apprendre et à mémoriser.
35
Jack Aidley

Cela dépend de ce que montrer et cacher signifie dans le contexte. Vous voulez d'abord déterminer laquelle est votre "voie principale" et vous concentrer sur son développement:

  • Raisons de choisir setVisible(bool)
    • C'est juste un simple retournement de bits, ou votre objet est principalement en état de maintien
    • Votre objet va passer la plupart de son temps dans un cadre CRUD
    • Il y a beaucoup de code facilement partagé entre l'affichage et le masquage
  • Raisons de choisir show() et hide()
    • Il y a des effets secondaires importants ou beaucoup de logique en cours d'exécution, comme lorsque l'objet doit vérifier tous ses conteneurs pour leur état de visibilité , ou déclenche une animation de transition.
    • Fait-il partie d'un modèle de domaine où l'expression de l'intention est importante

OK, maintenant que vous en avez codé le noyau "étalon-or", vous devez déterminer s'il vaut la peine d'ajouter des méthodes de commodité minces dans l'autre style, pour rendre la vie plus facile à quiconque va utiliser votre objet.

  • Commodité de setVisible(bool)
    • Vous permet d'éviter les instructions if qui ont des conditions triviales et n'affectent que la visibilité (ex. setVisible(a==b))
    • Peut être connecté à certains frameworks getter/setter, si c'est quelque chose que vous attendez
  • Commodité de show() et hide()
    • Utile dans une langue avec des fonctions et des rappels de première classe (ex. onSuccess(widget.show))
    • Beaucoup plus facile à lire avec les traces de pile et le profilage des performances, car vous pouvez voir rapidement ce que le programme essayait de faire

TLDR: Découvrez lequel est le plus important, implémentez-le, puis demandez-vous s'il vaut la peine d'ajouter l'autre style comme méthode de commodité fine.

19
Darien

Je dirais "les trois".

Show() et Hide() ont tendance à être plus faciles à grogner que SetVisible(true) et SetVisible(false). Cependant, lorsque vous souhaitez définir la visibilité de manière logique, il est préférable d'avoir une méthode prenant un bool plutôt que de construire un if autour de ce bool.

Vous pouvez prendre en charge les trois sans dupliquer la logique et le passe-partout minimal:

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

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

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

Alternativement, si les choses que vous enveloppez ont une API plus SetVisible- ish:

void Show() {
    SetVisible(true);
}

void Hide() {
    SetVisible(false);
}

void SetVisible(bool visible) {
    foo.SetVisible(visible);
    bar.SetVisible(visible);
}
12
Garry Shutler

Je crois que l'alternative Hide()/Show() est intéressante car il est plus facile de comprendre ce qui se passe qu'avec SetVisible(true), alors qu'une seule fonction est préférable car elle évite beaucoup de conditionnels.

Si c'est le cas, je suggère d'utiliser une énumération comme entrée de SetVisible, donc vous obtenez soit SetVisible(Visibility.Visible) ou SetVisible(Visibility.Hidden). Vous avez une seule fonction, vous pouvez lire instantanément quelles mesures sont prises.

En utilisant les conventions de dénomination de Java, vous auriez peut-être setVisible(Visibility.VISIBLE) ou setVisible(Visibility.HIDDEN).

5
Gabe

Je préfère afficher () et cacher (), en fait, chaque méthode qui reçoit un booléen peut être modifiée pour deux méthodes qui expriment mieux l'intention de l'API. Par exemple, Robert Martin dans un code propre recommande de préférer les méthodes avec zéro argument aux méthodes avec un argument.

Un autre argument important pour moi est la lisibilité, à mon avis, un bon code peut être lu comme de la prose, sa prose vraiment étrange quelque chose comme "main_window setVisible false" au lieu de "main_window hide", vous écrivez ou parlez comme ça normalement?, Pourquoi utiliser cette étrange construction du langage dans les logiciels quand est-il parfaitement possible d'utiliser un langage plus naturel?.

5
AlfredoCasado

Je crois que plus la méthode est expressive, plus le code sera lisible et, par conséquent, maintenable. Considérez les deux cas suivants:

Cas 1:

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

Cas 2:

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

Dans le premier cas, la fonction "setVisible" est claire, mais si vous voulez la lire, vous diriez:

définissez le panneau client sur visible si le client est activé ou définissez-le sur caché si le client est désactivé.

Bien qu'il soit plus descriptif de dire:

  • vérifier le statut du client:
    • si le client est activé, affichez le panneau du client
    • sinon, cache-le

ce qui changera la fonction "Cas 1" en ce qui suit:

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

il produit plus de code, mais est plus lisible.

Le deuxième cas a un défaut évident, c'est que vous savez déjà que vous voulez afficher le panneau, alors pourquoi ne pas utiliser la fonction "Afficher"?

Je ne dis pas que l'utilisation de "setVisible" est absolument erronée, mais cela devient déroutant lorsque vous essayez de lire du code non écrit par vous au fil du temps, et il n'est pas conforme à la règle "Une fonction ne doit effectuer qu'une seule opération".

5
OKAN

Je suis d'accord avec la réponse de Darien, mais je voulais ajouter un point de vue du point de vue des programmeurs C #.

Quand je vois du code qui dit "setXXX", je lis cela pour dire qu'il définit une valeur sur une chose, je ne m'attends pas à ce que cela ait des effets secondaires dans cette chose autre que la définition de cette valeur, et je m'attends à ce que ce soit idempotent (c'est-à-dire que je peux continuer à le régler avec la même valeur et ça va). C'est un peu comme accéder à un champ. En général, je m'attendrais également à voir une méthode "getXXX" avec un "setXXX".

Je ne sais pas si c'est ce à quoi vous vous attendez en Java et C++, mais c'est ce que j'attendrais en C #, bien qu'en C #, il y a un raccourci pour cela appelé Propriétés. Et voici quelques-unes Bons conseils sur la façon d'utiliser les propriétés ( http://msdn.Microsoft.com/en-us/library/ms182181.aspx ).

Compte tenu de cette vue, l'interface que je choisirais dépend uniquement de la présence d'effets secondaires (autres que la modification de la valeur du champ):

Si l'exécution de l'action a des effets secondaires, par exemple, elle affiche une boîte de dialogue, alors j'irais avec "Show ()" et "Hide ()".

S'il n'a pas d'effets secondaires, disons que je règle la visibilité d'un "widget" et que quelque chose d'autre le rend en fonction de son état, j'utiliserais setVisibility ou setIsVisible. (Je ne l'appellerais pas SetVisible).

En C # (pas sûr de Java), il est assez courant d'adopter un modèle d'observateur, où un cadre d'interface utilisateur écoutera les modifications apportées aux objets et restituera automatiquement l'interface utilisateur lorsqu'une propriété telle que la visibilité change. Cela signifie que la définition de la valeur en appelant setIsVisible semble avoir des effets secondaires, mais dans ma définition, ce n'est pas le cas. Le contrat du widget est rempli en définissant sa valeur de champ représentant "IsVisible".

Autrement dit, je suis d'accord pour basculer la visibilité d'une étiquette sur un formulaire avant que le formulaire ne soit affiché. C'est-à-dire label.getIsVisible == true, mais le formulaire n'est pas affiché.

Ce n'est pas correct pour moi d'appeler Hide () lorsque le formulaire n'est pas affiché.

3

Je suggère une interface légèrement modifiée:

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

De meilleurs noms

Ces noms de méthode aident le développeur à décider quelle méthode utiliser en fonction de ce qui doit être fait. Alors que SetVisible(bool visible) peut confondre un développeur car il transmet la même signification sémantique que Show() et Hide(), Toggle() implique l'existence d'une condition qui détermine l'action. Il devient ainsi intuitif pour le développeur quand utiliser chaque méthode.

Redondance de code réduite

L'avantage d'avoir plusieurs méthodes dans votre interface est qu'il simplifie le code appelant. Vous pouvez simplement exposer Show() et Hide(), mais:

  • Vous auriez probablement besoin d'une sorte de méthode privée SetVisible() pour faire le vrai travail en arrière-plan (ou écrire du code redondant pour Show() et Hide()).
  • Le code appelant peut avoir de nombreux blocs if/else redondants juste pour choisir la méthode à utiliser. Cela gonfle le code à mon avis.
  • Si j'étais le consommateur, j'écrirais probablement ma propre fonction wrapper qui fait ce que SetVisible() (ou Toggle()) fait déjà afin d'éviter le gonflement du code (je déteste le code redondant) . Dupliquer ainsi une méthode qui probablement existe déjà comme méthode privée dans l'implémentation.
2
gilly3

Je suggérerais d'utiliser SetVisible(bool) le cas échéant uniquement si le fait de basculer la visibilité deux fois (afficher et masquer à nouveau, ou masquer et afficher à nouveau) laisserait les choses dans le même état qu'avant l'exécution de l'opération (c'est très bien si afficher et cacher à nouveau quelque chose ou vice versa laisse des objets nécessitant une refonte, à condition que cela puisse arriver "automatiquement"). Si masquer et afficher un objet n'aura d'autre effet que de changer un bit d'état, alors il serait logique pour le code extérieur d'avoir des méthodes qui acceptent un paramètre de visibilité, et l'écriture de ce code sera facilitée par SetVisible.

Si le masquage et la nouvelle présentation d'un objet peuvent avoir des effets secondaires tels que la modification de l'ordre Z, ces actions devraient plus probablement être effectuées par des méthodes distinctes. Dans de tels cas, l'utilité des méthodes extérieures qui acceptent un paramètre de "visibilité" sera limitée, et il y aura donc peu d'avantages à les faciliter. De plus, une méthode SetVisible suggérera (à tort) que des changements dans la visibilité des objets peuvent être effectués sans effets secondaires.

0
supercat