【问题标题】:Is it worth making get and set methods in OOP?是否值得在 OOP 中使用 get 和 set 方法?
【发布时间】:2012-05-16 10:41:15
【问题描述】:

我见过一些项目,其中类具有获取和设置方法来操作插入数据。让我在这里举个例子:

    class Student extends dbClass
{
    private $TableID;
    private $FullName;
    private $Gender;
    private $Address;




    function setTableID($Value)
    {
        $this->TableID = $Value;
    }

    function getTableID()
    {
        return $this->TableID;
    }

    function setFullName($Value)
    {
        $this->FullName = $Value;
    }

    function getFullName()
    {
        return $this->FullName;
    }

    function setGender($Value)
    {
        $this->Gender = $Value;
    }

    function getGender()
    {
        return $this->Gender;
    }

    function setAddress($Value)
    {
        $this->Address = $Value;
    }

    function getAddress()
    {
        return $this->Address;
    }


    function UpdateStudent()
    {
        $sql = "UPDATE INTO usertable SET
        FullName = '".$this->getFullName()."',
        Gender = '".$this->getGender()."',
        Address = '".$this->getAddress()."'
        where TableID='".$this->getTableID()."'";
        $this->query($sql);
    }
}

上面是我看到的示例类。以下是他们如何使用它的过程:

$student = new Student;
$student->setTableID = 1;
$student->setFullName('My Name');
$student->setGender('Male');
$student->setAddress('this is my address');

$studen->UpdateStudent();

这样做值得吗?我个人认为设置字段然后获取和更新其中的记录是没有用的。为每个模块制作它确实需要很多时间。处理这种事情的最佳方法是什么? 这样做是否有任何安全问题?

【问题讨论】:

标签: php oop get set


【解决方案1】:

这样做值得吗?

视情况而定。

通过公开“智能”属性(即 getter 和/或 setter)从用户那里提取字段有两个缺点:

  1. 您需要编写更多代码;如果该属性并没有真正做任何聪明的事情,那么这就是没有任何用处的代码。
  2. 该属性的用户有点不便,因为他们还必须输入更多内容。

而且它有一个优点:

  1. 将来您可以向属性添加逻辑,即使之前没有任何逻辑而不会破坏用户的代码

如果这个优势是有意义的(例如,您正在编写一个可重用的软件库),那么编写属性而不是裸字段就很有意义。如果没有,你就是在无用的工作。

处理这种事情最好的方法是什么?

您可以重写神奇的__get__set 函数(也许在基类中,这样您也可以继承重写)以自动将属性访问转发给您的getter 和setter。简化代码:

public function __get($name) {
    $getter = 'get'.$name;
    if (method_exists($this, $getter)) {
        return $this->$getter();
    }

    $message = sprintf('Class "%1$s" does not have a property named "%2$s" or a method named "%3$s".', get_class($this), $name, $getter);
    throw new \OutOfRangeException($message);
}

public function __set($name, $value) {
    $setter = 'set'.$name;
    if (method_exists($this, $setter)) {
        return $this->$setter($value);
    }

    $getter = 'get'.$name;
    if (method_exists($this, $getter)) {
        $message = sprintf('Implicit property "%2$s" of class "%1$s" cannot be set because it is read-only.', get_class($this), $name);
    }
    else {
        $message = sprintf('Class "%1$s" does not have a property named "%2$s" or a method named "%3$s".', get_class($this), $name, $setter);
    }
    throw new \OutOfRangeException($message);
}

警告:由于__get__set被覆盖,__isset__unset也应该被覆盖!

这样做有什么安全问题吗?

不,根本没有(假设您没有意外插入错误)。

【讨论】:

  • 我认为它不会有任何未来的逻辑。我新公司的人用它来执行数据库的事情。他们认为它是安全的。我不知道它是如何保护的。
  • @SalmanKhimani:人们不善于预测未来。如果是公司代码,请使用 getter 和 setter,不要回头。
【解决方案2】:

在没有属性(实际上导致函数调用的公共成员“变量”)的语言中,通常建议使用 getter/setter 而不是公共变量。否则,如果人们已经在使用您的普通字段,则您以后无法添加逻辑(例如,在设置变量时)。

由于 PHP 是这样一种语言(很遗憾),答案是是的,使用它们

【讨论】:

    【解决方案3】:

    制作 setter 和 getter 有助于强制执行 OOP 封装。我不确定 PHP,但对于许多其他语言(Java、C++),一个好的 IDE(eclipse/netbeans)会为你自动生成这些 setter 和 getter。

    对于简单类型可能不会立即明显,但如果必须执行任何更复杂的处理,那么它会变得更加明显。

    【讨论】:

    • 它们并没有真正改进 OOP 封装,而是一种语言中缺少 属性 的解决方法。
    • @ThiefMaster,我认为如果需要任何类型的逻辑/处理来存储值,它确实会有所帮助。
    • 是的,但它们仍然是一个令人讨厌的解决方法。例如,在 python 中,您可以使用公共变量,如果您需要额外的逻辑,只需创建一个 property (访问自定义 getter/setter 函数)。在 C# 中,您创建属性并让编译器在内部为其创建“简单”getter/setter(您永远不会看到它们,它们不是您可以直接调用的实际函数),如果您需要自定义逻辑,您只需实现这些函数靠自己。然而,访问属性——无论是否有 getter/setter——总是通过obj.prop 像变量一样完成
    • @ThiefMaster,严格来说,私有变量在 Python 中不存在,但这只是一个细节 :) 我理解你的意思,但在我通常编程的语言中,我更喜欢保留它们。一般来说,我总是喜欢为所有可以设置/获取的属性设置getter/setter,从而使类接口对于那些有逻辑的和没有逻辑的都是同质的。这也使类保持面向未来,因此您将来不必更改类接口。
    【解决方案4】:

    关于为什么有时使用 getter 和 setter 的示例: 我有在 200 个不同文件中设置值的代码:

    $cat->name = 'Fery'          // in file one
    $favoriteCat->name = 'Tery'  // in another file
    $fatCat->name = 'jery'             // in another file
    // 200 more calls in alot of places
    

    想象一下客户突然有一个新要求:“所有猫的名字都必须在前面加上‘Sweet’

    现在我们必须找到所有猫的声明并替换它们的赋值:

    $cat->name = 'Sweet '.'Fery'
    // times 200   
    

    另一方面,如果我们使用 setter 方法,我们需要做的就是在一个地方添加代码以添加“Sweet”:

    public function setCatname($catname)
    {
      $this->catName = 'Sweet ' . $catname;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-04
      • 2021-03-19
      • 1970-01-01
      相关资源
      最近更新 更多