Réutilisation de code dans des constructeurs surchargés

Ma classe BigBlock nécessite quelques constructeurs surchargés. Tous doivent initialiser les mêmes champs de la même manière.

Quelle est la bonne façon de faire cela? Est-ce que c’est pour créer une fonction, par exemple Initialize dans l’exemple ci-dessous, que ces choses-là sont faites et que tous les constructeurs appellent cette fonction?

 public class BigBlock { private Thing parentThing; Units lengthUnit; LabCoordinateSystem labCoordinateSystem; private void Initialize(){ lengthUnit = parentThing.getPreferredUnits(0); labCoordinateSystem = parentThing.getCoordinateSystem(); } BigBlock(Thing myThing){ parentThing= myThing; Initialize(); } BigBlock(Thing myThing, double x, double y, double z){ parentThing= myThing; Initialize(); // more code involving x, y, z } // a few more constructors } 

En règle générale, il est préférable de regrouper toutes les chaînes de constructeurs en un seul contenant le plus d’informations, par exemple:

 BigBlock(Thing myThing) { this(myThing, 0, 0, 0); // Assuming 0 is the default value for x, y and z } 

Cela devient un peu plus étrange s’il existe différentes manières d’appeler le constructeur qui ne représentent pas réellement des sous-ensembles de la même information – mais à ce stade, je dirais qu’il y a quand même une odeur de conception.

Notez que lorsque vous avez toute la logique réelle dans un seul constructeur, vous n’avez plus du tout besoin de votre méthode Initialize (qui doit être initialize pour suivre les conventions de nommage Java, btw) – vous pouvez également rendre les champs finaux. ce qui auparavant ne pouvait pas être fait.

Il suffit de réutiliser votre constructeur actuel. Laissez chaque autre constructeur appeler celui qui initialise toutes les valeurs requirejses.

 BigBlock(Thing myThing){ parentThing = myThing; lengthUnit = parentThing.getPreferredUnits(0); labCoordinateSystem = parentThing.getCoordinateSystem(); } BigBlock(Thing myThing, double x, double y, double z){ this(myThing); // more code involving x, y, z } 

Si x , y et z doivent faire partie de l’initalisation, BigBlock(Thing myThing) doit appeler BigBlock(Thing myThing, double x, double y, double z) avec les valeurs par défaut.

Non – vous pouvez appeler d’autres constructeurs à partir d’un constructeur en utilisant ceci.

 BigBlock(Thing myThing) { this(myThing,0,0,0); // Pass default values for other constructors } 

Comme presque toujours, la réponse à la question “quelle est la meilleure façon de …” est “dépend”.

Si la logique derrière Initialize est spécifiquement couplée à la création d’object et que Thing est commun à tous les aspects de la création, vous pouvez le modéliser en insérant ce comportement sur le constructeur le plus simple et en l’utilisant dans tous les autres. Cela centraliserait cet usage du comportement d’initialisation dans un seul endroit.

 BigBlock(Thing myThing){ parentThing= myThing; Initialize(); } BigBlock(Thing myThing, double x, double y, double z){ this(myThing); // more code involving x, y, z } 

Dans d’autres circonstances, il peut être utile d’ Initialize tant que méthode distincte. Par exemple, si initialize utilise une logique réutilisable, vous pouvez appeler une “réinitialisation” de l’object que vous pouvez appeler à un moment différent de celui de la création de l’object.