Java Language Pourquoi utiliser des getters et des setters?


Exemple

Considérons une classe de base contenant un objet avec des getters et des setters dans Java:

public class CountHolder {
  private int count = 0;

  public int getCount() { return count; }
  public void setCount(int c) { count = c; }
}

Nous ne pouvons pas accéder à la variable count car elle est privée. Mais nous pouvons accéder aux getCount() et setCount(int) car elles sont publiques. Pour certains, cela pourrait soulever la question; pourquoi présenter l’intermédiaire? Pourquoi ne pas simplement les rendre publiques?

public class CountHolder {
  public int count = 0;
}

À toutes fins utiles, ces deux sont exactement les mêmes, du point de vue des fonctionnalités. La différence entre eux est l'extensibilité. Considérez ce que chaque classe dit:

  • Premièrement : "J'ai une méthode qui vous donnera une valeur int et une méthode qui définira cette valeur sur un autre int ".
  • Deuxièmement : "J'ai un int que vous pouvez définir et obtenir à votre guise."

Celles-ci peuvent sembler similaires, mais la première est en réalité beaucoup plus protégée dans sa nature; il vous permet seulement d'interagir avec sa nature interne comme il le dicte. Cela laisse la balle dans son camp; il arrive à choisir comment les interactions internes se produisent. Le second a exposé son implémentation interne en externe, et est désormais non seulement sujet aux utilisateurs externes, mais, dans le cas d'une API, engagé à maintenir cette implémentation (ou à publier une API non compatible).

Considérons si nous voulons synchroniser l'accès à la modification et à l'accès au compte. Dans le premier, c'est simple:

public class CountHolder {
  private int count = 0;

  public synchronized int getCount() { return count; }
  public synchronized void setCount(int c) { count = c; }
}

mais dans le deuxième exemple, cela est maintenant presque impossible sans passer par et en modifiant chaque endroit où la variable count est référencée. Pire encore, s'il s'agit d'un élément que vous fournissez dans une bibliothèque pour être consommé par d'autres, vous n'avez aucun moyen d'effectuer cette modification et vous devez faire le choix difficile mentionné ci-dessus.

Donc, cela pose la question; les variables publiques sont-elles une bonne chose (ou du moins pas mal)?

Je ne suis pas sûr D'une part, vous pouvez voir des exemples de variables publiques qui ont résisté à l'épreuve du temps (IE: la variable out référencée dans System.out ). D'autre part, fournir une variable publique n'apporte aucun avantage en dehors des frais généraux extrêmement minimes et de la réduction potentielle de la verbosité. Ma ligne directrice serait ici que, si vous avez l' intention de faire d' un public variable, vous devez juger de ces critères avec préjudice extrême:

  1. La variable ne devrait avoir aucune raison concevable de changer jamais dans sa mise en œuvre. C'est quelque chose qui est extrêmement facile à bousiller (et, même si vous faites les choses correctement, les exigences peuvent changer), ce qui explique pourquoi les getters / setters constituent l'approche commune. Si vous avez une variable publique, il faut vraiment y réfléchir, surtout si elle est publiée dans une bibliothèque / framework / API.
  2. La variable doit être référencée assez souvent pour que les gains minimaux résultant de la réduction de la verbosité le justifient. Je ne pense même pas que les frais généraux liés à l’utilisation d’une méthode par rapport au référencement direct devraient être pris en compte ici. C'est beaucoup trop négligeable pour 99,9% des demandes.

Il y a probablement plus que ce que je ne pensais pas. Si vous avez un doute, utilisez toujours les getters / setters.