【问题标题】:The advantage / disadvantage of private variables?私有变量的优点/缺点?
【发布时间】:2011-09-08 17:42:18
【问题描述】:

我习惯于将几乎所有的类变量设为私有并创建获取/设置它们的“包装”函数:

class Something{
  private $var;

  function getVar(){
    $return $this->var;
  }

}

$smth = new Something();
echo $smth->getVar();

我看到很多人都这样做,所以我最终也这样做了:)

以这种方式使用它们是否有任何优势:

class Something{
  public $var;
}
$smth = new Something();
echp $smth->var;

?

我知道私有意味着你不能直接在课堂之外访问它们,但对我来说,如果可以从任何地方访问变量似乎并不重要......

那么,私有变量是否还有其他隐藏的优势?

【问题讨论】:

标签: php class variables private public


【解决方案1】:

它被称为encapsulation,这是一个非常好的东西。封装将您的类与其他使用其内部的类隔离开来,它们只能通过您的方法获得您允许的访问权限。它还保护它们免受您可能对类内部进行的更改。如果您对变量的名称或用法进行更改,则如果没有封装,该更改会传播到使用该变量的所有其他类。如果你强迫他们通过一个方法,你至少有机会处理方法的变化并保护其他类免受变化。

【讨论】:

    【解决方案2】:

    如果您想将私有变量与公共 getter 和 setter 一起使用,或者您只想将变量直接声明为公共,则因情况而异。

    使用“getters”和“setters”可能更好的原因是如果您想控制某人何时访问数据。

    举个例子,假设你得到了这个:

    public setBirthday($date)
    

    然后您可以确保传递给该 setter 的日期是有效的生日。

    但是如果你只是像这样将变量声明为公共的,你就不能这样做

    public $birthday;
    

    基于 cmets。

    此外,如果您决定更改 从内部存储机制 包含日期的字符串 自 1970 年 1 月 1 日以来的秒数,您 仍然可以在外部显示日期 如果你用同样的方式 封装,但如果你暴露 直接变量。每一块 触及内部的代码 直接变量现在会被破坏。

    这意味着如果内部存储机制从 1970 年 1 月 1 日起更改为秒数,那么您不必更改“外部 API”。原因是你可以完全控制它:

    public getBirthday() {
      // you can still return a string formatted date, even though your 
      // private variable contains number of seconds from 1/1/1970
    }
    

    【讨论】:

    • 此外,如果您决定将内部存储机制从包含日期的字符串更改为自 1970 年 1 月 1 日以来的秒数,您仍然可以使用相同的方式在外部显示日期封装,但如果您直接公开变量,则不会。现在,每段直接触及内部变量的代码都会被破坏。
    【解决方案3】:

    访问修饰符在脚本语言中没有多大意义。许多实际的面向对象语言(如 Python 或 Javascript)没有它们。

    天真的 getter/setter 方法的流行仅仅是因为 PHP 没有为此提供明确的构造。 http://berryllium.nl/2011/02/getters-and-setters-evil-or-necessary-evil/

    【讨论】:

    • 它们在执行时非常有意义,就像在其他语言中一样。
    • 它们的过度使用通常表明对核心 OOP 概念的误解,例如消息传递和封装的目的。
    • @mario:我不同意,所有实例化的变量都应该有一个访问修饰符,如果没有别的,请注意它们的范围。
    • 这只是一个意见。我看不出有多少实用价值。而且我只会将属性声明为受保护或私有当且仅当存在实际原因。习惯性语法结构的使用不会提高代码质量。
    • @mario:任何有选择的东西都​​意味着一种观点。如果您没有列出访问修饰符,则编译器会假定默认值,依赖编译器默认值而不是明确说明某些内容是不干净的,因为它需要键入特定的内容。
    【解决方案4】:

    这是为了将类实现内部的变量与用于外部更改的变量区分开来。还有protected 变量,供内部使用,并由类的扩展使用。

    我们将变量设置为private,这样只有类内的代码才能修改变量,保护免受外部干扰,保证变量的控制和预期行为。

    【讨论】:

      【解决方案5】:

      封装的目的是向其他对象隐藏对象的内部。这个想法是对象的外部足迹构成了它的定义类型,将其视为与其他对象的合同。在内部,它可能需要跳过一些环节才能提供面向外部的功能,但这与其他对象无关。他们应该不能乱来。

      例如,假设您有一个提供销售税计算的类。基本上是某种实用服务对象。它有一些提供必要功能的方法。

      在内部,该类正在访问数据库以获取一些值(例如,给定司法管辖区的税)以执行计算。它可能在内部维护数据库连接和其他与数据库相关的事情,但其他类不需要知道这一点。其他类只关心面向外部的功能契约。

      假设以后某个时候需要用外部 Web 服务替换数据库。 (该公司正在提供一项计算销售税的服务,而不是在内部维护它。)。因为该类是封装的,所以您可以很容易地更改其内部实现以使用服务而不是数据库。该类只需要继续提供相同的外向功能。

      如果其他类在处理该类的内部结构,那么重新实现它可能会破坏系统的其他部分。

      【讨论】:

        猜你喜欢
        • 2013-11-30
        • 1970-01-01
        • 2011-10-23
        • 2018-08-26
        • 1970-01-01
        • 2011-07-18
        • 1970-01-01
        • 1970-01-01
        • 2017-02-24
        相关资源
        最近更新 更多