2

我刚刚开始学习 PHP OOP,之前我一直在以程序化的方式做 PHP。我正在阅读这篇文章,我有几个简单的问题,

  1. 通常如何定义值对象的构造函数?作为一个接受所有“数据成员”作为参数或坚持默认构造函数并使用 mutator/accessor 方法来设置/获取数据成员?

  2. 这实际上是开始执行 PHP OOP 的推荐方式吗?因为老实说,文章中解释的概念让我有点困惑。

干杯

4

2 回答 2

2

对象必须始终处于有效状态。这意味着对象总是行为(方法)并包含有意义的信息(成员变量)。构造函数的目的是创建处于有效状态的对象。

考虑到值对象,构造函数必须采用最少数量的参数,以使对象有意义。例如,如果您有一个 RGB 值对象,那么在您的应用程序中,如果红色是字符串“monkey”、绿色是 NULL、蓝色是一个数组,这是否有意义?

final class RGB {
    $r, $g, $b;
}

$mycolor = new RGB;

// NULL, what value of red is that supposed to be?
var_dump($mycolor->r);

// We are free to set these values too, even though they do not make sense.
$mycolor->r = 'monkey';
$mycolor->g = NULL;
$mycolor->b = array('foo', 'bar');

这正是这个对象允许发生的事情。$mycolor 引用了一个不处于有效状态的对象。我们如何确保一个 RGB 对象始终具有三个值,红色、蓝色和绿色,并且它们都是 0 到 255 之间的数字?

final class RGB {

    private $r;
    private $g;
    private $b;

    public function __construct($r, $g, $b) {

        // are our arguments numbers?

        if (!is_numeric($r)) {
            throw new Exception('Value of red must be a number');
        }
        if (!is_numeric($g)) {
            throw new Exception('Value of green must be a number');
        }
        if (!is_numeric($b)) {
            throw new Exception('Value of blue must be a number');
        }

        // are our arguments within range 0-255?

        if ($r < 0 || $r > 255) {
            throw new Exception('Value of red must be 0-255');
        }
        if ($g < 0 || $g > 255) {
            throw new Exception('Value of green must be 0-255');
        }
        if ($b < 0 || $b > 255) {
            throw new Exception('Value of blue must be 0-255');
        }

        // our arguments are fine.

        $this->r = $r;
        $this->g = $g;
        $this->b = $b;

    }

    //*// Canadian support

    public function getColour() {

        return $this->getColor();

    }

    public function getColor() {

        return array($this->r, $this->g, $this->b);

    }

}

$mycolor = new RGB;  // error! missing three arguments
$mycolor->r = 'monkey'; // error! this field is private

// exception! the constructor complains about our values not being numbers
$mycolor2 = new RGB('monkey', NULL, array('foo', 'bar'));

// exception! the constructor complains our numbers are not in range
$mycolor3 = new RGB(300, 256, -10);

$mycolor4 = new RGB(255, 0, 0); // ahh... a nice shade of red
var_dump($mycolor4->getColor()); // we can read it out later when we need to

如果您的构造函数需要三个参数,并且除非所有三个参数都是 0 到 255 之间的数字,否则它会引发异常,那么您将始终定义具有良好值的成员变量。

您还必须确保红色、蓝色和绿色成员变量是私有的。否则,任何人都可以为他们写任何他们想要的东西。当然,如果它们是私有的,也没有人可以阅读它们。为了创建一个只读操作,我们定义了 getColor() 方法来为我们访问私有成员变量。

此版本的 RGB 对象将始终具有有效状态。

希望这能对 OOP 的本质有所了解,并为您提供一个开始思考的地方。

于 2010-04-29T18:58:00.267 回答
1
  1. 要构建充当中性数据容器的对象,我将使用经典构造函数__contruct(),然后您可以使用魔法__get__set访问属性。例如,使用 db 行对象注入数据的另一种方法,您可以通过谷歌搜索“依赖注入”找到更多信息

  2. 您可以像在大多数 OOP 语言中一样通过 Main 类启动它,但对于 Web 问题,MVC 被广泛使用。

您以前有过 OOP 编程经验吗?

于 2010-04-29T15:59:30.413 回答