【问题标题】:Access Modifiers ... Why?访问修饰符...为什么?
【发布时间】:2011-04-12 05:01:04
【问题描述】:

好吧,我只是在想,为什么程序员在谈到 OOP 中的 Access Modifiers 时会如此紧张。

让我们以这段代码为例/PHP!

class StackOverflow
{
    private var $web_address;

    public function setWebAddress(){/*...*/}
}

因为 web_address 是私有的,所以 $object->web_address = 'w.e.' 不能更改它,但变量只会更改的事实是,如果您的程序更改了 $object->web_address = 'w.e.';

如果在我的应用程序中我希望一个变量不被更改,那么我将创建我的应用程序,以便我的编程没有代码来更改它,因此它永远不会被更改?

所以我的问题是:使用私有/受保护/非公共实体的主要规则和原因是什么

【问题讨论】:

    标签: access-modifiers application-structure


    【解决方案1】:

    因为(理想情况下)一个类应该有两个部分:

    1. 向世界其他地方公开的界面,显示其他人如何与之交谈。文件句柄类中的示例:String read(int bytes)。当然这必须是公开的,我们类的(一个/那个)主要目的是提供这个功能。
    2. 内部状态,除了实例本身之外没有人应该(必须)关心。文件句柄类中的示例:private String buffer。这可以而且应该对世界其他地方隐藏:他们与它无关,这是一个实现细节。

    这甚至可以在没有访问修饰符的语言中完成,例如Python - 除了我们不强迫人们尊重隐私(请记住,他们总是可以使用反射 - 封装永远不会 100% 强制执行),但在私有成员前面加上 _ 表示“你不应该碰这个;如果您想弄乱它,请自行承担风险”。

    【讨论】:

      【解决方案2】:

      因为您可能不是项目中唯一的开发人员,而其他开发人员可能不知道他们不应该更改它。或者你可能会忘记等等。

      当你在做一些有人说是个坏主意的事情时,它可以很容易地发现(甚至编译器也能发现)。

      【讨论】:

      • @S.Lott:评论可能不会被阅读(或阅读并忘记),我认为如果某些内容是私有的,那么编写单元测试可能会更容易,因为您可以控制状态对象在被调用时就会存在,因此您可能不必编写尽可能多的测试(或不太复杂的测试)。
      • 总而言之,如果可能的话,我会尝试编写我的代码,假设我会将它交给一个完整的初学者来维护它,所以我尝试将它编写得尽可能简单可以正确使用。我认为最小化我的类的公共接口有助于避免以错误的方式使用它们,尤其是我遇到的太多开发人员似乎不喜欢阅读 cmets 或任何类型的文档:)
      • “评论可能不会被阅读” 多么可悲。寻找新的同事一起工作。
      【解决方案3】:

      所以我的问题是:使用私有/受保护/非公共实体的主要规则和原因是什么

      在 Python 中,没有访问修饰符。

      所以原因实际上是特定于语言的。您可能需要稍微更新您的问题以反映这一点。

      这是一个关于 Python 的相当普遍的问题。许多来自 Java 或 C++(或其他)背景的程序员喜欢深入思考这一点。当他们学习 Python 时,真的没有深入的思考。工作原理是

      我们都是成年人

      尚不清楚访问修饰符对谁有帮助。在 Lakos 的《大规模软件设计》一书中,对“受保护”进行了长时间的讨论,因为受保护的语义使子类和客户端接口有点模糊。

      http://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620

      【讨论】:

        【解决方案4】:

        访问修饰符是防御性编程策略的工具。你有意识地保护你的代码免受你自己的愚蠢错误(当你一段时间后忘记某些东西,没有正确理解某些东西或者只是没有喝足够的咖啡)。

        【讨论】:

          【解决方案5】:

          避免意外执行$object->web_address = 'w.e.';。目前这似乎没有必要,但如果

          • 两个月后,您想更改项目中的某些内容(忘记了 web_address 不应直接更改这一事实)或

          • 您的项目有数千行代码,您根本不记得“允许”直接设置哪个字段以及哪些字段需要 setter 方法。

          【讨论】:

            【解决方案6】:

            仅仅因为一个类有“一些东西”并不意味着它应该公开那个东西。该类应该实现它的契约/接口/你想调用它的任何东西,但是这样做它可以很容易地拥有不需要(并且无论如何不应该)在外部知道的各种内部成员/方法那个班的。

            当然,您可以编写应用程序的其余部分来处理它,但这并不是真正的好设计。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-09-14
              • 2015-11-26
              • 2014-06-09
              • 2016-07-18
              • 2020-02-05
              • 1970-01-01
              • 2011-01-15
              • 2013-12-14
              相关资源
              最近更新 更多