在下面的代码中考虑Crate::addLength():
class Crate
{
protected $length, $width, $height;
function __construct(float $length, float $width, float $height)
{
$this->length = $length;
$this->width = $width;
$this->height = $height;
}
function addLength(float $length): Crate
{
return new self($this->length + $length, $this->width, $this->height);
}
}我担心Crate对象创建Crate对象违反了单一责任原则(SRP)。行李箱的任务是保持板条箱的尺寸。创建另一个板条对象似乎是在已经有责任的类中引入额外的责任。
考虑到这一点,我如何使代码更好?
我想我可以去的方向是
( 1)难道只增加箱子的长度更好吗?
function addLength(float $length): void
{
$this->length += $length;
}然而,当这样做时,我的板条箱就会变得“有弹性”,而这在现实生活中通常并不是这样的。相反,一个新的板条箱是用给定的测量来建造的。
因此,
( 2)将对象创建委托给单独的类更好吗?
class CrateService
{
function addLength(Crate $crate, float $length): Crate
{
return new Crate($crate->GetLength() + $length, $crate->getWidth(), $crate->getHeight());
}
}这似乎是可行的,即使有点麻烦--我们基本上把每个板条箱的尺寸分别命名为加法器长度,并创建一个新的板条箱。
发布于 2019-07-29 17:59:34
考虑到您的评论,我看不出有一个“弹性”板条箱有什么问题,但在我下面的示例代码中,您可以控制板条箱是否可以拉伸。
class Crate
{
private $length, $width, $height;
private $resizable = true;
function __construct(float $length, float $width, float $height)
{
list($this->length, $this->width, $this->height) = [$length, $width, $height];
}
function getDimensions(): array
{
return [$this->length, $this->width, $this->height];
}
function isResizable()
{
return $this->resizable;
}
function fixateSize()
{
$this->resizable = false;
}
function addLength(float $extraLength): float
{
return $this->length += $this->isResizable() ? $extraLength : 0;
}
}我添加了三种方法:getDimensions()、isResizable()和fixateSize()。请注意,没有任何函数可以撤消fixateSize()。这是有意的:如果你可以撤销它,那么固定大小又有什么意义呢?
我已经将维度和大小调整为private字段。只有Crate类应该负责操作这些。子类应该使用Crate的方法来更改它们,因此使用getDimensions()方法。
注意addLength()现在是如何返回新的长度的,以及在固定机箱大小时它是如何不添加$extraLength的。您可以返回一个布尔值,指示是否接受额外的长度,而不是返回新的长度。另一个不接受额外长度的原因可能是箱子会变得太长。
我不会使用CrateService类,这太复杂了,而返回新对象的addLength()方法很奇怪。该方法的名称并不表示这一点。更好的名字应该是cloneAndStretch()。
https://codereview.stackexchange.com/questions/225133
复制相似问题