【问题标题】:Differences between builder pattern and template method (builder vs template)构建器模式和模板方法之间的差异(构建器与模板)
【发布时间】:2022-02-22 11:07:54
【问题描述】:

模板模式在基类中提供算法,其步骤可以在派生类中修改。 在 Builder 模式中,具体的 builder 公开了用于构建产品的方法,这些方法是从 Director 类中调用的。

我了解使用这些模式的目的有所不同。模板模式是一种行为模式,它改变模板中的一个或多个步骤,而构建器模式是一种创建模式。

除了上面说的不同,还有其他的不同吗?

生成器模式中的主管不是作为模板模式中的基本模板。具体构建器的行为类似于模板模式中的派生类,具有可替换的步骤?

有人可以澄清一下吗?谢谢。

我指的是http://www.dofactory.com/Patterns/Patterns.aspx

【问题讨论】:

    标签: design-patterns builder template-method-pattern


    【解决方案1】:

    模板方法实际上只是一种定义每个子类必须定义的一些方法的方法。

    构建器模式用于构造更复杂的对象。

    假设我们要构建不同的 Saab(汽车品牌)模型。每个型号都有不同的引擎、灯光等。

    如果我们要使用模板方法模式,我们必须为每个单独的汽车组合创建一个类,或者使用一些讨厌的继承层次结构。很多这些方法也会包含重复的代码。

    通过构建模式,我们可以取而代之的是,将不同的部分组合在一起,形成一辆完整的汽车。因此,如果需要,我们可以为每个模型重用一个引擎,我们还可以定制汽车的每个部分。

    【讨论】:

    • 感谢 jgauffin。一个与builder中的主管如何工作有关的问题。导演不是有步骤以特定顺序创建对象吗?如果建筑商想要更改订单怎么办?我指的是这里提供的示例dofactory.com/Patterns/PatternBuilder.aspx#_self1
    • 好吧。然后你打破了 Liskovs 替代原则,应该重新设计你的代码;)
    【解决方案2】:

    我发现同样的问题很有趣。

    萨博汽车的例子很有趣,但它不符合“四人组”(设计模式)中对建造者模式的描述。

    我将使用“四人帮”的术语。

    在四人组中,每次调用aDirector->Construct() 都不能混合混凝土建造者,所以 Saab 的例子虽然很有趣,但对我来说并没有真正回答这个问题。

    我看到了一些:

    director 对象与构建器层次结构的分离是一个关键区别。在模板工厂中,体现通用流程的方法和被覆盖的方法都是同一类的成员。这使得 Builder 模式能够更好地封装流程的内部阶段,因为如果只访问 Director 对象,客户端代码就不太可能接触到这些方法。构建器模式还允许完全独立于构建器层次结构来制定组装过程,从而允许在需要时更灵活地替换构建器实例。例如,一旦您手头有一个 director 实例,您就可以轻松地构建产品的多个表示,每次都动态替换具体的构建器。因此构建器更加动态,更好地封装了具体构建器的内部工作。

    此外,如果您想通过继承来详细说明 Director 对象,您可以这样做而无需增加您的层次结构。例如,您可能有一个明确的构建过程,以在最终构建之前节省时间 - 您可以对 Director 对象进行子类化,甚至在其本身上使用“模板方法”来通过继承对其进行自定义,而无需重新实现您的具体构建器。

    但这导致我们考虑另一种与“模板工厂”密切相关的模式——“策略”模式。

    策略与模板工厂非常相似,有两个明显的区别:它也将上下文对象与策略层次结构分开,允许在运行时为单个问题实例切换算法。另一个不同之处在于,这些示例似乎表明调用策略不一定涉及“模板方法”中的复杂或结构化过程。

    但我把它带到这里是为了与 Builder 类似,以达到另一点 - 如果“策略”在其类结构中与 Builder 平行,那么与“模板方法”平行的创建模式应该是“工厂方法”。这一点很清楚,不仅是名称,而且有趣的是,本书的“工厂方法”和“模板方法”两章的讨论都使用了几乎相同的示例(用于编辑文档的应用程序)。

    所以,不讨论创建模式和行为模式有什么区别,我倾向于认为 Builder 和 Factory Method 基本上分别是 Strategy 和 Template Method 的具体案例和改进。

    所以问题变成了——如果你看不出 Builder 和 Template Factory 之间的区别——试着回答这些问题:

    1. 您更喜欢对系统的特定部分有什么看法?是“行为”还是“创造”?和

    2. 一方面,您是否需要强大的封装,或者构建器实例的动态替换、部署或调整,或者您是否期望复杂性(通过继承、组合或其他方式)围绕创建过程或模板方法?如果这些问题的答案与构建器/策略结构有关。否则,在 XX 方法模式中使用简单的关系或行为多态。

    【讨论】:

      【解决方案3】:

      在我开始之前,我的所有答案的通用路线:“任何语言的任何编程概念都需要从三个方面理解。(a)从设计角度(b)运行时角度(c)从内存角度。

      话虽如此,基于 (a) 给出答案的人可能与 (b) 不一致,反之亦然(或者可能有人会给出循环解释以污染明确的定义)。 Pizza builder、Restaurant builder、Car builder 或 UI 模板、工作流模板在企业项目中被要求实现 Builder/Template 模式时没有任何意义(可能这些模式还不够成熟,无法自行定义)。失败的原因是如果我知道某些对象必须分 4 步构建,那么为什么我会从空开始实例化它并使用 director 一步一步地填充它。如果我不希望第 3 步或第 2 步发生太多异常会发生什么。相反,我将在完成所有 4 个步骤后创建最终对象(这在我的整个职业生涯中都发生过,这就是为什么构建器模式是未被开发人员采用)。在这里,人们可能会在需要异步行为的分布式系统中争论,然后 Builder 可以提供帮助;但如果是这种情况,那么我仍然会依赖 onreadystatechange==4 然后实例化我的builderObj。所以我们不应该使用 Builder 吗?恕我直言,答案是“否”。

      我的理解是在.net中我们有ControllerBuilder、SqlConnectionStringBuilder、UriBuilder;都在定制ControllerFactory、Sql、Uri Factory;然后我的主程序可以使用这些工厂来生成 Controllers、ConnStrings、Uries。那么 Builder 模式是用于工厂设置定制的吗?我们需要工厂设置定制吗?可能永远不会;相反,我会做的最好的事情是创建 4 个异步方法并使用步骤 2 参数链接它们(在第二个链接步骤 3 参数中......)。什么 abt 模板模式(asp.net 工作流模板或 jQuery 模板或罐装模板)。对我来说,两者都是相同的,但与 builder 相比,模板本质上更加严格(几乎所有东西都固定了,很少有属性会改变以定义特定的 tmplt),一旦定义了模板,然后是工厂。我还看到关于这两个的另一个谣言是能够“任何工厂->任何产品”为When would you use the Builder Pattern?;但这不是真的,因为它类似于上面 .net ControllerBuilder、sql、uri 场景,带有“Factory of Factory”的概念。这违反了许多设计原则(SRP、LSP、不良封装)。希望我关于这两个的完整文章能从初学者到高级。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多