【问题标题】:Which is more appropriate: getters and setters or functions?哪个更合适:getter 和 setter 还是函数?
【发布时间】:2010-09-15 13:41:11
【问题描述】:

如果替代函数名称使 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()”方法?有没有约定俗成,还是纯属主观的东西?

【问题讨论】:

    标签: c++ coding-style setter getter


    【解决方案1】:

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

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

    1. 获取当前可见度值,
    2. 根据价值做出决定,
    3. 更新对象。

    【讨论】:

    • 作为“by the by”的副作用,可见性作为可嵌套的操作通常是有利的。换句话说,Show() 为您的可见性增加了一个,而 Hide() 则减少了一个。非负表示可见,负表示不可见。在这个模型中,你只需要 Show/Hide/IsVisible。
    【解决方案2】:

    在您给出的示例中,show()hide() 很有意义,至少对我而言。

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

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

    【讨论】:

      【解决方案3】:

      我会选择 isVisible()/show()/hide() 设置。

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              【解决方案7】:

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

              【讨论】:

                【解决方案8】:

                隐含地,您列出的“显示”和“隐藏”函数都是设置器

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

                【讨论】:

                • 非 'const' 的方法很可能会改变对象的状态。这正是面向对象背后的原因:您调用执行操作的操作,而不必担心对象的内部状态。
                【解决方案9】:

                如果您实际上必须编写类似

                的代码
                if (shouldBeShowingAccordingToBusinessLogic()) w.show();
                else w.hide();
                

                到处都是,你可能会更好

                w.showIfAndOnlyIf(shouldBeShowingAccordingToBusinessLogic())
                

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

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

                (我不是说很奇怪吗?)

                【讨论】:

                  【解决方案10】:

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

                  setVisible 方法有一个“副作用”,即它还会显示或隐藏SomeClass。 display/hide 方法可以更好地传达所发生事情的意图。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2021-03-15
                    • 1970-01-01
                    • 2011-10-21
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-07-30
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多