Подтвердить что ты не робот

Пример шаблона Builder в Java API?

Joshua Bloch Эффективная Java описывает шаблон Builder, который можно использовать для создания объектов с несколькими необязательно настраиваемыми параметрами. Соглашение об именовании, которое он предлагает для функций Builder, которое "имитирует именованные дополнительные параметры, найденные в Ada и Python", похоже, не соответствует стандарту стандартного именования Java. Функции Java, как правило, полагаются на наличие глагола для запуска функции, а затем именную фразу для описания того, что она делает. Класс Builder имеет только имя переменной, которая должна быть определена этой функцией.

Существуют ли какие-либо API в стандартных библиотеках Java, которые используют шаблон Builder? Я хочу сравнить предложения в книге с фактической реализацией в основном наборе библиотек Java, прежде чем использовать его.

4b9b3361

Ответ 1

Я не уверен в основном JDK, но хорошие примеры можно найти в Guava. MapMaker, вероятно, лучший пример, который я могу придумать с головы. Например, из документов:

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

Да, такого рода вещи могут пойти против зерна "стандартного" именования Java, но также могут быть очень читабельными.

В ситуациях, когда вы не возвращаете "this", а новый объект (обычно с неизменяемыми типами), мне нравится префикс "с". Время Joda Time широко использует этот шаблон. Это не шаблон строителя, а альтернативная и связанная с ним конструкция.

Ответ 2

Единственным строителем, наиболее точным для эффективной Java-книги, является StringBuilder. Единственное отличие, которое я вижу в этом примере, состоит в том, что этот строитель не является внутренним классом String.

Все методы возвращают объект-строитель в цепочку. а метод toString() - метод build().

Ответ 4

Он только определен (не реализован) в стандартной библиотеке, однако объекты DataSource JDBC напоминают мне шаблон построителя. Вы создаете объект DataSource, а затем задаете несколько свойств, а затем создаете соединение.

Вот пример кода...

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

Ответ 5

ProcessBuilder - это, скорее, экземпляр шаблона построителя, но не совсем с использованием условных обозначений 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();

В пакете SQL PreparedStatement можно считать экземпляром шаблона построителя:

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

Ответ 6

SAXParser кажется хорошим примером:

  • SAXParser - Директор
  • ContentHandler - Builder

Типичное использование SAXParser идентично Builder:

// 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();

Ответ 7

Довольно хороший пример из Java 8 Core API - Calendar, например вы можете использовать:

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

Другим хорошим примером из Java 7 является Locale, используйте:

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

Шаблон компоновщика наиболее полезен в контексте неизменяемых объектов. Интересно, что в Java много изменяемых сборщиков, StringBuilder является наиболее распространенным. Mutable builders из Java 8:

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