65 votes

Immuable Type: public final champs vs getter

J'ai besoin d'un petit Conteneur de Classe pour le stockage de certaines Chaînes qui devrait être immuable. Comme une Chaîne de caractères elle-même est immuable type, j'ai pensé à quelque chose comme ça:

public final class Immu
{
  public final String foo;
  public final String bar;

  public Immu(final String foo, final String bar)
  {
    this.foo = foo;
    this.bar = bar;
  }
}

Beaucoup de gens semblent à l'objet à l'aide de champs publics à tous et à utiliser les Accesseurs à la place. À mon humble avis, ce serait tout simplement de standard dans ce cas, parce que la Chaîne elle-même est immuable.

D'autres pensées que j'ai peut-être manquant sur celui-ci?

62voto

Peter Lawrey Points 229686

Je ferais ce que vous croyez est la plus simple et la plus claire. Si vous avez une valeur de données de la classe qui n'est utilisée que par un nombre restreint de classes. esp un paquet de classe locale. alors je voudrais éviter de lecture/définition et l'utilisation du package local ou les champs publics.

Si vous avez une classe à laquelle vous vous attendez à d'autres modules/développeurs de l'utiliser, à la suite d'un getter/setter modèle peut être une approche plus sûre à long terme.

27voto

Daniel C. Sobral Points 159554

Le problème, c'est l'uniforme principe d'accessibilité. Vous devrez par la suite modifier foo , de sorte qu'il est obtenu par une méthode au lieu d'être fixe, et si vous avez exposé le champ au lieu d'un getter, vous aurez besoin de casser votre API.

14voto

emory Points 6319

Pourquoi pas

interface Immu { String getA() ; String getB ( ) }

Immu immu ( final String a , final String b )
{
       /* validation of a and b */
       return new Immu ( )
       {
              public String getA ( ) { return a ; }

              public String getB ( ) { return b ; }
       }
}

7voto

ChrisA Points 31

J'utilise le public-final-champ (anti?)motif sur la maison des projets pour les classes qui sont essentiellement immuable structure de données avec un constructeur, avec base absolue comme equals(), hashCode(), toString(), etc. si nécessaire. (J'évite le mot "struct" en raison de la variété de langues différentes interprétations de celle-ci.)

Je ne voudrais pas porter cette approche de quelqu'un d'autre de la base de code (de travail, de projet public, etc), parce qu'il serait susceptible d'être incompatible avec d'autres codes, et les principes comme À Rome ou Moins Surprise prioritaires.

Cela dit, à l'égard de Daniel C. Sobral et aioobe réponses, mon attitude est que si la conception de classe devient un problème en raison de l'évolution imprévue des circonstances, c'est le travail de 30 secondes dans un IDE pour privatiser les champs et ajouter des accesseurs, et pas plus de 5 ou 10 minutes à la réparation de références que si il y a des centaines d'entre eux. Tout ce qui tombe en panne à la suite est l'unité de test, il devrait avoir dans la première place.:-)

[Edit: Efficace Java est assez fermement contre l'idée, tout en notant qu'il est "moins nocif" sur immuable champs.]

0voto

n0rm9n Points 1683

Il n'est pas très clair si quelqu'un va utiliser votre code par le biais d'une API. Vous êtes également en manque une occasion de valider l'entrée, si vous allez exiger d'autres plus tard.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X