2013-05-21 2 views
0

Je suis tombé sur une classe avec un constructeur privé mais l'objet est retourné par une autre méthode publique par appel au constructeur privé. Quel peut être l'avantage d'une telle construction alors que nous aurions pu rendre le constructeur public?Constructeur privé initialisé par une méthode publique

public final class TokenTable { 

    static public int errorToken = 0; 
    static public int timesToken = 1; 
    static public int divToken = 2; 
    static public int plusToken = 11; 
    ...... 
    ...... 

    private final HashMap<String, Integer> keywordMap = new HashMap(); 
    private final HashMap<String, Integer> operationMap = new HashMap(); 

    private TokenTable() { 

     operationMap.put("*", timesToken); 
     operationMap.put("/", divToken); 
     operationMap.put("+", plusToken); 
     .... 



    } 


    static public TokenTable getInstance() { 

      LexTokenTabInstance = new TokenTable(); 
      return LexTokenTabInstance; 
    } 

} 
+0

Je dois dire, je suis un Peu déçu que la plupart des réponses ici soulèvent des singletons. Je suppose que c'est le nom de 'getInstance()' (qui est l'un des noms les plus communs pour un getter singleton) ... mais quand même. – cHao

+0

@cHao Si vous n'êtes pas satisfait des réponses actuelles, pourquoi ne créez-vous pas les vôtres? Si vous pensez qu'il y a une meilleure réponse que celles fournies, je serais curieux de le lire. – Supericy

+0

@Supericy: Parce qu'il y a deux bons ici qui disent déjà à peu près ce que je voudrais. Ce sont les autres qui me dépriment. – cHao

Répondre

0

Le principal avantage est que personne ne peut créer une instance, mais en utilisant la méthode getInstance statique.

De cette façon, vous pouvez vous assurer que une instance est créée, tout comme Singelton design pattern

5

Ceci est appelé le modèle Factory. Découvrez la description here - Factory Design Pattern.

Il y a plusieurs avantages:

  • vous pouvez avoir des méthodes d'usine multiples nommées pour créer différentes saveurs de l'objet qui peut permettre une surcharge avec le même ensemble de types de paramètres
  • vous pouvez retourner un singleton si approprié ou revenir peut-être un d'un ensemble d'instances mises en cache
  • si ne pas besoin d'utiliser new
  • lors de l'utilisation des médicaments génériques, le type générique est déduit par le compilateur donc ne pas avoir besoin d'utiliser le <> opérateur
  • vous pouvez retourner une interface au lieu d'une classe concrète
  • permet d'initialisation pré-constructeur (par exemple, si init doit être fait avant d'appeler le constructeur de classe de base)

Pour être clair, ce qui précède Par exemple, il semble que cela a été fait comme une "bonne pratique", car aucune des capacités ci-dessus n'a été utilisée (à part que vous n'avez pas besoin d'utiliser "nouveau").

+2

Il convient de noter que lorsque vous n'avez pas besoin de ces avantages, un constructeur public ordinaire porte un peu moins de bagage mental. ie: Ne pas tout transformer en usine juste parce que c'est plus spiffieux. :) – cHao

0

La raison principale pour masquer un constructeur d'une classe est de contrôler comment les objets de cette classe sont créés. Un exemple commun de ceci est dans le modèle de Singleton, où un seul objet d'une classe est instancié.

Pour la police, l'utilisateur accède à une méthode statique qui accédera au constructeur privé si l'objet est pas créé, ou bien renvoyer une référence à l'objet déjà créé:

public class SingletonDemo { 
    private static volatile SingletonDemo instance = null; 

    private SingletonDemo() {  } 

    public static SingletonDemo getInstance() { 
      if (instance == null) { 
        synchronized (SingletonDemo.class){ 
          if (instance == null) { 
            instance = new SingletonDemo(); 
          } 
        } 
      } 
      return instance; 
    } 
} 

Pour d'autres exemples, voir Modèles d'usine en général: http://en.wikipedia.org/wiki/Factory_method_pattern

3

Cette méthode est appelée une méthode d'usine. Une méthode de fabrication présente de nombreux avantages sur un constructeur:

  • il a un nom (et plusieurs méthodes d'usine peuvent avoir des noms différents)
  • il permet de retourner une instance mise en cache au lieu d'une nouvelle instance
  • il permet le retour une instance de sous-classe au lieu de la classe réelle
  • etc.
0

Si vous ne voulez pas protéger la création de plusieurs instances en dehors de la classe, alors vous pouvez créer constructeur privé.
Ceci est utile pour créer une instance unique.
Vous pouvez le faire comme (chargement Désireuse):

private static final TokenTable tokenTable = new TokenTable(); 

static public TokenTable getInstance() { 

      return tokenTable; 
    } 

Ou, vous pouvez le faire comme (chargement Lazy):

private static TokenTable tokenTable; 

static public TokenTable getInstance() { 
     if(null == tokenTable){ 
     tokenTable = new TokenTable(); 
     } 
      return tokenTable; 
    } 
+0

Notez, l'exemple de chargement paresseux n'est pas thread-safe. : P Vous marqueriez généralement la fonction comme 'synchronized', ou synchroniser explicitement sur la classe ou quelque chose. – cHao

+0

Ok Chao, Merci pour cette précieuse information. –

Questions connexes