在一个类中混合流畅和不流畅的界面

pet*_*hen 5 class-design fluent-interface

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

只是一个例子(这有点做作,请耐心等待):

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

Str & Str::Trim() { return TrimLeft().TrimRight(); }
Run Code Online (Sandbox Code Playgroud)

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

Str Str::GetFirstToken() const
{ 
   // result = first token;
   return result;
}
Run Code Online (Sandbox Code Playgroud)

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

Str Str::SplitFirstToken() 
{ 
   result = GetFirstToken();
   // this = remainder
   return result;
}
Run Code Online (Sandbox Code Playgroud)

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


我已经决定Str不做不可变 - 因为SplitToken提供核心功能的方法.我的主要问题是混合流畅的方法你会做什么?

  • 不要在该界面中使用流畅的方法

  • 将它们移动到子接口(见下文)

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

  • 为流畅的方法使用一个seocific前缀?

  • 别担心?

  • ???

子接口的想法:

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

我对此犹豫不决,我真的不喜欢额外的"流畅" - 尤其是它是C++中的方法调用

你怎么看?

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

Mik*_*ton 3

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

Str String = OtherString.GetFirstToken().SplitFirstToken().Trim();
Run Code Online (Sandbox Code Playgroud)

我认为也许这种类型的相对低级的实用程序类不是尝试流畅界面的错误地方。在我看来,当你的对象受到持久、集中的关注时,流畅性似乎比它们短暂且辅助于核心逻辑时更重要。