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

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

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-й рефрактированный метод?

4

Решение

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

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

Другие решения

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

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

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

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

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

1

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

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

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

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

Проверьте «Гений Закона Деметры».

1
По вопросам рекламы [email protected]