文章目录
- 概要
- 什么是封装模型属性?
- 使用访问器和修改器封装属性
- 访问器(Accessor)
- 修改器(Mutator)
- 测试业务实现
- 运行结果
- 小结
概要
随着项目规模的扩大,模型中的属性和方法可能会变得越来越复杂,这会使得代码的维护变得更加困难。为了提高代码的可维护性和可扩展性,我们可以通过封装模型属性来简化这些操作。本文将探讨如何封装 Laravel 模型中的属性,如何将属性封装成方法,并提供一种清晰、结构化的方式来管理模型的属性
什么是封装模型属性?
封装模型属性是将模型的属性(字段)通过方法进行封装,而不是直接访问属性本身。通过这种方式,可以集中处理一些常见的逻辑,比如格式化、转换、验证等,避免将这些操作散布在代码的各个地方。
例如,假设我们有一个 Goods 模型,模型中有一个 price 属性。我们可以封装这个属性,通过方法来自动处理转换,例如将价格从数据库存储的整数(分)转换为浮动数值(元),或反之。
使用访问器和修改器封装属性
Laravel 的 Eloquent 提供了访问器(Accessor)和修改器(Mutator)来帮助我们封装属性。访问器和修改器是通过特定的方法名称约定来定义的,分别用于获取和设置模型的属性值。
模型实现
namespace App\Models;use App\Services\Goods\Contracts\GoodsEntity;class Goods extends BaseModel implements GoodsEntity
{use \App\Models\Traits\GoodsEntity;
}
对应的访问器和修改器接口
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)
访问器用于获取属性值时进行处理,通常用于格式化、转换或者添加前后缀等操作。通过定义一个访问器方法,你可以自动在访问属性时进行转换或计算。
访问器接口
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;}
访问器实现
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)
修改器用于设置属性值时进行处理,通常用于数据的格式化、转换或者加密等操作。通过定义一个修改器方法,你可以在给属性赋值时进行转换。
修改器接口
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);
}
修改器实现
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;}
}
测试业务实现
控制器代码
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
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(),];}
}
运行结果
通过访问接口验证实现效果:
http://xxx.test/api/Learn/goods/getEntityList
结果:
{"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 提供的访问器、修改器和自定义方法,我们可以将常见的属性转换、计算或格式化逻辑集中管理,避免将业务逻辑散布在控制器和视图中。这样不仅能够提升代码的可读性,也能确保数据处理的一致性。
在实际开发中,可以根据项目的需求灵活选择封装的方式,确保代码的高效和可维护性。