使用构建器模式的一些常见的、真实的例子是什么?它能给你买什么?为什么不直接使用工厂模式?


当前回答

以餐厅为例。“今天的饭菜”的创建是一种工厂模式,因为您告诉厨房“给我今天的饭菜”,然后厨房(工厂)根据隐藏的标准决定生成什么对象。

如果你订购了一个定制的披萨,建造者就会出现。在这种情况下,服务员告诉厨师(建筑工人)“我需要一个披萨;加奶酪、洋葱和培根!”因此,构建器公开了生成的对象应该具有的属性,但隐藏了如何设置这些属性。

其他回答

对于多线程问题,我们需要为每个线程构建一个复杂的对象。对象表示正在处理的数据,并且可以根据用户输入进行更改。

我们能用工厂代替吗?是的

为什么我们没有呢?我想建造者更有意义。

工厂用于创建具有相同基本类型的不同类型的对象(实现相同的接口或基类)。

构建器一遍又一遍地构建同一类型的对象,但是构造是动态的,因此可以在运行时更改它。

当我想在Java中为XML使用标准XMLGregorianCalendar来对DateTime进行对象封送时,我听到了很多关于使用它是多么沉重和麻烦的评论。我试图控制xs:datetime结构中的XML字段来管理时区,毫秒等。

因此,我设计了一个实用程序,从GregorianCalendar或java.util.Date构建一个xml公历。

由于我工作的地方,我不允许在网上分享它,但这里有一个客户如何使用它的例子。它抽象了XMLGregorianCalendar的细节,并过滤了xs:datetime中较少使用的一些实现。

XMLGregorianCalendarBuilder builder = XMLGregorianCalendarBuilder.newInstance(jdkDate);
XMLGregorianCalendar xmlCalendar = builder.excludeMillis().excludeOffset().build();

假定此模式更像是一个过滤器,因为它将xmlCalendar中的字段设置为未定义,因此将它们排除在外,但它仍然“构建”它。我已经很容易地向构建器添加了其他选项,以创建xs:date和xs:time结构,并在需要时操作时区偏移量。

如果您曾经见过创建和使用XMLGregorianCalendar的代码,您就会看到这是如何使它更容易操作的。

构建器的另一个优点是,如果您有一个Factory,那么代码中仍然存在一些耦合,因为要让Factory工作,它必须知道它可能创建的所有对象。如果您添加了另一个可以创建的对象,则必须修改工厂类以包括他。这在抽象工厂中也会发生。

另一方面,对于构建器,您只需要为这个新类创建一个新的具体构建器。director类将保持不变,因为它在构造函数中接收构造器。

此外,构建器也有很多种。神风特攻队雇佣兵又给了一个。

. net StringBuilder类是构建器模式的一个很好的例子。它主要用于在一系列步骤中创建字符串。执行ToString()的最终结果始终是一个字符串,但该字符串的创建取决于使用StringBuilder类中的哪些函数。总而言之,基本思想是构建复杂的对象,并隐藏如何构建对象的实现细节。

我一直不喜欢Builder模式,因为它笨拙、突兀,而且经常被缺乏经验的程序员滥用。这是一个模式,只有当你需要从一些需要后初始化步骤的数据组装对象时才有意义(即,一旦收集了所有的数据-对它做一些事情)。相反,在99%的时间里,构建器只是用来初始化类成员。

在这种情况下,最好是在类中声明withXyz(…)类型setter,并让它们返回对自身的引用。

考虑一下:

public class Complex {

    private String first;
    private String second;
    private String third;

    public String getFirst(){
       return first; 
    }

    public void setFirst(String first){
       this.first=first; 
    }

    ... 

    public Complex withFirst(String first){
       this.first=first;
       return this; 
    }

    public Complex withSecond(String second){
       this.second=second;
       return this; 
    }

    public Complex withThird(String third){
       this.third=third;
       return this; 
    }

}


Complex complex = new Complex()
     .withFirst("first value")
     .withSecond("second value")
     .withThird("third value");

现在我们有了一个整洁的单一类,它管理自己的初始化,做的工作与构建器几乎相同,只是它要优雅得多。