Это также нарушает закон Деметры? Или это было бы излишним, чтобы исказить это?

Очень простой момент:

class Point
{
    private $x, $y;

    public function __constructor($x, $y)
    {
        $this->x = $x;
        $this->y = $y;
    }

    public function getX()
    {
        return $this->x;
    }

    public function getY()
    {
        return $this->y;
    }
}

и круг

class Circle
{
    private $r;
    private $point;

    public function __constructor (Point $point, $r)
    {
        $this->point = $point;
        $this->r = $r;
    }

    public function getPoint() // here is the law breaking
    {
        return $this->point;
    }
}

$circle = new Circle(new Point(1,2), 10);
$circle->getPoint()->getX(); // here is the law breaking
$circle->getPoint()->getY(); // here is the law breaking

конечно это нарушает закон Деметры. Итак, позвольте мне преломить это:

class Circle
{
    private $r;
    private $point;

    public function __constructor (Point $point, $r)
    {
        $this->point = $point;
        $this->r = $r;
    }

    public function getPointX()
    {
        return $this->point->getX();
    }

    public function getPointY()
    {
        return $this->point->getY();
    }
}

$circle = new Circle(new Point(1,2), 10);
$circle->getPointX();
$circle->getPointY();

кроме того, что выглядит лучше, я не вижу никаких преимуществ - только две дополнительные функции обтекания. Технически у меня снова есть полный доступ к Point и нет никакого способа, которым было бы добавлено больше методов Point, Стоит ли еще использовать 2-й рефрактированный метод?

3 ответа

Я согласен с @Webdesigner, что это скорее вопрос, основанный на мнении.

Однако, на мой взгляд, я не думаю, что нарушение закона деметры - это действительно проблема, когда вы рассматриваете Point как объект стоимости.

Добытчик может быть

public function center() : Point { ... };

чтобы сделать это еще более ясным.

Хотя вторая версия технически не нарушает Закон Деметры, я бы сказал, что она все еще нарушает его "по духу". Причина, по которой вы не можете сказать, какая из них лучше, заключается в том, что вторая из них лишь незначительно лучше первой с точки зрения сокрытия и инкапсуляции информации (то, что Закон Деметры пытается кодифицировать).

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

Резюме: добытчики - ваша проблема. Пока они у вас есть, вам всегда придется сражаться с Законом Деметры, и вы, вероятно, проиграете:)

Итак, как вы пишете код без геттеров, спросите вы? Ну, вы добавляете методы, которые делают что-то для вас с координатами. Вещи, которые вам нужны. Расстояние между точками, точки преобразования и т. Д. Все, что вам нужно в вашем текущем приложении. Подумайте о том, что означает точка в вашем текущем контексте.

Проверьте " Гений закона Деметры".

Помимо того, что это вопрос, основанный на мнении, я бы сделал это так:

class Circle extends Point
{
    private $r;

    public function __constructor (Point $point, $r)
    {
        $this->x = $point->getPointX();
        $this->y = $point->getPointY();
        $this->r = $r;
    }
}

$circle = new Circle(new Point(1,2), 10);
$circle->getPointX();
$circle->getPointY();
Другие вопросы по тегам