Концепции ООП PHP (объекты-значения / объекты доступа к данным) - PullRequest
2 голосов
/ 29 апреля 2010

Я только начал изучать PHP ООП, ранее я занимался PHP процедурным способом. Я читал эту статью , и у меня есть пара быстрых вопросов,

  1. Как обычно определяется конструктор для объектов-значений? Как тот, который принимает все «члены данных» в качестве параметров или придерживается конструктора по умолчанию и использует методы мутатора / средства доступа для установки / получения членов данных?

  2. Это действительно рекомендуемый способ начать работу с ООП PHP? Честно говоря, концепции, изложенные в статье, меня немного смутили.

Приветствия

Ответы [ 2 ]

2 голосов
/ 29 апреля 2010

Объекты всегда должны быть в действительном состоянии . Это означает, что объект всегда ведет себя (методы) и содержит информацию (переменные-члены), которая имеет смысл. Целью конструктора является создание объекта в допустимом состоянии.

При рассмотрении объектов-значений конструктор должен принимать минимальное количество аргументов, чтобы объект имел смысл. Например, если у вас есть объект значения RGB, имеет ли смысл в вашем приложении, если красный - это строка «обезьяна», зеленый - это 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 всегда будет иметь действительное состояние.

Надеюсь, это проливает некоторый свет на природу ООП и дает вам возможность начать думать.

1 голос
/ 29 апреля 2010
  1. Для создания объектов, которые действуют как нейтральные контейнеры данных, я бы использовал классический конструктор __contruct(), затем вы можете использовать магию __get и __set для доступа к свойствам. Например, для ввода данных с помощью объекта строки db вы можете найти дополнительную информацию об этом, прибегая к помощи «инъекции зависимостей»

  2. Вы можете запустить его, как и в большинстве языков ООП, через основной класс, но для веб-задач широко используется MVC.

У вас есть опыт программирования ООП?

...