2010-01-30 4 views
12

de Joshua Bloch Effective Java décrit un modèle de générateur qui peut être utilisé pour construire des objets avec plusieurs paramètres facultatifs. La convention de nommage qu'il suggère pour les fonctions Builder, qui "simule des paramètres optionnels nommés tels que trouvés dans Ada et Python", ne semble pas correspondre à la convention d'appellation standard de Java. Les fonctions Java ont tendance à s'appuyer sur un verbe pour démarrer la fonction, puis une phrase basée sur le nom pour décrire ce qu'il fait. La classe Builder a seulement le nom de la variable qui doit être définie par cette fonction.Exemple de modèle Builder dans l'API Java?

Existe-t-il des API dans les bibliothèques standard Java qui utilisent le modèle Builder? Je veux comparer les suggestions dans le livre à une implémentation réelle dans l'ensemble de base de bibliothèques Java avant de poursuivre son utilisation.

+0

Vous trouverez par exemple dans cette question SE: http://stackoverflow.com/questions/1673841/exemples-de-gof-design-patterns-dans-javas-core-libraries? Rq = 1 –

Répondre

17

Je ne suis pas sûr dans le JDK noyau, mais de bons exemples peuvent être trouvés dans Guava. MapMaker est probablement le meilleur exemple que je peux penser au-dessus de ma tête. Par exemple, des docs:

ConcurrentMap<Key, Graph> graphs = new MapMaker() 
    .concurrencyLevel(32) 
    .softKeys() 
    .weakValues() 
    .expiration(30, TimeUnit.MINUTES) 
    .makeComputingMap(
     new Function<Key, Graph>() { 
      public Graph apply(Key key) { 
      return createExpensiveGraph(key); 
      } 
     }); 

Oui, ce genre de chose peut aller contre le grain de nommage Java « standard », mais il peut aussi être très lisible. Pour les situations où vous ne renvoyez pas "ceci" mais un nouvel objet (typiquement avec des types immuables) j'aime un préfixe "avec" - Joda Time utilise intensément ce motif. Ce n'est pas le modèle constructeur, mais une forme de construction alternative et connexe.

0

Elle est seulement définie (non implémentée) dans la bibliothèque standard, cependant, les objets DataSource JDBC me rappellent le modèle de générateur. Vous créez un objet DataSource, puis vous définissez un nombre de propriétés et ensuite vous établissez une connexion.

Voici un exemple de code ...

DataSource ds = (DataSource)ctx.lookup("jdbc/AcmeDB"); 
ds.setServerName("my_database_server"); 
ds.setDescription("the data source for inventory and personnel"); 
Connection con = ds.getConnection("genius", "abracadabra"); 
0

ProcessBuilder est en fait une instance du modèle de générateur, mais n'utilise pas tout à fait les conventions de dénomination Java.

 
ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2"); 
Map env = pb.environment(); 
env.put("VAR1", "myValue"); 
env.remove("OTHERVAR"); 
env.put("VAR2", env.get("VAR1") + "suffix"); 
pb.directory(new File("myDir")); 
Process p = pb.start(); 

Dans le package SQL, PreparedStatement pourrait être considéré comme une instance du motif constructeur:

 
PreparedStatement stmt = conn.prepareStatement(getSql()); 
stmt.setString(1, ...); 
stmt.setString(2, ...); 
ResultSet rs = stmt.executeQuery(); 
... 
stmt.setString(2, ...); 
rs = stmt.executeQuery(); 
... 
+3

Ce n'est pas un modèle de lder si vous ne pouvez pas enchaîner les méthodes. – BalusC

4

Le seul constructeur le plus précis du livre efficace java est StringBuilder. La seule différence que je vois de l'exemple est que ce constructeur n'est pas une classe interne de String.

Toutes les méthodes renvoient l'objet du constructeur à la chaîne. et la méthode toString() est la méthode build().

+0

'StringBuilder' n'est pas une implémentation de Builder Pattern, juste parce que son nom dit builder, il ne retourne pas un' Object' à la place. Paix. –

0

SAXParser semble être un bon exemple:

  • SAXParser - Directeur
  • ContentHandler - Constructeur

L'utilisation typique de SAXParser est identique avec le constructeur:

// Create Director 
SAXParser parser = new org.apache.xerces.parsers.SAXParser(); 
// Create Concrete Builder (our own class) 
IdentingContentHandler handler = new IndentingContentHandler(); 
// Set Buidler to Director 
parser.setContentHandler(handler); 
// Build 
parser.parse(new InputSource(new FileReader(fileName)); 
// Get indented XML as String from handler 
String identedXML = handler.getResult(); 
0

Très bon exemple de Java 8 API Core est Calendar, par exemple, vous pouvez utiliser:

Calendar cal = new Calendar.Builder().setCalendarType("iso8601") 
         .setWeekDate(2013, 1, MONDAY).build(); 

Un autre bon exemple de Java 7 est Locale, utilisez:

Locale aLocale = new Builder().setLanguage("sr").setScript("Latn").setRegion("RS").build(); 

Le modèle de générateur est très utile dans le contexte d'objets immuables. Fait intéressant, il existe de nombreux constructeurs mutables en Java, StringBuilder étant le plus commun. constructeurs mutables de Java 8:

  • Stream.Builder
  • IntStream.Builder
  • LongStream.Builder
  • DoubleStream.Builder