类相关
组合优于继承
正如在四人帮著名的 设计模式 中所说的那样,
你应该更青睐于组合而不是继承。使用继承和组合的理由有很多。这句格言的主要观点是,如果你倾向于继承,试着想想组合是否能更好的模拟你的问题。在某些情况下,它可以做到。
你可能会想,“我应该什么时候使用继承?” 这取决于你手头上的问题,但是这是一个关于继承比组合更有意义的列表:
- 你的继承代表了 “是一个” 的关系,并且不是 “有一个” 的关系 (人类->动物 vs. 用户->用户详情)。
- 你可以从基类中重用代码 (人类可以像所有动物一样移动)。
- 你想通过更改基类对派生类进行全局更改。(改变所有动物移动时所消耗的卡路里)。
坏的:
class Employee
{
private $name;
private $email;
public function __construct(string $name, string $email)
{
$this->name = $name;
$this->email = $email;
}
// ...
}
// 不好是因为 Employees “有” 税收数据。
// EmployeeTaxData 不是 Employee 类型
class EmployeeTaxData extends Employee
{
private $ssn;
private $salary;
public function __construct(string $name, string $email, string $ssn, string $salary)
{
parent::__construct($name, $email);
$this->ssn = $ssn;
$this->salary = $salary;
}
// ...
}
好的:
class EmployeeTaxData
{
private $ssn;
private $salary;
public function __construct(string $ssn, string $salary)
{
$this->ssn = $ssn;
$this->salary = $salary;
}
// ...
}
class Employee
{
private $name;
private $email;
private $taxData;
public function __construct(string $name, string $email)
{
$this->name = $name;
$this->email = $email;
}
public function setTaxData(EmployeeTaxData $taxData): void
{
$this->taxData = $taxData;
}
// ...
}
避免流畅的接口
流畅接口 是一个面向对象的 API,旨在通过 方法链 提高源代码的可读性。
虽然可能存在一些上下文,频繁的构建对象,这个模式在那里减少了代码的冗余度 (如 PHPUnit 模拟构造器 或者是 查询构造器),更多的时候,它需要付出一些代价:
更多信息,请完整阅读 博客推文 由 Marco Pivetta 编写的这个话题。
坏的:
class Car
{
private $make = 'Honda';
private $model = 'Accord';
private $color = 'white';
public function setMake(string $make): self
{
$this->make = $make;
// NOTE: Returning this for chaining
return $this;
}
public function setModel(string $model): self
{
$this->model = $model;
// NOTE: Returning this for chaining
return $this;
}
public function setColor(string $color): self
{
$this->color = $color;
// NOTE: Returning this for chaining
return $this;
}
public function dump(): void
{
var_dump($this->make, $this->model, $this->color);
}
}
$car = (new Car())
->setColor('pink')
->setMake('Ford')
->setModel('F-150')
->dump();
好的:
class Car
{
private $make = 'Honda';
private $model = 'Accord';
private $color = 'white';
public function setMake(string $make): void
{
$this->make = $make;
}
public function setModel(string $model): void
{
$this->model = $model;
}
public function setColor(string $color): void
{
$this->color = $color;
}
public function dump(): void
{
var_dump($this->make, $this->model, $this->color);
}
}
$car = new Car();
$car->setColor('pink');
$car->setMake('Ford');
$car->setModel('F-150');
$car->dump();
final classes 优先
应尽可能使用 final
关键字:
唯一的条件是您的类应该实现一个接口,并且没有定义其他公共方法。
有关更多信息,您可以阅读 [Marco Pivetta (Ocramius)](https: //ocramius.github.io/)。
Bad:
final class Car
{
private $color;
public function __construct($color)
{
$this->color = $color;
}
/**
* @return 返回汽车的颜色
*/
public function getColor()
{
return $this->color;
}
}
Good:
interface Vehicle
{
/**
* @return 字符串 车辆颜色
*/
public function getColor();
}
final class Car implements Vehicle
{
private $color;
public function __construct($color)
{
$this->color = $color;
}
public function getColor()
{
return $this->color;
}
}
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。