2010-01-30 11 views
12

Joshua Bloch's Effective Java describe un patrón de generador que se puede usar para construir objetos con varios parámetros personalizables opcionalmente. La convención de nomenclatura que sugiere para las funciones del Generador, que "simula parámetros opcionales con nombre como los encontrados en Ada y Python", no parece coincidir con la convención de nomenclatura estándar de Java. Las funciones de Java tienden a depender de tener un verbo para comenzar la función y luego una frase basada en el nombre para describir lo que hace. La clase Builder solo tiene el nombre de la variable que definirá esa función.Ejemplo de patrón de generador en la API de Java?

¿Hay alguna API dentro de las bibliotecas estándar de Java que haga uso del patrón de generador? Quiero comparar las sugerencias en el libro con una implementación real dentro del conjunto básico de bibliotecas Java antes de seguir su uso.

+0

puede encontrar ejemplo en esta pregunta SE: http://stackoverflow.com/questions/1673841/examples-of-gof-design-patterns-in-javas-core-libraries? Rq = 1 –

Respuesta

17

no estoy seguro acerca de JDK dentro del núcleo, pero los buenos ejemplos se pueden encontrar en Guava. MapMaker es probablemente el mejor ejemplo en el que puedo pensar fuera de mi cabeza. Por ejemplo, a partir de los documentos:

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); 
      } 
     }); 

Sí, este tipo de cosas pueden ir contra la corriente de Java Naming "estándar", pero también puede ser muy legible.

Para las situaciones en las que no devuelve "esto" sino un objeto nuevo (generalmente con tipos inmutables), me gusta el prefijo "con" - Joda Time usa ese patrón extensivamente. Ese no es el patrón del constructor, sino una forma de construcción alternativa y relacionada.

0

Solo está definido (no implementado) en la biblioteca estándar, sin embargo, los objetos DataSource de JDBC me recuerdan el patrón del generador. Usted crea un objeto DataSource y luego establece un número de propiedades y luego establece una conexión.

Aquí está un ejemplo de código ...

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 es en gran medida una instancia del patrón de generador, pero no del todo con las convenciones de nomenclatura de 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(); 

En el paquete de SQL, PreparedStatement se podría considerar una instancia de la Builder:

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

No es una fuente completa Si no puede encadenar los métodos, use el patrón. – BalusC

4

El único constructor más precisa para el libro Effective Java es StringBuilder. La única diferencia que veo en el ejemplo es que este constructor no es una clase interna de String.

Todos los métodos devuelven el objeto constructor a la cadena. y el método toString() es el método build().

+0

'StringBuilder' no es una implementación del Patrón del constructor, simplemente porque su nombre dice constructor, no devuelve un nuevo' Objeto', en su lugar hace lo contrario. Paz. –

0

SAXParser parece ser un buen ejemplo:

  • SAXParser - Director
  • ContentHandler - Constructor

El uso típico de SAXParser es idéntico al Constructor:

// 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

Bastante buen ejemplo de Java 8 API Core es Calendar, por ejemplo, puede usar:

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

Otro buen ejemplo de Java 7 es Locale, utilice:

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

El patrón de generador es más útil en el contexto de objetos inmutables. Curiosamente, hay muchos constructores mutables en Java, siendo el más común el StringBuilder. constructores mutables de Java 8:

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