是否值得在 OOP 中制作获取和设置方法


Is it worth making get and set methods in OOP?

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

    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();

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

这样做值得吗?

这要看情况。

通过公开"智能"属性(即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也应该被覆盖!

这种方式这样做是否有任何安全保障?

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

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

由于PHP是这样的语言(不幸的是(,答案是肯定的,使用它们

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

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

为什么有时使用 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

想象一下,客户突然有一个新的要求:"所有的猫名都必须在前面加上'甜蜜'。

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

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

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

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