前情提要
上一篇文章 使用策略模式和簡單工廠模式重寫支付模組 最後提到有 兩點不足之處 後來思考了下覺得可以用一個實體類,把需要的引數都 set
進實體,用 get
方法獲取引數,這樣 $request
既可以不向下傳遞,使用 get
方法獲取引數又能很明確。
建立實體類
根據 vipStrategy策略 第三步中,提取臨時訂單中公共的資料新增對應的成員方法,並新增
get
和set
方法,完成公共實體類namespace App\Http\Services\PayOrder\Strategy; abstract class Entity { protected $ip; protected $packageCope; protected $code; protected $uid; protected $type; public function __construct(Request $request) { $this->ip = $request->getClientIp(); $this->code = $request->get('code'); $this->uid = Auth::id(); $this->packageCope = app(PayOrderService::class)->getVipByCode($this->code); // 為成員方法 `set` 值 foreach ($request->all() as $fields => $value) { $property = 'set' . Str::studly($fields); if (property_exists($this, $fields)) { $this->$property = $value; } } } public function getIp() { return $this->ip;} public function setIp($ip) { $this->ip = $ip;} public function getCode() { return $this->code;} public function setCode($code) { $this->code = $code;} public function getUid() { return $this->uid;} public function setUid($uid) { $this->uid = $uid;} public function getType() { return $this->type;} public function setType($type) { $this->type = $type;} public function getPackageCope() { return $this->packageCope;} public function setPackageCope($packageCope) {$this->packageCope = $packageCope;} }
開通vip實體類
namespace App\Http\Services\PayOrder\Entity; class VipEntity extends Entity { // 開通vip月數 protected $buyMonth; public function getBuyMonth() { return $this->buyMonth;} public function setBuyMonth($buyMonth){ $this->buyMonth = $buyMonth;} }
修改程式碼
vip 介面
public function vip(Request $request)
{
$strategy = new VipStrategy();
// 原始碼將$request向下傳傳遞
$tmpOrderKey = (new PayOrderContext($strategy))->createOrder($request);
// 修改後:通過VipEntity() 構造實體
$vipEntity = new VipEntity($request);
$tmpOrderKey = (new PayOrderContext($strategy))->createOrder($vipEntity);
return $this->data(['key' => $tmpOrderKey]);
}
VipStrategy.php
原來:接收vip介面傳入的 $request
function createTemporaryOrder(Request $request)
{
$packageCode = $request['code'];
$buyMonth = $request['buy_month'];
$package = app(PayOrderService::class)->getVipByCode($packageCode);
// 臨時訂單資料
$tmpOrder = [
'package_cope' => $package->toArray(),
'type' => PayOrderService::TYPE_VIP,
'uid' => 1,
'ip' => $request->ip(),
'buy_month' => $buyMonth
// ....
];
}
修改後:接收實體類,通過 $entity
可明確知道有什麼引數
function createTemporaryOrder(Entity $entity)
{
// 臨時訂單資料
$tmpOrder = [
'package_cope' => $entity->getPackageCope(),
'type' => PayOrderService::TYPE_VIP,
'uid' => $entity->getUid(),
'ip' => $entity->getIp(),
'buy_month' => $entity->getBuyMonth()
// ....
];
$tmpOrderKey = app(PayOrderService::class)->saveTemporaryOrder($tmpOrder);
return $tmpOrderKey;
}
總結
- 建立
VipEntity
實體類之後就可以明確引數,並且將$request
留在控制器中不再向下傳遞。 - 第二個問題不明確
redis
臨時訂單中有什麼資料也可以建立一個實體類,然後想引數set
完成後就可以愉快的get
了。
本作品採用《CC 協議》,轉載必須註明作者和本文連結