一个非常简单的观点:
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
添加更多方法。是否仍然值得使用第二种折射方法?
答案 0 :(得分:1)
除了这个更基于意见的问题之外,我会这样做:
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 :(得分:1)
我同意@Webdesigner这是一个基于意见的问题。
但是,在我看来,当你认为Point为value object时,我认为违反demeter的规律确实是个问题。
getter可能是
public function center() : Point { ... };
使其更加清晰。
答案 2 :(得分:1)
虽然第二个版本在技术上没有违反德米特定律,但我认为它仍然违反了它的精神和#34;。你无法分辨出哪一个更好的原因是因为第二个在信息隐藏和封装方面仅略微优于第一个(Demeter法则试图编纂的东西)。
该法则是关于隐藏对象的内部结构,从而实现封装,信息隐藏和防止耦合。 Getters(访问者)本质上与信息隐藏相反,它们允许访问内部结构而不是阻止它。
摘要: getter是你的问题。只要你拥有这些,你将永远不得不与德米特法律作斗争,你可能会失败:)
好的,那么如果没有你问的吸气剂你怎么编码?好吧,你用坐标为你添加做的方法。你需要的东西。点,转换点之间的距离等。无论您当前的应用需要什么。考虑一下Point在当前上下文中的含义。
查看" The Genius of the Law of Demeter"。