57 votes

Constructeurs statiques vs constructeurs d'instance (normaux)?

Dans un langage où les deux sont disponibles, préférez-vous voir un constructeur d'instance ou une méthode statique qui renvoie une instance?

Par exemple, si vous créez un String partir d'un char[] :

  1. String.FromCharacters(chars);

  2. new String(chars);

65voto

Jon Skeet Points 692016

Dans Efficace Java, 2nd edition, Joshua Bloch certainement recommande à l'ancienne. Il y a quelques raisons que je me souvienne, et sans doute certains je ne peux pas:

  • Vous pouvez donner la méthode un nom significatif. Si vous avez deux manières de construire une instance à la fois de prendre un int, mais ont des significations différentes pour que int, à l'aide d'une méthode normale fait l'appel de code beaucoup plus lisible.
  • Un corollaire de la première, vous pouvez avoir différentes méthodes de fabrique avec la même liste de paramètres
  • Vous pouvez retourner la valeur null pour "potentiellement échec prévisible" des cas, alors qu'un constructeur va toujours retourner une valeur ou lever une exception
  • Vous pouvez retourner un type autre que le déclaré (par exemple, le retour d'une classe dérivée)
  • Vous pouvez l'utiliser comme une usine, peut-être retourner une référence au même objet plusieurs fois

Les inconvénients:

  • Ce n'est pas comme idiomatiques, actuellement, les développeurs sont plus habitués à voir des "nouveaux"
  • Si vous voyez un "nouveau" vous savez que vous obtenez une nouvelle instance (modulo la curiosité je l'ai mentionné récemment)
  • Vous avez besoin de faire des constructeurs disponibles pour les sous-classes
  • En C# 3, constructeur appels sont en mesure de définir des champs/propriétés dans un boîtier compact avec objet d'initialiseur expressions; la fonction ne s'applique pas aux méthodes statiques

27voto

Robert Rossney Points 43767

J'écris un constructeur lors de la création de l'instance n'a pas d'effets secondaires, c'est à dire quand la seule chose que le constructeur est en train de faire l'initialisation de propriétés. - Je écrire une méthode statique (et faire le constructeur privé) si la création de l'instance ne fait quelque chose que vous ne serait pas normalement s'attendre à un constructeur pour le faire.

Par exemple:

public class Foo
{
   private Foo() { }

   private static List<Foo> FooList = new List<Foo>();
   public static Foo CreateFoo()
   {
      Foo f = new Foo();
      FooList.Add(f);
      return f;
   }
}

Parce que j'adhère à la présente convention, si je vois

Foo f = Foo.CreateFoo();
Bar b = new Bar();

lors de la lecture de mon code, j'ai un ensemble très différent des attentes à propos de ce que chacune de ces deux lignes est en train de faire. Ce code n'est pas de me dire ce que c'est qui rend la création de Foo différent de la création d'un Bar, mais il me dit que j'ai besoin de regarder.

14voto

MB. Points 2847

J'ai travaillé sur une API publique récemment, et j'ai été à l'agonie sur le choix de la statique de l'usine de méthodes contraceptives constructeur. Statique méthodes de fabrique certainement faire sens dans certains cas, mais dans d'autres, il n'est pas clair et je ne suis pas certain que la cohérence avec le reste de l'API est une raison suffisante pour inclure plus de constructeurs.

De toute façon, je suis tombé sur une citation de Bill Venners interview avec Josh Bloch que j'ai trouvé utile:

Lorsque vous écrivez une classe, vous pouvez exécutez le mon livre la liste de la avantages de la statique des usines de plus de les constructeurs publics. Si vous trouvez que un nombre important de ces avantages s'appliquent effectivement dans votre cas, alors vous devriez aller avec les statique des usines. Sinon, vous devriez aller avec les constructeurs.

Certains ont été déçus de trouver que des conseils dans mon livre. Ils l'ont lu et dit, "Vous avez soutenu fortement pour le public static usines que nous faut juste les utiliser par défaut." J' pense que le seul vrai inconvénient dans ce faisant, c'est que c'est un peu déconcertant pour les personnes qui sont utilisés à l'aide de constructeurs pour créer leur objets. Et je suppose qu'il fournit un un peu moins d'un repère visuel dans le programme. (Vous ne voyez pas le nouveau mot-clé.) C'est également un peu plus difficile de trouver de la statique des usines en la documentation, parce que Javadoc des groupes de tous les constructeurs ensemble. Mais je dirais que tout le monde devrait envisager statique des usines de tous les temps, et de les utiliser quand ils sont approprié.

Après avoir lu cette citation, et l'étude d'Uri mentionnés*, je me sens enclin à pencher en faveur des constructeurs, sauf s'il existe des raisons impérieuses de le faire autrement. Je pense statique méthode de fabrique, sans bonne raison est probablement juste une complexité inutile et plus-ingénierie. Bien que je pourrais bien changer d'avis et de nouveau d'ici demain...

*Malheureusement, cette étude se focalise moins sur la statique de l'usine de méthodes et de plus en plus sur le modèle de fabrique (où une usine distincte de l'objet existe pour créer de nouvelles instances), donc je ne suis pas sûr que l'on peut vraiment en tirer la conclusion que statique usine méthodes de confondre de nombreux programmeurs. Bien que l'étude ne me donnent l'impression que, souvent, ils le feraient.

10voto

Dan Goldstein Points 8940

Si votre objet est immuable, vous pourrez peut-être utiliser la méthode statique pour renvoyer des objets mis en cache et enregistrer vous-même l'allocation et le traitement de la mémoire.

8voto

Uri Points 50687

Il y a un article de ICSE'07 qui a étudié l'utilisabilité des constructeurs par rapport aux modèles d'usine. Bien que je préfère les modèles d'usine, l'étude a montré que les développeurs étaient plus lents à trouver la bonne méthode d'usine.

http://www.cs.cmu.edu/~NatProg/papers/Ellis2007FactoryUsability.pdf

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