逻辑代码增减需求,让我们来解耦,维护更轻松

  • 前言
产品的需求千变万化,有时候需要在原有代码逻辑上增加需求,或者 删除,或者修改。

  1. addMeiqucickOrder 第一次 简单的新增一个订单
  2. addmeiquickorderBeforeValidate 第二次变化, 在新增订单前验证一堆判断,至少20个判断
  3. addMeiquickOrderWithNoRepeat 第三次变化,在验证前,增加一个防止并发的重新新增问题
  • 贡献
如果有更好的办法解耦,请在评论区贴上博客链接哦,互相讨论O(∩_∩)O哈哈~!
  • 产品需求变化了三次
需求1:商家 --> 订单修改 --> 保存运单号 --> 修改订单状态为发货

需求2: 商家 --> 订单修改 --> 判断 订单异常信息(未退款,未取消 等状态)--> 保存运单号 --> 修改订单状态为发货

需求3: 商家 --> 订单修改 --> 判断 订单异常信息(未退款,未取消 等状态)--> 保存运单号 --> 修改订单状态为发货 --> 记录订单状态修改的日志

前景分析

从上面的需求可以看出,前后需求三次变化,

需求 1 与 需求 2 对比:在保存运单号前,先判断订单异常信息 才能修改

需求2 与 需求3 对比:在修改订单为发货状态时,增加记录订单状态修改日志

普遍程序员做法

把 整个流程 从头到尾 都是 这样写

function updateOrderExpressNo(OrderModel $order, $expressNo) {

//先判断  

if else if else if else ....

    //修改运单号

  $order->express_no = $expressNo;

   //增加日志

  Log::info('订单修改了发货状态:'.$order->id);

  //修改订单状态

  $order->status = '1'; //1为发货状态

$order-save();

}

普遍程序员做法分析:

此时 增加了我们调试难度,把所有逻辑都放到一个函数里面写,也不确保每个功能是否完整是否能运行正常,随着以后项目越做越大,这时只能重构。

我的做法,解耦过程如下

我们先分析以下 需求1共有2个步骤

1.保存运单号

2.订单发货状态修改

//以下代码 基于laravel5框架实现

//定义两个行为接口,分别是上面两个

interface UpdateOrderExpressNoInterface {

 //修改订单运单号接口

  public function handle($order, $expressNo);

}

interface UpdateOrderStatusInterface {

//修改订单状态接口

public function handle($order, $status);

}



//两个行为类

//修改运单号行为

class UpdateOrderExpressNo implements UpdateOrderExpressNoInterface {

   public function handle($order, $expressNo){

     $order->express_no = $expressNo;

     return $order->save();

   }

}



//修改订单状态行为

class UpdateOrderStatus implements UpdateOrderStatusInterface {

   public function handle($order, $status){

     $order->status = $status;

     return $order->save();

   }

}

//新建一个AppBehaviorProvider

class AppBehaviorProvider extends ServiceProvider
{

    /**行为类接口
     * @var array
     */
    protected $behaviorArr = [
        //运单号修改, 啥意思呢?当我们要调用app(UpdateOrderExpressNoInterface::class) 就会得到 new UpdateOrderExpressNo 的实例对象
        UpdateOrderExpressNoInterface::class => UpdateOrderExpressNo::class,
        //修改订单状态
        UpdateOrderStatusInterface::class => UpdateOrderStatus::class,
     ];

    public function boot()
    {

    }
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {

        foreach ($this->behaviorArr as $interface => $class)
        {
            $this->app->bind($interface, $class);
        }
    }
}
//订单操作控制器

class OrderController {

  protected $orderService;

  public function __construct(OrderService $orderService){

   $this->orderService = $orderService;

  }  

 public function updateExpressNo(int $orderId, Request $request){

    $status = $this->orderService->updateExpressNo($orderId, $request->input('express_no', ''));

   return $status;

 }

}

//订单服务

class OrderService {

protected $orderModel;
protected $updateOrderExpressNo;
protected $updateOrderStatus;

  public function __construct(
    OrderModel $orderModel,
    UpdateOrderExpressNoInterface $updateOrderExpressNo,
    UpdateOrderStatusInterface $updateOrderStatus
  ){

    $this->orderModel = $orderModel;
    $this->updateOrderExpressNo = $updateOrderExpressNo;
    $this->updateOrderStatus = $updateOrderStatus;
  }  

  public function find($id){

   return $this->orderModel->find($id);

  }

  public function updateExpressNo($orderId, $expressNo)

  {

  //开启事务,此处省略

   $order = $this->find($orderId);

     //执行修改运单号动作

     //$result = app(UpdateOrderExpressNoInterface::class)->handle($order, $expressNo);
     $result = $this->updateOrderExpressNo->handle($order, $expressNo);

    if ($result) {

    //执行修改订单状态动作

      //$result1 = app(UpdateOrderStatus::class)->handle($order, 1); //1为发货状态
      $result1 = $this->updateOrderStatus->handle($order, 1); //1为发货状态

   }

  //失败保存则回滚,此处省略

  }

接下来我们先分析以下 需求2共有三个步骤

1. 判断订单状态

2. 保存运单号

3. 订单发货状态修改

//2,3步骤不变,在原有的保存运单号接口上,增加步骤1, 增加一个判断订单状态的行为类

class UpdateOrderBeforeValidate implements  UpdateOrderExpressNoInterface{

protected $updateOrder;

//这里laravel自动帮我们new UpdateOrderExpressNo()并传入到 构造函数了

public function __construct(UpdateOrderExpressNo $updateOrder) {

  $this->updateOrder = $updateOrder;

}

   public function handle($order, $expressNo){

     if ($order->refund != 0) {

        return '订单退款状态,无法保存订单运单号';

    }else if ($order->cancle != 0){

        return '订单取消状态,无法保存运单号';

   }

    return $this->updateOrder->handle($order, $expressNo);

   }

}

//增加保存运单号前需要验证的 行为类时,需要修改AppBehaviorProvider定义的修改运单号接口对应的类,也就是告诉laravel,当控制器需要 修改运单号时,切换 UpdateOrderBeforeValidate类。

class AppBehaviorProvider extends ServiceProvider
{

    /**行为类接口
     * @var array
     */
    protected $behaviorArr = [
       //从UpdateOrderExpressNo类 切换 UpdateOrderBeforeValidate类
        UpdateOrderExpressNoInterface::class => UpdateOrderBeforeValidate::class,
        //修改订单状态
        UpdateOrderStatusInterface::class => UpdateOrderStatus::class,
     ];

    public function boot()
    {

    }
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {

        foreach ($this->behaviorArr as $interface => $class)
        {
            $this->app->bind($interface, $class);
        }
    }
}

需求1 -> 需求2分析

需求2,增加了UpdateOrderBeforeValidate类,无需修改 UpdateOrder这个类,也就是对这个类修改的关闭,其他类也无需要改,并且 在该类 通过构造函数实例UpdateOrder类,并且增强 他的handle方法,装饰者模式。

至于需求三,分析共以下步骤:

1. 订单状态判断

2. 修改订单运单号

3. 修改订单状态为发货状态

4. 记录日志

//代码就不一一列举了,解题思路:

//增加一个 UpdateOrderStatusAfterLog类,该类用来记录日志,通过装饰者模式,在构造函数传入pdateOrderStatus类实例.

public handle($order, $status) {

  Log::info('订单状态修改为:'.$order->id.':'.$status);

   return $this->updateOrderStatus->handle($order, $status);

}

//接着在 AppBehaviorProvider 修改UpdateOrder::class 为UpdateOrderStatusAfterLog::class

备注:

__construct(OrderService $orderService) 。laravel自动给你 new OrderService() 传入到构造函数里面

__construct(UpdateOrderExpressNoInterface $updateOrderExpressNo)

因为我们在provider里面注册了

$this->app->bind(UpdateOrderExpressNoInterface::class, UpdateOrderExpressNo::class);

告诉我们的容器,当需要UpdateOrderExpressNoInterface的接口实现类时,我们就new UpdateOrderExpressNo()传到构造函数里面。这是laravel的容器+依赖注入的特性。

当然在provider注册了,需要在 config/app.php 的providers键下增加 AppBehaviorProvider::class, 告诉laravel自动引入这个服务提供者。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值