类相关

未匹配的标注

组合优于继承

正如在四人帮著名的 设计模式 中所说的那样,
你应该更青睐于组合而不是继承。使用继承和组合的理由有很多。这句格言的主要观点是,如果你倾向于继承,试着想想组合是否能更好的模拟你的问题。在某些情况下,它可以做到。

你可能会想,“我应该什么时候使用继承?” 这取决于你手头上的问题,但是这是一个关于继承比组合更有意义的列表:

  1. 你的继承代表了 “是一个” 的关系,并且不是 "有一个" 的关系 (人类->动物 vs. 用户->用户详情)。
  2. 你可以从基类中重用代码 (人类可以像所有动物一样移动)。
  3. 你想通过更改基类对派生类进行全局更改。(改变所有动物移动时所消耗的卡路里)。

坏的:

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 模拟构造器 或者是 查询构造器),更多的时候,它需要付出一些代价:

  1. 破坏 封装
  2. 破坏 装饰
  3. 在测试套件中更难 模拟
  4. 使提交的差异更难阅读。

更多信息,请完整阅读 博客推文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 关键字:

1.它防止了不受控制的继承链。

  1. 它鼓励 组成
  2. 它鼓励单一职责原则
  3. 它鼓励开发人员使用您的公共方法而不是扩展类来访问受保护的方法。
  4. 它允许您在不破坏使用您的类应用程序的情况下更改代码。

唯一的条件是您的类应该实现一个接口,并且没有定义其他公共方法。

有关更多信息,您可以阅读 [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;
    }
}

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/clean-code-php/...

译文地址:https://learnku.com/docs/clean-code-php/...

上一篇 下一篇
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
贡献者:3
讨论数量: 0
发起讨论 只看当前版本


暂无话题~