112 votes

Surcharge des constructeurs en Java - Meilleures pratiques

Il y a quelques sujets similaires à celui-ci, mais je n'ai pas pu en trouver un avec une réponse suffisante.

Je voudrais savoir quelle est la meilleure pratique pour la surcharge de constructeur en Java. J'ai déjà mes propres idées sur le sujet, mais j'aimerais entendre davantage de conseils.

Je fais référence à la fois à la surcharge de constructeur dans une classe simple et à la surcharge de constructeur lors de l'héritage d'une classe déjà surchargée (ce qui signifie que la classe de base a des constructeurs surchargés).

Merci :)

176voto

Spoike Points 32082

Alors qu'il n'existe pas de lignes directrices officielles" j'ai suivi le principe de la BAISER et de la SEC. Faire des constructeurs surchargés aussi simple que possible, et de la façon la plus simple est qu'elle ne fait appel de cette(...). De cette façon, vous avez uniquement besoin de vérifier et de gérer les paramètres une fois et une seule fois.

public class Simple {

    public Simple() {
        this(null);
    }

    public Simple(Resource r) {
        this(r, null);
    }

    public Simple(Resource r1, Resource r2) {
        // Guard statements, initialize resources or throw exceptions if
        // the resources are wrong
        if (r1 == null) {
            r1 = new Resource();
        }
        if (r2 == null) {
            r2 = new Resource();
        }

        // do whatever with resources
    }

}

À partir d'un test d'unité de point de vue, il deviendra facile de tester la classe puisque vous pouvez mettre dans les ressources en elle. Si la classe possède de nombreuses ressources (ou des collaborateurs comme certains OO-geeks), pensez à l'une de ces deux choses:

Faire un paramètre de classe

public class SimpleParams {
    Resource r1;
    Resource r2;
    // Imagine there are setters and getters here but I'm too lazy 
    // to write it out. you can make it the parameter class 
    // "immutable" if you don't have setters and only set the 
    // resources through the SimpleParams constructor
}

Le constructeur Simples que les besoins de diviser l' SimpleParams paramètre:

public Simple(SimpleParams params) {
    this(params.getR1(), params.getR2());
}

...ou SimpleParams d'un attribut:

public Simple(Resource r1, Resource r2) {
    this(new SimpleParams(r1, r2));
}

public Simple(SimpleParams params) {
    this.params = params;
}

Faire une classe factory

Faire une usine de classe qui initialise les ressources pour vous, ce qui est favorable si l'initialisation de ressources est un peu difficile:

public interface ResourceFactory {
    public Resource createR1();
    public Resource createR2();
}

Le constructeur est alors fait de la même manière qu'avec le paramètre de la classe:

public Simple(ResourceFactory factory) {
    this(factory.createR1(), factory.createR2());
} 

Faire une combinaison des deux

Oui... vous pouvez mélanger et faire correspondre les deux façons selon ce qui est plus facile pour vous à l'époque. Paramètre classes et simple de l'usine de classes sont à peu près la même chose compte tenu de l' Simple de la classe qu'ils sont utilisés de la même manière.

74voto

oxbow_lakes Points 70013

Je pense que la meilleure solution consiste à faire primaire unique constructeur à laquelle les constructeurs surchargés consulter en appelant this() avec les valeurs par défaut des paramètres. La raison pour cela est qu'il est beaucoup plus claire qu'est-ce que le construit de l'état de l'objet est - vraiment, vous pouvez penser à la primaire constructeur comme le seul véritable constructeur, les autres de lui déléguer

Un exemple de ceci pourrait être JTable - le principal constructeur prend un TableModel (plus de la colonne et de la sélection de modèles) et les autres constructeurs appel de ce premier constructeur.

Pour les sous-classes où la super-classe a déjà constructeurs surchargés, j'aurais tendance à penser que c'est raisonnable pour traiter l'un des parents constructeurs de la classe en tant que primaire et pense qu'il est parfaitement légitime de ne pas avoir un seul primaire constructeur. Par exemple,lors de l'extension d' Exception, j'ai souvent fournir des 3 constructeurs, l'un prenant juste un String message, celui qui prend un Throwable la cause et de l'autre tenant à la fois. Chacun de ces constructeurs appels super directement.

7voto

Si vous avez un complexe très classe avec beaucoup d'options, dont seulement certaines combinaisons sont valables, pensez à utiliser un Générateur de rapports. Fonctionne très bien à la fois codewise mais aussi logiquement.

Le Constructeur est une classe imbriquée avec les méthodes conçu uniquement pour définir les champs, puis la ComplexClass constructeur ne prend qu'un tel Générateur comme argument.


Edit: Le ComplexClass constructeur ne peut garantir que l'etat le Constructeur est valable. C'est très difficile à faire si vous venez d'utiliser les setters sur ComplexClass.

2voto

Gregory Mostizky Points 4565

Cela dépend vraiment du type de cours que pas toutes les classes sont créés égaux.

Comme ligne directrice générale je dirais 2 options:

  • Pour la valeur et immuable classes (à l'Exception, Entier, Otd) utilisation principale unique constructeur comme suggéré dans la réponse ci-dessus
  • Pour tout le reste (beans de session, des services, des objets mutables, JPA & JAXB entités et ainsi de suite) utiliser le constructeur par défaut uniquement avec des paramètres par défaut sur tous les biens de sorte qu'il peut être utilisé sans configuration supplémentaire

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