Generic placeholder image
闲敲代码、落灯花
What's past is prologue

联系邮箱:email@hezehua.net


联系QQ:1907330840

座右铭

保持热情,持续学习,每日精进

使用匿名函数动态设置前置或者后置操作(装饰器模式的)

使用匿名函数动态设置前置或者后置操作(装饰器模式的)

本文与作者在csdn上的博文【使用匿名函数动态设置前置或者后置操作(装饰器模式的)】保持同步


在维护另一个同事的代码时,由于代码量比较大而且封装程度低耦合高,维护起来不太顺手,就怕哪没注意把现有的逻辑改坏了,受到laravel-admin的保存回调功能的启发,想到了使用匿名函数来动态设置前置或者后置操作,也就是应用装饰器模式。
比如,有一个delete函数是要删除一些商品,现在有个需求需要在删除前做一些检测,满足条件才可以删除,否则直接响应错误提示。
不使用装饰器模式的话,只能往原来的代码插入新的逻辑,而且又有新的需求的话还要继续破坏原来的代码,这种方式,可维护性和安全性都比较差。
而使用装饰器模式,只需要不破坏原来逻辑的基础上去增加[设置装饰者]的逻辑,一次改变终身受益~。
下面是具体的解决方案:

class Production
{
    private $deleting = [];
    //......

    //删除
    public function delete()
    {
        if(($response = $this->callDeleting()) instanceof JsonResponse)return $response;

        //......
        //这是原有的删除逻辑
    }

    //前置操作调用
    public function callDeleting()
    {
        foreach($this->deleting as $func)
        {
            if($func instanceof \Closure && $ret = call_user_func($func,$this) instanceof JsonResponse)
            return $ret;
        }
    }

    //设置前置操作
    public function deleteBefore(\Closure $closure)
    {
        $this->deleting[] = $closure;
    }
    //......后置操作类似
}

这样的话,在使用删除功能的时候,需要增加前置或者后置操作时,只需要调用deleteBefore函数添加匿名函数就行了。
具体使用如下:

class  IndexController
{
    //在此响应删除接口
    public function delPro($pro_id)
    {
        $pro = new Production($pro_id);
        //删除前商品前先记录商品的快照
        $pro->deleteBefore(function(){
            if(! Snap::record('production',$pro))return response('快照操作失败',500);
        });
        //执行删除
        $pro->delete();
    }
}
猜你喜欢