Builder设计模式和Factory设计模式之间的区别是什么?

哪一种更有利?为什么?

如果我想测试和比较/对比这些模式,我如何将我的发现表示为图表?


当前回答

与工厂模式相比,构建器模式的主要优势在于,如果您希望创建一些具有大量可能自定义的标准对象,但最终通常只能自定义少数对象。

例如,如果你想写一个HTTP客户端,你将设置一些默认参数,比如默认的写/读超时、协议、缓存、DNS、拦截器等。

客户端的大多数用户将只使用这些默认参数,而其他一些用户可能希望自定义一些其他参数。在某些情况下,您只需要更改超时并按原样使用其余部分,而在其他情况下,可能需要自定义例如缓存。

以下是实例化客户端的可能方法(取自OkHttpClient):

//just give me the default stuff
HttpClient.Builder().build()   

//I want to use custom cache
HttpClient.Builder().cache(MyCache()).build() 

//I want custom connection timeout
HttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS).build() 

//I am more interested in read/write timeout
HttpClient.Builder()
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS).build()

如果你使用一个工厂模式,你最终会写出很多方法,包括所有可能的创造参数组合。对于构建器,您只需指定您关心的参数,并让构建器为您构建它,同时考虑所有其他参数。

其他回答

生成器和抽象工厂有着不同的目的。根据正确的用例,您必须选择合适的设计模式。

生成器的显著特点:

生成器模式使用简单对象和分步方法构建复杂对象生成器类逐步构建最终对象。此生成器独立于其他对象在这种情况下替换为Factory方法/抽象工厂:从客户端程序传递给Factory类的参数太多,容易出错某些参数可能是可选的,不像工厂中强制发送所有参数

工厂(简单工厂)的显著特点:

创建型模式基于继承Factory返回一个Factory方法(接口),然后返回具体对象您可以用新的具体对象替换接口,客户端(调用者)不应该知道所有具体实现客户端始终只访问接口,您可以在Factory方法中隐藏对象创建详细信息。

通常,设计从使用工厂方法(不那么复杂,更可定制,子类激增)开始,并向抽象工厂、原型或生成器(更灵活,更复杂)发展

查看相关帖子:

将生成器保持在单独的类中(流畅的接口)

设计模式:工厂vs工厂方法vs抽象工厂

有关详细信息,请参阅以下文章:

资源制造

日志记录设备

复杂构造是指要构造的对象由抽象表示的不同的其他对象组成。

考虑麦当劳的菜单。菜单包括饮料、主菜和配菜。根据单个抽象的后代组合在一起,创建的菜单具有另一种表示。

例如:可乐、巨无霸、薯条示例:雪碧、掘金、卷曲薯条

在那里,我们得到了两个具有不同表示的菜单实例。施工过程保持不变。您可以创建一个菜单,其中包含饮料、主菜单和副菜单。

通过使用生成器模式,可以将创建复杂对象的算法与用于创建它的不同组件分开。

就构建器模式而言,算法封装在控制器中,而构建器用于创建完整的部分。在控制器的算法中改变使用的生成器会导致不同的表示,因为其他部分都是由菜单组成的。菜单的创建方式保持不变。

两者非常相似,但如果您有大量用于对象创建的参数,其中一些参数是可选的,并且具有一些默认值,请选择生成器模式。

工厂模式允许您一次创建一个对象,而生成器模式允许您中断对象的创建过程。这样,您可以在创建对象期间添加不同的功能。

构建器设计模式描述了一个对象,该对象知道如何在几个步骤中创建另一个特定类型的对象。它在每个中间步骤保持目标项所需的状态。想想StringBuilder是如何生成最终字符串的。

工厂设计模式描述了一个对象,该对象知道如何在一个步骤中创建几种不同但相关的对象,其中特定类型是基于给定参数选择的。想想串行化系统,在这里创建串行化器,它在一次加载调用中构造所需的in对象。