Question

Est-il toujours approprié d'abandonner le "getMyValue ()" et "setMyValue ()" motif de getters et setters si les noms de fonction alternatifs rendent l’API plus évidente?

Par exemple, imaginez que j'ai cette classe en C ++:


public class SomeClass {
private:
    bool mIsVisible;

public:
    void draw();
    void erase();
}

Je pourrais ajouter des fonctions pour obtenir / définir "mIsVisible". comme ceci:


bool getVisible() { return mIsVisible; };

void setVisible(bool visible) { if (!mIsVisible && visible) { draw(); } else if (mIsVisible && !visible) { erase(); }

mIsVisible = visible;

}

Cependant, il serait également possible d'utiliser les méthodes suivantes à la place:


bool isVisible() { return mIsVisible; };

void show() { 
    if (!mIsVisible) {
        mIsVisible = true;
        draw();
    }
}

void hide() {
    if (mIsVisible) {
        mIsVisible = false;
        erase();
    }
}

En résumé, vaut-il mieux avoir un seul "setVisible (bool)"? méthode, ou une paire de "show ()" et " hide () " les méthodes? Existe-t-il une convention ou s'agit-il uniquement d'une chose subjective?

Était-ce utile?

La solution

Lisez l'article " Dites, ne demandez pas . " sur le site Web de Pragmatic Programmers et je pense que vous verrez que le deuxième exemple est la voie à suivre.

En principe, vous ne devriez pas diffuser la logique par le biais de votre code, ce qui est impliqué dans votre premier exemple, à savoir:

  1. obtenir la valeur de visibilité actuelle,
  2. prendre une décision en fonction de la valeur,
  3. mettre à jour l'objet.

Autres conseils

Dans l'exemple que vous avez donné, show () et hide () ont beaucoup de sens, du moins pour moi.

D'autre part, si vous avez une propriété skinPigment et que vous avez décidé de créer des fonctions appelées tanMe () et makeAlbino () , serait un choix vraiment médiocre et non évident.

C’est subjectif, vous devez essayer de penser comme vos utilisateurs (les utilisateurs de cette classe). Quelle que soit la méthode choisie, cela devrait être évident pour eux et bien documenté.

Je choisirais le jeu isVisible () / show () / hide ().

setVisible () implique que tout ce qu'il fait change la variable interne. show () et hide () rendent les effets secondaires clairs.

D'un autre côté, si getVisible () / setVisible () a été chargé de changer la variable interne, vous ne modifiez que très peu de les avoir comme champs publics.

Les

setters ont en réalité très peu à voir avec l'orientation des objets, qui est l'idiome de programmation appliqué dans l'exemple. les getters sont légèrement meilleurs, mais peuvent souvent être vécus sans. Si tout peut être obtenu et mis en place, quel est l'intérêt d'avoir un objet? Les opérations doivent être appelées à des objets pour accomplir des choses, la modification de l'état interne n'en est qu'un effet secondaire. La mauvaise chose à propos d'un configurateur en présence de polymorphisme - l'une des pierres angulaires de OO - est que vous obligez chaque classe dérivée à disposer d'un configurateur. Que se passe-t-il si l'objet en question n'a pas besoin d'un état interne appelé mIsVisible? Bien sûr, il peut ignorer l'appel et l'implémenter comme vide, mais vous vous retrouvez alors avec une opération dénuée de sens. OTOH, des opérations comme afficher et masquer peuvent être facilement remplacées par différentes implémentations, sans rien révéler de l'état interne.

En général, je pense que les setters / getters ne devraient définir que les valeurs des propriétés. Dans votre exemple, vous effectuez également une action en fonction de la valeur de la propriété isVisible. Dans ce cas, je dirais qu'il est préférable d'utiliser des fonctions pour effectuer l'action et mettre à jour l'état plutôt que de définir un getter / getter qui effectue une action en tant qu'effet secondaire de la mise à jour de la propriété.

Si le changement de mIsVisible active et désactive immédiatement la visibilité de l'objet, utilisez le scénario afficher / masquer. S'il reste dans l'état ancien un peu plus longtemps (par exemple, jusqu'à ce que quelque chose d'autre déclenche un redessinage), le scénario set / get sera la solution.

Je préfère les méthodes show () et hide () car elles indiquent explicitement ce que vous allez faire. Le setVisible (booléen) ne vous dit pas si la méthode va montrer / dessiner tout de suite. De plus, show () et hide () sont des méthodes mieux nommées pour une interface (IMHO).

Implicitement, les fonctions "afficher" et "masquer" que vous avez répertoriées sont à la fois déterminantes

Pour les booléens, je pense qu’un seul outil, comme vous l’avez montré, serait bien. Cependant, les fonctions .show et .hide ressemblent également à des commandes et non à des fonctions qui modifient l'état de l'objet.

Si vous devez réellement écrire du code tel que

if (shouldBeShowingAccordingToBusinessLogic()) w.show();
else w.hide();

partout, vous pourriez être mieux avec

w.showIfAndOnlyIf(shouldBeShowingAccordingToBusinessLogic())

Ou, dans des cas vraiment bizarres, lorsque votre logique ne peut pas décider si vous souhaitez effectuer un dhow ou non jusqu'à la fin de l'étirement du code, vous pouvez essayer

w.setPostponedVisibility(shouldBeShowingAccordingToBusinessLogic());
...
w.realizeVisibility();

(N’ai-je pas dit que c’est bizarre?)

Une autre motivation supplémentaire pour la solution d'affichage / masquage est que, en tant que setter,

la méthode setVisible a un "effet secondaire", en ce sens qu'elle affiche ou masque également SomeClass . Les méthodes d'affichage / masquage reflètent mieux l'intention de ce qui se passe.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top