使用构建器模式的一些常见的、真实的例子是什么?它能给你买什么?为什么不直接使用工厂模式?
当前回答
当我想在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的代码,您就会看到这是如何使它更容易操作的。
其他回答
以餐厅为例。“今天的饭菜”的创建是一种工厂模式,因为您告诉厨房“给我今天的饭菜”,然后厨房(工厂)根据隐藏的标准决定生成什么对象。
如果你订购了一个定制的披萨,建造者就会出现。在这种情况下,服务员告诉厨师(建筑工人)“我需要一个披萨;加奶酪、洋葱和培根!”因此,构建器公开了生成的对象应该具有的属性,但隐藏了如何设置这些属性。
我在自制消息库中使用了builder。库核心从线路接收数据,用Builder实例收集数据,然后,一旦Builder确定它已经获得了创建Message实例所需的一切,Builder. getmessage()就使用从线路收集的数据构造消息实例。
在浏览微软MVC框架时,我对构建器模式有了一些想法。我在ControllerBuilder类中遇到了这种模式。这个类返回控制器工厂类,然后用它来构建具体的控制器。
我认为使用构建器模式的优点是,您可以创建自己的工厂并将其插入到框架中。
@Tetha,可以有一家意大利人开的餐厅(框架),供应披萨。为了准备披萨,Italian guy (Object Builder)使用Owen (Factory)和一个披萨基(基类)。
现在印度人从意大利人手里接管了餐厅。印度餐厅(框架)提供dosa而不是披萨。为了准备dosa, Indian guy(对象构建器)使用fried Pan(工厂)和Maida(基类)
如果你看场景,食物是不同的,食物的制作方式是不同的,但在同一家餐厅(在同一框架下)。餐馆应该以这样一种方式建造,它可以支持中国菜、墨西哥菜或任何菜。框架内的对象构建器有助于你想要的插件料理。例如
class RestaurantObjectBuilder
{
IFactory _factory = new DefaultFoodFactory();
//This can be used when you want to plugin the
public void SetFoodFactory(IFactory customFactory)
{
_factory = customFactory;
}
public IFactory GetFoodFactory()
{
return _factory;
}
}
在前面的回答(双关语)的基础上,有一个很好的现实例子,就是Groovy对Builders的内置支持。
使用Groovy的MarkupBuilder创建XML 使用Groovy的StreamingMarkupBuilder创建XML Swing构建器 SwingXBuilder
请参阅Groovy文档中的构建器
我一直不喜欢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");
现在我们有了一个整洁的单一类,它管理自己的初始化,做的工作与构建器几乎相同,只是它要优雅得多。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap