繁体   English   中英

流畅的界面和 Builder 模式有什么区别?

[英]What is the difference between a fluent interface and the Builder pattern?

我对设计模式很陌生,并且在流畅的界面和 Builder 模式之间的区别上遇到了麻烦。

我理解流畅接口的概念。 但是构建器模式有点令人困惑。 我无法理解在 Builder 模式中使用 Director。

我可以同时使用 Builder 模式和 Fluent Interface 吗? 如果是这样,那么我应该如何与导演和混凝土建造者一起这样做?

我的问题不是关于构建器模式的优势。 但是这个问题的目的是了解构建器模式和流畅界面之间的关系。


使用来自 GoF 的 Builder 的 UML 序列图进行编辑:

带导演的序列图

Fluent Interfaces语义门面 您将它们放在现有代码之上,以减少语法噪音并更清楚地表达代码在无处不在的语言中的作用。 这是构建内部领域特定语言时使用的模式。 这是关于可读性的。

导演/建造者精心策划某物的建造。 也就是说,如果您正在构建比萨烘焙机,主管将确保从订单到比萨的步骤由正确的构建者以正确的顺序使用正确的数据执行。 这是关于验证和委托。

您当然可以将 Fluent Interface 放在 Director/Builder 模式之上,以使其更流畅地阅读并强调领域概念(相对于构建和委托的技术过程)。 那可能是一个表达式生成器

我想强调的是 Fluent Interfaces 不仅仅是Method Chaining 这是一个普遍的误解。 方法链是实现 Fluent Interface 的一种方法,但它不一样,因为它缺乏语义质量,例如这不是 Fluent Interface:

SomeObject.setFoo(1).setBar(2).setBaz(3);

上面没有表达任何关于 SomeObject 的内容。 它不是某种语义模型之上的外观。 这只是一些链接的方法。 Fluent Interface 的一个例子是 SQL 查询构建器,例如

SQLBuilder.select('foo').from('bar').where('foo = ?', 42).prepare();

在该 API 的底层是创建 SQL 语句的代码。 它可能包含多个对象,显示的调用可以很好地创建一个 Select 对象,在其上调用一个 setter,创建一个 Condition 对象并将其应用于 Select 对象,最后返回一个 Statement 对象。 但这一切都对我们隐藏。 这也突出了 Fluent Interfaces 的另一个方面:它们可能违反SOLIDDemeter 定律 但由于它是代码之上的外观,希望遵循这些设计原则,所以它并不重要,因为您将违规行为本地化到 Fluent Interface。

Fluent 接口背后的想法是,可以通过将多个属性用点连接来将多个属性应用于对象,而不必每次都重新指定对象。 构建器模式背后的想法是,非共享可变对象通常比非共享不可变对象更容易使用,但与共享可变对象相比,共享不可变对象更容易推理。 因此,代码可以使用一个易于使用的可变对象来生成所需实例的“模型”,然后使用它来创建一个易于共享的、包含相同数据的不可变对象。

这两个想法可以很好地协同工作,但有些正交。

请注意,流畅的界面至少可以通过三种方式工作:

  • 通过让实例的每个成员返回一个应用了适当更改的新实例。
  • 通过让每个成员改变调用它的实例并返回它。
  • 通过让每个成员返回一个轻量级补丁对象的实例,该对象包含指向正在修改的事物或前一个补丁的链接。

最后一种风格需要采取一些行动来应用所有补丁,但如果被修改的对象很大并且需要进行很多更改,它可以最大限度地减少所需的复制量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM