使用策略模式和簡單工廠模式重寫支付模組(二)-最佳化$request

zxr615發表於2021-04-15

前情提要

上一篇文章 使用策略模式和簡單工廠模式重寫支付模組 最後提到有 兩點不足之處 後來思考了下覺得可以用一個實體類,把需要的引數都 set 進實體,用 get 方法獲取引數,這樣 $request 既可以不向下傳遞,使用 get 方法獲取引數又能很明確。

建立實體類

  1. 根據 vipStrategy策略 第三步中,提取臨時訂單中公共的資料新增對應的成員方法,並新增 getset 方法,完成公共實體類

     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;}
     }
  2. 開通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 協議》,轉載必須註明作者和本文連結

相關文章