Les domaines publics de Java ne sont-ils qu'un défaut de conception historique tragique à ce stade? [fermé]

17

Il semble que l'orthodoxie Java soit à ce stade que l'on ne devrait fondamentalement jamais utiliser de champs publics pour l'état d'objet. (Je ne suis pas nécessairement d'accord, mais ce n'est pas pertinent pour ma question.) Étant donné que, serait-il juste de dire que d'où nous sommes aujourd'hui, il est clair que les champs publics de Java étaient une erreur / faille de la conception du langage? Ou existe-t-il un argument rationnel selon lequel ils sont une partie utile et importante de la langue, même aujourd'hui?

Merci!

Mise à jour: je connais les approches les plus élégantes, comme en C #, Python, Groovy, etc. Je ne recherche pas directement ces exemples. Je me demande vraiment s'il y a toujours quelqu'un au fond d'un bunker, marmonnant à quel point les champs publics sont vraiment merveilleux, et comment les masses ne sont que des moutons, etc.

Mise à jour 2: les champs publics finaux clairement statiques sont le moyen standard de créer des constantes publiques. Je faisais plus référence à l'utilisation de champs publics pour l'état d'objet (même l'état immuable). Je pense que cela semble être une faille de conception que l'on devrait utiliser les champs publics pour les constantes, mais pas pour l'état… les règles d'un langage devraient être appliquées naturellement, par syntaxe, et non par des directives.

Avi Flax
la source
2
Sur quoi vous basez-vous pour dire qu'il s'agit bien d'un défaut?
Aaron McIver
1
Existe-t-il une manière différente de créer des expressions constantes symboliques en Java maintenant?
Edward Strange
@Aaron Je n'affirmais pas qu'ils étaient un défaut, je déclarais que j'avais perçu qu'il s'agissait d'orthodoxie à ce stade, il ne fallait jamais utiliser les champs publics. Cette perception peut être fausse, mais c'est bien ce que j'ai perçu.
Avi Flax
@Crazy Eddie J'ai oublié cette utilisation, je pensais plus à l'utilisation plus courante des champs, état. Je vais modifier la question.
Avi Flax

Réponses:

14

Je les aime, tant que le champ est final et n'est utilisé qu'en interne dans l'application, non exposé dans une API pour d'autres applications. Cela rend votre code plus court et plus lisible.

Vous ne devez pas exposer les champs publics dans une API, car en exposant les champs publics, vous exposez également l'implémentation. Si vous l'exposez en tant que getXXX()méthode, vous pouvez modifier l'implémentation sans modifier l'interface API. Par exemple, vous pouvez modifier et obtenir la valeur d'un service distant, mais les applications qui utilisent l'API n'ont pas besoin de le savoir.

Il s'agit d'une conception viable pour les public finalchamps des classes immuables .

De Java efficace :

Point 14: Dans les classes publiques, utilisez des méthodes d'accesseur, pas des champs publics

... si une classe est privée de package ou est une classe imbriquée privée, il n'y a rien de mal à exposer ses champs de données. Cette approche génère moins d'encombrement que l'approche par méthode d'accesseur.

Bien que ce ne soit jamais une bonne idée pour une classe publique d'exposer directement des champs, il est moins dangereux si les champs sont immuables.

Voir aussi Pourquoi ne devrais-je pas utiliser des POJO immuables au lieu de JavaBeans?

Jonas
la source
Je me demande simplement, quelles sont vos raisons pour ne pas l'exposer dans une API?
Steven Jeuris
2
@Steven: Parce qu'en exposant des champs publics, vous exposez également l'implémentation. Si vous l'exposez en tant que getXXX()méthode, vous pouvez modifier l'implémentation sans modifier l'interface API. Par exemple, vous pouvez modifier et obtenir la valeur d'un service distant, mais les applications qui utilisent l'API n'ont pas besoin de le savoir.
Jonas
@ Jonas: Ce ne sont généralement pas des candidats pour les constantes en premier lieu.
Steven Jeuris
@Steven: Je ne parle pas des constantes en premier lieu mais des champs finaux publics dans les classes immuables . Par exemple, voir Pourquoi ne devrais-je pas utiliser des POJO immuables au lieu de JavaBeans?
Jonas
@ Jonas: C'est aussi un bon cas d'utilisation! Il est peut-être utile de mettre à jour un peu votre réponse pour clarifier.
Steven Jeuris
9

L'utilisation de paires de méthodes get / set est le défaut de conception historique tragique. Je ne peux pas penser à un autre langage qui implémente les propriétés de manière verbeuse et inefficace.

Kevin Cline
la source
1
Bien que cela soit vrai, cela est quelque peu tangentiel au point de la question, qui est (essentiellement) qu'étant donné le choix entre les méthodes set / get et les champs publics, y a-t-il de bonnes raisons de préférer les champs dans certaines situations? Le fait que d'autres langues offrent de meilleures solutions au problème ne me semble pas pertinent.
Jules
5

Je pense que les champs publics sont corrects pour une classe qui est essentiellement un type de valeur comme un nombre complexe ou un point, où la classe ne fait guère plus que regrouper les types primitifs comme une structure de style C et peut-être définir quelques opérateurs.

Karl Bielefeldt
la source
2
java.awt.Pointet les amis sont un peu un cauchemar.
Tom Hawtin - tackline
@ TomHawtin-tackline: Le problème avec Pointest qu'il est ambigu si une variable de type Pointest censée encapsuler un emplacement, ou est censée encapsuler l'identité d'une entité avec un emplacement qui peut changer. Conceptuellement, je considérerais le code qui circule Pointcomme un code qui circule autour des tableaux.
supercat
Donc, si j'obtiens un Pointet le modifie, dois-je m'attendre à ce que l'objet auquel il se réfère se mette à jour proprement à l'écran? Non, le problème Pointest qu'il est modifiable. Nous avions String/ StringBuffermais l'idée ne semblait pas passer. / La transmission de tableaux présente des problèmes similaires.
Tom Hawtin - tackline
5

Pour définir des constantes publiques, il est toujours utile. Par exemple

final statique public int DAYS_IN_WEEK = 7;

Cependant, préférez toujours les énumérations lorsque cela est possible. Par exemple

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
    THURSDAY, FRIDAY, SATURDAY 
}

Pour simuler des classes de structure simples, il est également utile. Aucune raison de créer un getter et un setter pour chaque champ, quand ils sont tous publics de toute façon.

class Point
{
    public int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
Steven Jeuris
la source
Mais là encore, beaucoup diraient que les structures n'ont pas leur place dans un langage comme Java ...
1
@delnan: Ils sont presque les mêmes que JavaBeans, mais JavaBeans est beaucoup plus verbeux et non threadsafe. Voir Pourquoi ne devrais-je pas utiliser des POJO immuables au lieu de JavaBeans?
Jonas
Certaines observations spécifiques à Android: les énumérations sont plus lentes à évaluer que les nombres entiers et doivent être évitées. En outre, les champs fréquemment consultés par les poseurs et les accesseurs en boucles serrées peuvent également bénéficier du fait d'être public.
Nailer
2

Avant que les IDE ne se généralisent, rendre tous vos domaines publics était un outil puissant pour créer rapidement des prototypes / preuves de concepts.

De nos jours, il y a très peu d'excuse pour les utiliser, quand vous pouvez générer une paire getter / setter avec un clic de souris.

biziclop
la source
4
Mais 10 public finalchamps sont plus lisibles que 10 getXXX()méthodes.
Jonas
1
@ Jonas Oui, mais nous ne parlons pas ici des derniers champs. Si vos champs finaux publics sont également statiques, ce sont des constantes, et un constmot-clé serait suffisant, s'ils ne sont pas statiques, ils constituent une violation grave de l'encapsulation.
biziclop
3
@biziclop selon Wikipedia : "bien que réservé comme mot-clé en Java, const n'est pas utilisé et n'a aucune fonction"
Avi Flax
@Avi Flax Oui, mais il aurait pu être utilisé pour marquer des constantes, éliminant ainsi la nécessité de déclarer des constantes en tant que champs publics.
biziclop
2
En supposant qu'une paire getter / setter est tout à fait appropriée, c'est-à-dire. Ce n'est souvent pas le cas.
David Thornley
2

C'est subjectif, mais mon avis est que toute la notion public / privé est dépassée et à l'envers.

En python, il n'y a pas de public / privé; tout est public au fond. N'a pas causé beaucoup de problèmes.

En Java, vous avez tendance à créer des getters / setters inutiles pour chaque champ pour éviter le péché de les marquer "publics". (À mon humble avis, si vous vous trouvez en train de le faire, vous devez simplement les marquer comme publics).

hasen
la source
Python vous permet de marquer les choses comme privées en préfixant les noms avec __. Ce n'est pas 100% privé, car il existe toujours des moyens d'accéder à ces variables et méthodes, mais en C #, vous pouvez faire des choses similaires avec la réflexion.
Adam Lear