7

如果替代函数名称使 API 更明显,那么放弃 getter 和 setter 的“getMyValue()”和“setMyValue()”模式是否合适?

例如,假设我在 C++ 中有这个类:


public class SomeClass {
private:
    bool mIsVisible;

public:
    void draw();
    void erase();
}

我可以像这样添加函数来获取/设置“mIsVisible”:


bool getVisible() { return mIsVisible; };

void setVisible(bool visible) { if (!mIsVisible && visible) { draw(); } else if (mIsVisible && !visible) { erase(); }

mIsVisible = visible;

}

但是,同样可以使用以下方法:


bool isVisible() { return mIsVisible; };

void show() { 
    if (!mIsVisible) {
        mIsVisible = true;
        draw();
    }
}

void hide() {
    if (mIsVisible) {
        mIsVisible = false;
        erase();
    }
}

简而言之,最好有一个“setVisible(bool)”方法还是一对“show()”和“hide()”方法?有没有约定,还是纯粹是主观的东西?

4

10 回答 10

13

阅读Pragmatic Programmers 网站上的文章“ Tell, Don't Ask ”,我想您会看到第二个示例是可行的方法。

基本上,您不应该通过您的第一个示例所暗示的代码将逻辑传播出去,即:

  1. 获取当前可见性值,
  2. 根据价值做出决定,
  3. 更新对象。
于 2008-10-06T17:12:45.247 回答
5

在你给出的例子中show()hide()至少对我来说很有意义。

另一方面,如果你有一个属性skinPigment并且你决定调用函数tanMe()makeAlbino()那将是一个非常糟糕、不明显的选择。

这是主观的,您必须尝试以您的用户(使用此类的人)的方式思考。无论您决定采用哪种方式,对他们来说都应该是显而易见的,并且有据可查。

于 2008-10-06T17:08:54.193 回答
3

我会选择 isVisible()/show()/hide() 集。

setVisible() 意味着它所做的一切都会改变内部变量。show() 和 hide() 使副作用变得清晰。

另一方面,如果 getVisible()/setVisible() 所做的只是更改内部变量,那么将它们作为公共字段所做的改变非常小。

于 2008-10-06T17:39:25.817 回答
3

setter 实际上与面向对象关系不大,这是示例中应用的编程习惯。吸气剂稍微好一点,但在很多情况下可以不用吸气剂。如果一切都可以得到和设置,那么拥有一个对象有什么意义呢?应该在对象上调用操作来完成事情,改变内部状态只是这样做的副作用。在存在多态性(OO 的基石之一)的情况下,setter 的坏处是您强制每个派生类都有一个 setter。如果所讨论的对象不需要名为 mIsVisible 的内部状态怎么办?当然,他可以忽略该调用并将其实现为空,但随后您将进行无意义的操作。OTOH,显示和隐藏等操作可以很容易地被不同的实现覆盖,

于 2008-10-06T17:48:55.843 回答
2

一般来说,我认为 setter/getter 应该只设置属性的值。在您的示例中,您还根据 isVisible 属性的值执行操作。在这种情况下,我认为使用函数来执行操作和更新状态比使用 setter/getter 作为更新属性的副作用来执行操作要好。

于 2008-10-06T17:20:13.827 回答
2

如果切换 mIsVisible 确实会立即打开和关闭对象的可见性,则使用显示/隐藏场景。如果它将在旧状态中停留更长时间(例如,直到其他事情触发重绘),那么设置/获取场景将是可行的方法。

于 2008-10-06T17:23:24.100 回答
1

我更喜欢 show() 和 hide() 方法,因为它们明确地告诉你要做什么。setVisible(boolean) 不会告诉您该方法是否会立即显示/绘制。加上 show() 和 hide() 是更好命名的接口方法(恕我直言)。

于 2008-10-06T17:20:51.110 回答
0

隐含地,您列出的“显示”和“隐藏”功能都是二传手

对于布尔值,我认为像您展示的单个工具会很好。但是,.show 和 .hide 函数也看起来像命令,而不是改变对象状态的函数。

于 2008-10-06T17:11:27.823 回答
0

在这种情况下,您实际上必须编写类似的代码

if (shouldBeShowingAccordingToBusinessLogic()) w.show();
else w.hide();

到处都是,你可能会更好

w.showIfAndOnlyIf(shouldBeShowingAccordingToBusinessLogic())

或者,对于真正奇怪的情况,当您的逻辑无法决定是否要使用单桅帆船直到某些代码延伸结束时,您可以尝试

w.setPostponedVisibility(shouldBeShowingAccordingToBusinessLogic());
...
w.realizeVisibility();

(我不是说很奇怪吗?)

于 2008-10-06T18:05:34.330 回答
0

选择显示/隐藏解决方案的另一个动机是,作为二传手,

setVisible方法有一个“副作用”,因为它还显示或隐藏SomeClass. 显示/隐藏方法更好地传达了所发生事情的意图。

于 2008-10-06T18:06:31.910 回答