2009-07-06 77 views
5

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

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

假设一个字符串的工具类,微调似乎不错的链接:

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

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

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

而且看到一只3型,即 - 本身 - 逻辑上发生变异的对象 RET瓮一个新问题:

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++

什么方法调用您认为?

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

回答

3

我没有用流畅的界面做过很多工作(尽管我一般都玩过DSL),但在我看来,尽管类可能适合这种方法,但在这种情况下并不是特别必要。也许我错过了一些东西,但是在我看来,你不可能在一个字符串上做一堆动作,而没有引用其他任何东西,这就是你在这里结束的东西。此外,你过渡到新的对象链,这似乎又违反了一个流畅的界面的目的,特别是当你考虑这个链条会发生什么中间:

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

我想也许是这种相对较低级别的实用程序类是尝试流畅接口的错误地方。当你的对象受到持续的,专注的关注时,流畅性似乎比在核心逻辑的瞬态和辅助时更重要。

+0

“你正在过渡到链中间的新对象” - 这正是我关心的核心,说得好!我会尽量摆脱现在没有链接,虽然firstName = line.SplitToken(...)。修剪()似乎是一个规范的事情。 – peterchen 2009-07-08 18:21:42