尝试使用类型约束来优化你的 Laravel 模型

在最近的几个项目中,我们对Eloquent模型做了一些小的改动,并发现了一些巨大的价值。我想和大家分享一下,以使他人也能和我们一样从中受益 🚀

让我们首先为一个想象中的电子商务商店建立一个产品模型:

php artisan make:model Product

现在我们在App命名空间下有了全新的Product模型:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    // 
}

我们在开始时做一些初始化设置:

  • 强制使用严格类型模式
  • 标记类为final
  • 添加逻辑代码段

...结果如下:

<?php

declare(strict_types=1);

namespace App;

use Illuminate\Database\Eloquent\Model;

final class Product extends Model
{
    #-----------------------------------------------------------------
    # Class Constants
    #-----------------------------------------------------------------

    // 

    #-----------------------------------------------------------------
    # Class Properties
    #-----------------------------------------------------------------

    // 

    #-----------------------------------------------------------------
    # Relationships
    #-----------------------------------------------------------------

    //

    #-----------------------------------------------------------------
    # Accessors and Mutators
    #-----------------------------------------------------------------

    // 
}

接下来,我们将遵循一些有关表和主键名的一般团队约定进行设置,并包含必要的关联代码:

<?php

//

final class Product extends Model
{
    // 

    #-----------------------------------------------------------------
    # Properties
    #-----------------------------------------------------------------

    /**
     * @var string
     */
    protected $table = 'products';

    /**
     * @var string
     */
    protected $primaryKey = 'product_id';

    #-----------------------------------------------------------------
    # Relationships
    #-----------------------------------------------------------------

    /**
     * @return HasOne
     */
    public function currency(): HasOne
    {
        return $this->hasOne(Currency::class, 'currencyCode', 'currency');
    }

    // 
}

你可能想知道这当中有什么不一样,这就是标准的Laravel-你完全正确。我包括了这些细节,是为了确保新手也能够跟进 😌

在这个阶段,我们将自己风格的访问器和修改器引入到模型中(大家熟知的getters/setters):

<?php

//

final class Product extends Model
{
    // 

    #-----------------------------------------------------------------
    # Accessors and Mutators
    #-----------------------------------------------------------------

    /**
     * @return string
     */
    public function getName(): string
    {
        return $this->getAttribute('name');
    }

    /**
     * @param string $name
     */
    public function setName(string $name): void
    {
        $this->setAttribute('name', $name);
    }

    /**
     * @return float|null
     */
    public function getPrice(): ?float
    {
        return $this->getAttribute('price');
    }

    /**
     * @param float|null $value
     */
    public function setPrice(?float $value): void
    {
        $this->setAttribute('price', $value);
    }

    /**
     * @return bool
     */
    public function isActive(): bool
    {
        return $this->getAttribute('is_active');
    }

    // 
}

这很简单,但是您可能想知道详细细节以及为什么要手工编写这些方法。

有什么优点?

自从介绍了这种编码风格以来,我们已经看到了这些好处:

  • 模型划分逻辑部分,因此易于查找代码
  • IDE自动提示模型属性
  • 因为使用严格类型的功能,所以模型属性带有类型提示
  • 保留了 Eloquent 的功能,不会任何骇人的重写操作

在我们的团队中,由于这些微小的变化,我们发现开发人员的经验有了整体改善。使用其他人的代码时,错误更少,代码理解得到改善,学习成本降低。

为什么不仅仅使用公共属性?

当我向任何人展示此问题时,自然会出现一个问题:为什么不仅仅使用公共属性?好吧,我认为这会带来一些限制:

  • 无法强制限制给定属性的数据类型,可以将浮点值赋值给int 型的数据库属性

  • 无法确定给定属性的返回类型,因此在语言级别上,您不知道状态字段是否应返回字符串或整数

  • 属性级别的数据验证很困难,您可以为明显无效的属性设置一个负值(例如:产品的负价)

  • 如果更改了属性列名称,则需要在访问该属性的所有位置手动进行该更改;由于属性是动态的,因此无法利用 IDE 使用情况搜索

结束语

您可能想尝试一下,看看是否有任何好处。这在很大程度上有利于 PHP 7 的强类型化,因此对此优先考虑的团队将获得最大的收益。最后,您的想法可能会有所不同🙂

在Twitter上与我分享您的想法和想法!

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

原文地址:https://dev.to/phpfour/structuring-larav...

译文地址:https://learnku.com/laravel/t/44626

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

当我想同时赋值多个字段怎么办?

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!