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


当前回答

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

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

其他回答

我在自制消息库中使用了builder。库核心从线路接收数据,用Builder实例收集数据,然后,一旦Builder确定它已经获得了创建Message实例所需的一切,Builder. getmessage()就使用从线路收集的数据构造消息实例。

我一直不喜欢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");

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

当你有很多选择要处理的时候,你就用它。想想jmock这样的东西:

m.expects(once())
    .method("testMethod")
    .with(eq(1), eq(2))
    .returns("someResponse");

这感觉更自然,而且是可能的。

还有xml构建,字符串构建和其他很多东西。想象一下,如果java.util.Map将put作为构建器。你可以这样做:

Map<String, Integer> m = new HashMap<String, Integer>()
    .put("a", 1)
    .put("b", 2)
    .put("c", 3);

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

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

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

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

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

构建器和工厂之间的关键区别是,当你需要做很多事情来构建一个对象时,构建器是有用的。例如,想象一个DOM。您必须创建大量节点和属性才能获得最终对象。当工厂可以在一个方法调用中轻松创建整个对象时,就使用工厂。

使用构建器的一个例子是构建一个XML文档,我在构建HTML片段时使用了这个模型,例如,我可能有一个构建器来构建一个特定类型的表,它可能有以下方法(参数未显示):

BuildOrderHeaderRow()
BuildLineItemSubHeaderRow()
BuildOrderRow()
BuildLineItemSubRow()

然后这个构建器会为我输出HTML。这比遍历一个大型过程方法容易得多。

在维基百科上查看生成器模式。