Java API中的Builder模式示例?

Fos*_*tah 13 java design-patterns builder

Joshua Bloch的Effective Java描述了一个Builder模式,可用于构建具有多个可选定制参数的对象.他为Builder函数建议的命名约定,"模拟在Ada和Python中找到的命名可选参数",似乎不符合Java的标准命名约定.Java函数往往依赖于使用动词来启动函数,然后依靠基于名词的短语来描述它的作用.Builder类只有该函数定义的变量的名称.

Java标准库中是否有使用Builder模式的API?我想在继续使用之前,将本书中的建议与核心Java库集中的实际实现进行比较.

Jon*_*eet 17

我不确定核心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);
          }
        });
Run Code Online (Sandbox Code Playgroud)

是的,这种事情可能违背"标准"Java命名,但它也可以非常易读.

对于你没有返回"this"而是一个新对象(通常使用不可变类型)的情况,我喜欢"with"前缀 - Joda Time广泛使用该模式.这不是构建器模式,而是替代和相关的构造形式.


小智 5

唯一对 Effective java 书籍最准确的构建器是 StringBuilder。我从示例中看到的唯一区别是此构建器不是 String 的内部类。

所有方法都返回要链接的构建器对象。toString() 方法是 build() 方法。


小智 5

Locale类有一个Builder模式的例子. https://docs.oracle.com/javase/7/docs/api/java/util/Locale.Builder.html

用法:

Locale locale = new Builder().setLanguage("sr").setScript("Latn").setRegion("RS").build();
Run Code Online (Sandbox Code Playgroud)


Ani*_*kar 5

Java 8 Core API 的一个很好的例子是Calendar,例如你可以使用:

Calendar cal = new Calendar.Builder().setCalendarType("iso8601")
                        .setWeekDate(2013, 1, MONDAY).build();
Run Code Online (Sandbox Code Playgroud)

另一个很好的例子Java 7是Locale,使用:

Locale aLocale = new Builder().setLanguage("sr").setScript("Latn").setRegion("RS").build();
Run Code Online (Sandbox Code Playgroud)

构建器模式在不可变对象的上下文中最有用。有趣的是,Java 中有许多可变构建器,StringBuilder这是最常见的一种。来自 Java 8 的可变构建器:

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