1
0
mirror of https://github.com/jupeter/clean-code-php.git synced 2025-09-27 14:38:59 +02:00

correct good example

This commit is contained in:
Peter Gribanov
2017-09-11 12:12:14 +03:00
committed by GitHub
parent 5c7064a69c
commit 2ba99292cd

View File

@@ -1181,28 +1181,25 @@ class Square extends Rectangle
} }
} }
function areaVerifier(Rectangle $rectangle) function printArea(Rectangle $rectangle)
{ {
$rectangle->setWidth(4); $rectangle->setWidth(4);
$rectangle->setHeight(5); $rectangle->setHeight(5);
// BAD: Will return 25 for Square. Should be 20. // BAD: Will return 25 for Square. Should be 20.
return $rectangle->area() == 20; echo sprintf('%s has area %d.', get_class($rectangle), $rectangle->area()).PHP_EOL;
} }
$rectangles = [new Rectangle(), new Square()]; $rectangles = [new Rectangle(), new Square()];
foreach ($rectangles as $rectangle) { foreach ($rectangles as $rectangle) {
   if (!areaVerifier($rectangle)) { printArea($rectangle);
throw new Exception('Bad area!');
}
} }
``` ```
**Not bad:** **Not bad:**
You can solve the problem by making objects immutable. You can solve the problem by making objects immutable.
But this is not the best solution, because the square specifies the invariants of the rectangle.
```php ```php
class Rectangle class Rectangle
@@ -1240,41 +1237,64 @@ class Square extends Rectangle
} }
} }
function areaVerifier(Rectangle $rectangle) function printArea(Rectangle $rectangle)
{ {
return $rectangle->area() == $rectangle->width() * $rectangle->height(); echo sprintf('%s has area %d.', get_class($rectangle), $rectangle->area()).PHP_EOL;
} }
$rectangles = [new Rectangle(4, 5), new Square(5)]; $rectangles = [new Rectangle(4, 5), new Square(5)];
foreach ($rectangles as $rectangle) { foreach ($rectangles as $rectangle) {
if (!areaVerifier($rectangle)) { printArea($rectangle);
throw new Exception('Bad area!');
}
} }
``` ```
This solution no longer violates the LSP principle because we can use a subtype.
```php
function printSquareArea(Square $rectangle)
{
// ...
}
printSquareArea(new Rectangle(4, 5));
```
But this is not a best solution, because the square specifies the invariants of the rectangle.
**Good:** **Good:**
The best way is separate the quadrangles. The best way is separate the quadrangles and the allocation of a more general subtype for both shape.
Despite the apparent similarity of the square and the rectangle, they are different. Despite the apparent similarity of the square and the rectangle, they are different.
A square has much in common with a rhombus, and a rectangle with a parallelogram, but they are not subtype. A square has much in common with a rhombus, and a rectangle with a parallelogram, but they are not subtype.
A square, a rectangle, a rhombus and a parallelogram are separate figures with their own properties, albeit similar. A square, a rectangle, a rhombus and a parallelogram are separate figures with their own properties, albeit similar.
```php ```php
class Rectangle interface Shape
{
public function area();
}
class Rectangle implements Shape
{ {
private $width = 0; private $width = 0;
private $height = 0; private $height = 0;
public function setWidth($width) public function __construct($width, $height)
{ {
$this->width = $width; $this->width = $width;
$this->height = $height;
} }
public function setHeight($height) public function width()
{ {
$this->height = $height; return $this->width;
}
public function height()
{
return $this->height;
} }
public function area() public function area()
@@ -1283,46 +1303,35 @@ class Rectangle
} }
} }
class Square class Square implements Shape
{ {
private $length = 0; private $length = 0;
public function setLength($length) public function __construct($length)
{ {
$this->length = $length; $this->length = $length;
} }
public function length()
{
return $this->length;
}
public function area() public function area()
{ {
return pow($this->length, 2); return pow($this->length, 2);
} }
} }
function rectangleAreaVerifier(Rectangle $rectangle) function printArea(Shape $shape)
{ {
$rectangle->setWidth(4); echo sprintf('%s has area %d.', get_class($shape), $shape->area()).PHP_EOL;
$rectangle->setHeight(5);
return $rectangle->area() == 20;
} }
function squareAreaVerifier(Square $square) $shapes = [new Rectangle(4, 5), new Square(5)];
{
$square->setLength(5);
return $square->area() == 25; foreach ($shapes as $shape) {
} printArea($shape);
$rectangle = new Rectangle();
if (!rectangleAreaVerifier($rectangle)) {
throw new Exception('Bad area!');
}
$square = new Square();
if (!squareAreaVerifier($square)) {
throw new Exception('Bad area!');
} }
``` ```