Les structures ont leur place, même en Java. Vous ne devriez les utiliser que si les deux choses suivantes sont vraies:
- Vous avez juste besoin d'agréger des données qui n'ont aucun comportement, par exemple pour les passer en paramètre.
- Peu importe le type de valeurs que les données agrégées ont
Si tel est le cas, vous devez alors rendre les champs publics et ignorer les getters / setters. De toute façon, les accesseurs et les setters sont maladroits, et Java est idiot de ne pas avoir de propriétés comme un langage utile. Comme votre objet de type struct ne devrait de toute façon pas utiliser de méthode, les champs publics ont le plus de sens.
Toutefois, si l’un ou l’autre de ces critères ne s’applique pas, vous avez affaire à une véritable classe. Cela signifie que tous les champs doivent être privés. (Si vous avez absolument besoin d'un champ dont la portée est plus accessible, utilisez un getter / setter.)
Pour vérifier si votre supposée-structure a un comportement, regardez quand les champs sont utilisés. Si cela semble violer tell, ne demandez pas , alors vous devez déplacer ce comportement dans votre classe.
Si certaines de vos données ne doivent pas changer, vous devez alors rendre tous ces champs définitifs. Vous pourriez envisager de rendre votre classe immuable . Si vous devez valider vos données, fournissez une validation dans les setters et les constructeurs. (Une astuce utile consiste à définir un poseur privé et à modifier votre champ au sein de votre classe en utilisant uniquement ce sélecteur.)
Votre exemple de bouteille échouerait probablement aux deux tests. Vous pourriez avoir un code (artificiel) qui ressemble à ceci:
public double calculateVolumeAsCylinder(Bottle bottle) {
return bottle.height * (bottle.diameter / 2.0) * Math.PI);
}
Au lieu de cela, il devrait être
double volume = bottle.calculateVolumeAsCylinder();
Si vous changiez la hauteur et le diamètre, s'agirait-il de la même bouteille? Probablement pas. Celles-ci devraient être finales. Une valeur négative est-elle acceptable pour le diamètre? Votre bouteille doit-elle être plus grande que large? Le cap peut-il être nul? Non? Comment validez-vous cela? Supposons que le client soit stupide ou méchant. ( Il est impossible de faire la différence. ) Vous devez vérifier ces valeurs.
Voici à quoi pourrait ressembler votre nouvelle classe Bottle:
public class Bottle {
private final int height, diameter;
private Cap capType;
public Bottle(final int height, final int diameter, final Cap capType) {
if (diameter < 1) throw new IllegalArgumentException("diameter must be positive");
if (height < diameter) throw new IllegalArgumentException("bottle must be taller than its diameter");
setCapType(capType);
this.height = height;
this.diameter = diameter;
}
public double getVolumeAsCylinder() {
return height * (diameter / 2.0) * Math.PI;
}
public void setCapType(final Cap capType) {
if (capType == null) throw new NullPointerException("capType cannot be null");
this.capType = capType;
}
// potentially more methods...
}