5

我认为流畅的界面对于许多任务来说非常方便。但是当我最终将流利的方法和修改方法混合在一个类中时,我感到不安。

只是一个例子(有点做作,请多多包涵):

假设一个字符串实用程序类,修剪似乎有利于链接:

Str & Str::Trim() { return TrimLeft().TrimRight(); }

其他方法自然会返回一个新对象:

Str Str::GetFirstToken() const
{ 
   // result = first token;
   return result;
}

还有第三种类型,它本身会在逻辑上改变对象返回一个新对象:

Str Str::SplitFirstToken() 
{ 
   result = GetFirstToken();
   // this = remainder
   return result;
}

当我单独使用每个方法最明显的签名时,我最终得到了这三种类型,我担心使用哪个类不是很直观,特别是因为返回类型是 mroe 或更少相同。


我已经决定Str不做不可变的——因为像SplitToken提供核心功能这样的方法。我的主要问题是混合流利的方法你会怎么做?

  • 不要在该接口中使用流利的方法

  • 将它们移动到子界面(见下文)

  • “如果一个人流利,所有修改方法都应该流利”?

  • 对流利的方法使用 seocific 前缀?

  • 不用担心?

  • ???

子界面思路:

void CStr::Trim() { TrimLeft(); TrimRight(); }
CStrFluent & Str::Fluent() { return CStrFluent(*this); }
....
str.Fluent().TrimLeft().TrimRight();

我对此犹豫不决,我真的不喜欢额外的“流利”——尤其是它是 C++ 中的方法调用

你怎么看?

[编辑] 我在这里使用“流利”的基本含义是在单个实例上链接方法调用,而不是在代码中创建英语句子的高级意义。

4

1 回答 1

3

我没有用流畅的接口做太多的工作(虽然我一般都玩过 DSL),但在我看来,虽然这个类可能适合这种方法,但在这种情况下它并不是特别必要的。也许我遗漏了一些东西,但在我看来,您不太可能在一个字符串上执行一堆操作而不参考其他任何内容,这就是您在这里得到的结果。此外,您正在转换到链中间的新对象,这似乎再次违反了流畅接口的目的,特别是当您考虑在此链中发生的情况时:

Str String = OtherString.GetFirstToken().SplitFirstToken().Trim();

我认为也许这种类型的相对低级的实用程序类是尝试流畅接口的错误场所。在我看来,当你的对象受到持久的、集中的关注时,流畅性似乎比它们是短暂的和附属于核心逻辑的时候更重要。

于 2009-07-08T16:27:52.617 回答