假设我们正在用C ++写一个GUI工具包(尽管这个问题可能也适用于其他语言)。我们有一个带有成员函数hide的按钮类,该函数隐藏了按钮。该成员函数使用布尔参数animated来控制是否应使用动画隐藏按钮。

class Button {
public:
  // Rule of three, etc…

  void hide(bool animated);
};


调用此成员函数时,可能不清楚它的含义。

Button button;
button.hide(false); // well, does it hide the button or not?
                    // what does "false" even mean here?!



我们可以使用布尔枚举来重写它。

class Button {
public:
  // Rule of three, etc…

  enum Animated : bool {
    Animate = true,
    DoNotAnimate = false,
  };
  void hide(Animated animated);
};


现在如果我们称呼它,一切将变得更加清晰。

Button button;
button.hide(Button::DoNotAnimate);



这是一件好事吗?它会提高代码的清晰度,还是只是过大了?我们应该为此使用单独的文档(类似Doxygen)吗?

评论

我不知道它们是否在C ++中,但是不需要定义新类型的一个很好的替代方法是使用命名参数。例如button.hide(animated:false);。否则,如果可能的话,尝试使用更多通用的枚举而不是过于具体的枚举可能是一个好主意,但我肯定会比hide(false)版本更喜欢它。另一种可能性是使用两个单独的命名方法,也许是hideWithAnimation和hideNoAnimation之类。

hide()应该隐藏按钮,并且不带参数。如果按钮需要知道隐藏自身的不同方法,则它们可能应该具有状态(例如setHideAnimationOn())或具有不同的类型(AnimatedButton与NormalButton),或者被不同的方法调用(hideWithAnimation()与hide())。

#1 楼

我认为枚举在这里是一个非常好的解决方案。在某种程度上,我不同意Johannes的观点,即使是单次使用,枚举也可以提高API的可读性和可发现性,而编写它可以忽略不计。而且我会警惕在他的示例中使用评论,他们会尖叫“ hack”。

评论


\ $ \ begingroup \ $
我认为保持一致是很好的(即,从不使用布尔枚举或始终使用布尔枚举),我同意这些意见。
\ $ \ endgroup \ $
–daknøk
2012年6月8日13:43



#2 楼

我认为提高代码的清晰度始终是一个好主意,而您的更改确实确实可以提高清晰度。引入该枚举。我是在这个问题上采用Clang实践的。

评论


\ $ \ begingroup \ $
它的确切价格是多少?微秒的编译时间?
\ $ \ endgroup \ $
–Kotauskas
19年8月16日在14:16

\ $ \ begingroup \ $
@Vla的代价是用枚举类型声明使代码混乱。 7年后,再加上7年的编程经验,我不太确定该断言的一般性。
\ $ \ endgroup \ $
– Johannes Schaub-小人
19年8月16日在20:14

\ $ \ begingroup \ $
嗯...我想说的是混乱的点,但布尔枚举通常足够小,可以压缩为单行并且仍然可读,因此使其不成问题。如果保证可见,则注释是有效的(例如,提供了脱机文档或提供了源代码),但通常不易从IDE获得注释。总体而言,我想说的是成本超过了收益。
\ $ \ endgroup \ $
–贾斯汀时间-恢复莫妮卡
19年8月21日在19:36

#3 楼

通常,我只支持布尔值的枚举,尤其是当您需要将一串“标志”传递给函数时,因为布尔值在此点变得不合理了。

案件和类似案件,尽管还有另一种选择; hide()show()是功能的“立即执行”版本,并且animate_hide()animate_show()异步执行相同的工作。之所以提出这一点,是因为我怀疑“组合”函数的主体在很大程度上是if / else语句:


#4 楼

如果该方法做一件事,那么在这种情况下,隐藏按钮根本不应该包含参数:void Hide()。相反,您可以创建仅显示按钮的方法void Show()。您甚至可以检查当前是否可见:bool IsVisible(),它仅返回成员bool的当前状态。成员void Show()void Hide()

定义:

class Button {
    public:
        //Other methods...
        void Show();
        void Hide();
        bool IsVisible();
    private: //or protected:, depending on your requirements
    //Other methods...
    void Visible(bool is_visible);
    //Other members...
    bool _visible;
};


实现:

void Button::Show() {
    Visible(true);
}

void Button::Hide() {
    Visible(false);
}

bool Button::IsVisible() {
    return _visible;
}

void Button::Visible(bool is_visible) {
    _visible = is_visible;
}


bool成员方法强制执行,只有一个函数负责更改void Visible(bool is_visible)成员并使其生效,因此,如果需求发生变化,则只需要更改一个地方。

所有这些方法都使该代码更加简洁,模棱两可。每种方法也只能做一件事。

评论


\ $ \ begingroup \ $
建议您阅读问题。该成员函数采用一个布尔型动画参数来控制是否应使用动画隐藏该按钮。
\ $ \ endgroup \ $
–daknøk
2012年6月8日15:57