1

我很难做出这个设计决定。

我可以使用传统new语言构造来初始化对象,并通过变量使用它们,例如:

$o = new Object('arg');
$o->method();
$o->property = 'value';
$o->save();

或者我可以选择工厂模式和积极的可链接性,例如

Object::new('arg')->method()->setProperty('value')->save();

这将导致

  • 更少的 LOC 到
    • 读,
    • 维持,
    • 重构,
  • 无需命名变量。

但是,我不确定这是否是一种可接受的方法,以及我是否忘记考虑某些事情。

请表达您的担忧或同意,并指导我如何做出决定。

4

4 回答 4

3

我对最近流行的 Fluent Interface 的看法很复杂。

对我来说,当整个方法链从头到尾表达一个单一的概念时,流畅的接口是有意义的。例如:

var SuperLate = (new Coffee()).AddMocha().AddCream().Invert().Blend();

每个步骤都需要链的上下文才能理解,并且链中方法的执行顺序很重要。如果在 Invert() 之前调用 Blend(),就会出现混乱。

在您的示例中,接口的方法之间几乎没有时间耦合。设置属性和执行方法不应依赖于顺序。我相信为例行方法调用和属性操作引入一个流畅的接口只会增加接口的复杂性,同时给人一种时间耦合的感觉。

另外,增加一个 fluent 接口增加了每个方法之间的耦合,因为它们现在相互依赖于彼此的返回值。当每种方法仅表达整体概念的一部分时(例如制作咖啡的步骤),这种耦合是有意义的,但当每种方法单独存在时,可能会阻碍未来的重构。

虽然它可能更冗长,但我不建议为例程方法调用和属性设置引入流畅的接口。

于 2009-11-09T17:39:54.863 回答
1

我是你的“可链式”设计的忠实粉丝。这种设计有时被称为Fluent Interface

于 2009-11-09T17:13:47.093 回答
1

流畅界面的好处在于,代码的核心不会在额外的语法管道中丢失,从而更容易阅读。然而,与逐行程序方法相比,它是一个不太熟悉的习语,而且没有那么普遍;例如,并非所有代码结构都适合这种风格

if (something) $o->method();

不会翻译得那么干净。因此,如果这样的事情是典型的,它可能不太合适。

还要考虑将围绕它的其他代码的上下文。如果代码将主要是这些样板样板看起来像

$o = new Object('arg');
$o->method();
$o->property = 'value';
$o->save();

那么让它们更简洁肯定是一种改进。但是,如果这样的代码会在不同风格的许多其他代码中丢失,也许不会。

如果它看起来可能是一个好主意,我会说去吧。如果效果不好,切换回来的小努力将值得学习经验。

于 2009-11-09T21:10:50.523 回答
0

为什么没有多个构造函数来获取初始化值。所以你会有:

Object::new()
Object::new('arg1')
Object::new('arg1','arg2')

等等

于 2009-11-09T17:12:08.743 回答