文章目录
概要
随着项目规模的扩大,模型中的属性和方法可能会变得越来越复杂,这会使得代码的维护变得更加困难。为了提高代码的可维护性和可扩展性,我们可以通过封装模型属性来简化这些操作。本文将探讨如何封装 Laravel 模型中的属性,如何将属性封装成方法,并提供一种清晰、结构化的方式来管理模型的属性
什么是封装模型属性?
封装模型属性是将模型的属性(字段)通过方法进行封装,而不是直接访问属性本身。通过这种方式,可以集中处理一些常见的逻辑,比如格式化、转换、验证等,避免将这些操作散布在代码的各个地方。
例如,假设我们有一个 Goods 模型,模型中有一个 price 属性。我们可以封装这个属性,通过方法来自动处理转换,例如将价格从数据库存储的整数(分)转换为浮动数值(元),或反之。
使用访问器和修改器封装属性
Laravel 的 Eloquent 提供了访问器(Accessor)和修改器(Mutator)来帮助我们封装属性。访问器和修改器是通过特定的方法名称约定来定义的,分别用于获取和设置模型的属性值。
模型实现
php
namespace App\Models;
use App\Services\Goods\Contracts\GoodsEntity;
class Goods extends BaseModel implements GoodsEntity
{
use \App\Models\Traits\GoodsEntity;
}
对应的访问器和修改器接口
php
namespace App\Services\Goods\Contracts;
use App\Services\Goods\Contracts\Accessors\GoodsAccessor;
use App\Services\Goods\Contracts\Mutators\GoodsMutator;
interface GoodsEntity extends GoodsAccessor, GoodsMutator
{
}
访问器(Accessor)
访问器用于获取属性值时进行处理,通常用于格式化、转换或者添加前后缀等操作。通过定义一个访问器方法,你可以自动在访问属性时进行转换或计算。
访问器接口
php
namespace App\Services\Goods\Contracts\Accessors;
interface GoodsAccessor
{
/**
* 获取商品品牌Id
* @return string
*/
public function getBrandId(): int;
/**
* 获取商品名称
* @return array
*/
public function getGoodsName(): string;
/**
* 获取商品副标题
* @return string
*/
public function getGoodsSubname(): string;
/**
* 获取商品编号
* @return float
*/
public function getGoodsNo(): string;
/**
* 获取价格
* @return float
*/
public function getGoodsPrice(): float;
/**
* 获取商品市场价格
* @return float
*/
public function getGoodsMarketPrice() : float;
/**
* 获取商品库存
* @return int
*/
public function getGoodsStock() : int;
/**
* 获取商品销量
* @return int
*/
public function getGoodsSale() : int;
}
访问器实现
php
namespace App\Models\Traits\Accessors;
trait GoodsAccessor
{
/**
* 获取商品品牌Id
* @return string
*/
public function getBrandId(): int
{
return $this->attributes['brand_id'];
}
/**
* 获取商品名称
* @return array
*/
public function getGoodsName(): string
{
return $this->attributes['goods_name'];
}
/**
* 获取商品副标题
* @return string
*/
public function getGoodsSubname(): string
{
return $this->attributes['goods_subname'];
}
/**
* 获取商品编号
* @return float
*/
public function getGoodsNo(): string
{
return $this->attributes['goods_no'];
}
/**
* 获取价格
* @return float
*/
public function getGoodsPrice(): float
{
return $this->attributes['goods_price'];
}
/**
* 获取商品市场价格
* @return float
*/
public function getGoodsMarketPrice() : float
{
return $this->attributes['goods_market_price'];
}
/**
* 获取商品库存
* @return int
*/
public function getGoodsStock() : int
{
return $this->attributes['goods_stock'];
}
/**
* 获取商品销量
* @return int
*/
public function getGoodsSale() : int
{
return $this->attributes['goods_sale'];
}
}
修改器(Mutator)
修改器用于设置属性值时进行处理,通常用于数据的格式化、转换或者加密等操作。通过定义一个修改器方法,你可以在给属性赋值时进行转换。
修改器接口
php
namespace App\Services\Goods\Contracts\Mutators;
interface GoodsMutator
{
/**
* 设置品牌id
* @param int $brandId
* @return $this
*/
public function setBrandId(int $brandId);
/**
* 设置商品名称
* @param string $name
* @return $this
*/
public function setGoodsName(string $name);
/**
* 设置商品副名称
* @param string $goodsSubname
* @return $this
*/
public function setGoodsSubname(string $goodsSubname);
/**
* 设置商品编号
* @param string $goodsNo
* @return $this
*/
public function setGoodsNo(string $goodsNo);
/**
* 设置价格
* @param float $price
* @return $this
*/
public function setGoodsPrice(float $price);
/**
* 设置商品市场价格
* @param float $price
* @return $this
*/
public function setGoodsMarketPrice(float $price);
/**
* 设置商品库存
* @param int $stock
* @return $this
*/
public function setGoodsStock(int $stock);
/**
* 设置商品销量
* @param int $sale
* @return $this
*/
public function setGoodsSale(int $sale);
}
修改器实现
php
namespace App\Models\Traits\Mutators;
trait GoodsMutator
{
/**
* 设置品牌id
* @param int $brandId
* @return $this
*/
public function setBrandId(int $brandId)
{
$this->attributes['brand_id'] = $brandId;
return $this;
}
/**
* 设置商品名称
* @param string $name
* @return $this
*/
public function setGoodsName(string $name)
{
$this->attributes['goods_name'] = $name;
return $this;
}
/**
* 设置商品副名称
* @param string $goodsSubname
* @return $this
*/
public function setGoodsSubname(string $goodsSubname)
{
$this->attributes['goods_subname'] = $goodsSubname;
return $this;
}
/**
* 设置商品编号
* @param string $goodsNo
* @return $this
*/
public function setGoodsNo(string $goodsNo)
{
$this->attributes['goods_no'] = $goodsNo;
return $this;
}
/**
* 设置价格
* @param float $price
* @return $this
*/
public function setGoodsPrice(float $price)
{
$this->attributes['goods_price'] = $price;
return $this;
}
/**
* 设置商品市场价格
* @param float $price
* @return $this
*/
public function setGoodsMarketPrice(float $price)
{
$this->attributes['goods_market_price'] = $price;
return $this;
}
/**
* 设置商品库存
* @param int $stock
* @return $this
*/
public function setGoodsStock(int $stock)
{
$this->attributes['goods_stock'] = $stock;
return $this;
}
/**
* 设置商品销量
* @param int $sale
* @return $this
*/
public function setGoodsSale(int $sale)
{
$this->attributes['goods_sale'] = $sale;
return $this;
}
}
测试业务实现
控制器代码
php
namespace App\Http\Controllers\Learn;
use App\Http\Controllers\Controller;
use App\Http\Resources\Goods\GoodsResource;
use App\Models\Goods;
use Illuminate\Http\Request;
class GoodsController extends Controller
{
public function getEntityList()
{
$list = Goods::query()->get();
return GoodsResource::collection($list);
}
}
将模型或集合转换为 JSON
php
namespace App\Http\Resources\Goods;
use Illuminate\Http\Resources\Json\JsonResource;
class GoodsResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$item = $this->resource;
return [
'brand_id' => $item->getBrandId(),
'goods_name' => $item->getGoodsName(),
'goods_subname' => $item->getGoodsSubname(),
'goods_no' => $item->getGoodsNo(),
'goods_price' => $item->getGoodsPrice(),
'goods_market_price' => $item->getGoodsMarketPrice(),
'goods_stock' => $item->getGoodsStock(),
'goods_sale' => $item->getGoodsSale(),
];
}
}
运行结果
通过访问接口验证实现效果:
结果:
json
{
"data": [
{
"brand_id": 1,
"goods_name": "温热温热",
"goods_subname": "额我认为耳闻",
"goods_no": "",
"goods_price": 34,
"goods_market_price": 34,
"goods_stock": 44,
"goods_sale": 3
},
{
"brand_id": 0,
"goods_name": "额温热玩儿",
"goods_subname": "而扼腕容器",
"goods_no": "",
"goods_price": 33.4,
"goods_market_price": 44,
"goods_stock": 33,
"goods_sale": 4
},
{
"brand_id": 1,
"goods_name": "空调开空调开",
"goods_subname": "的方式地方的说法",
"goods_no": "",
"goods_price": 33,
"goods_market_price": 44,
"goods_stock": 2232,
"goods_sale": 0
}
]
}
小结
封装模型属性是提高 Laravel 应用可维护性和可扩展性的一种有效方法。通过使用 Eloquent 提供的访问器、修改器和自定义方法,我们可以将常见的属性转换、计算或格式化逻辑集中管理,避免将业务逻辑散布在控制器和视图中。这样不仅能够提升代码的可读性,也能确保数据处理的一致性。
在实际开发中,可以根据项目的需求灵活选择封装的方式,确保代码的高效和可维护性。