• php实现空对象模式


    空对象模式(Null Object Pattern):用一个空对象取代 NULL,减少对实例的检查。这样的空对象可以在数据不可用的时候提供默认的行为

    (一)为什么需要空对象模式

    解决在需要一个对象时返回一个null值,使其调用函数出错的情况
    

    (二)空对象模式UML图

    上图是Java的空对象模式UML图,网上很多PHP设计模式的代码实现都是照着上面这个UML图

    实际上PHP在空对象模式的实现上比Java更加简单些。因为PHP有美妙的语法糖,魔术方法__call方法。

    我们只要实现空对象的__call方法就可以实现空对象模式,并不需要使用nullobject去继承对应的抽象object。

    (三)简单实例

    假设现在我们有这么一段代码

    <?php
    //测试类
    class Person{
        public function code(){
            echo 'code makes me happy'.PHP_EOL;
        }
    }
    
    
    //定义一个生成对象函数,只有PHPer才允许生成对象
    function getPerson($name){
        if($name=='PHPer'){
            return new Person;
        }
    }
    
    $phper = getPerson('PHPer');
    $phper->code();
    

    是的,现在这段代码会输出code makes me happy。如果有时候这个函数是别人调用的,它并没传入合适的参数呢?

    $phper = getPerson('Javaer');
    $phper->code();
    

    这个时候就会报错了error : Call to a member function code() on null。是的$phper现在是一个null值,所以调用code方法就会报错

    这种情况很常见,系统并没有返回一个我们期待的对象,而是返回了一个null值。所以多数情况下,我们的代码都要这样写

    $phper = getPerson('Javaer');
    if(!is_null($phper)){
        $phper->code();
    }
    

    或者是

    if(is_object($phper)){
        $phper->code();
    }
    

    这样让太多的if判断不可避免地存在于我们的代码中
    如果我们使用NullObject模式的话,我们就可以让函数没有返回值时返回一个nullobject对象。而不是一个null值(没有return 默认null值)

    //测试类
    class Person{
        public function code(){
            echo 'code makes me happy'.PHP_EOL;
        }
    }
    
    
    //空对象模式
    class NullObject{}
    
    //定义一个生成对象函数,只有PHPer才允许生成对象
    function getPerson($name){
        if($name=='PHPer'){
            return new Person;
        }else{
            return new NullObject;
        }
    }
    
    $phper = getPerson('PHer');
    $phper->code();
    

    这个时候就不会再报一个null调用函数的错误了,但是会报一个call to undefined method的错误,这是由于NullObject对象没有code方法。这个时候我们只需实现魔术方法__call,就不会报错了。

    //空对象模式
    class NullObject{
        public  function __call($method,$arg){
            echo 'this is NullObject';
        }
    }
    

    我们可以通过返回一个NullObject对象来取代返回null,这样就不用在调用方法时判断是否为null,而且只要你实现了call方法,不管真正的对象它原来是调用那个方法的,NullObject都可以去调用而且不报错(实际是隐式调用了魔术方法call)。当然,如果你原本的逻辑是返回对象是null的话什么都不做,那么你可以让__call()什么都不做。或者你也可以让它抛出一个异常。

    欢迎大家学习,交流
  • 相关阅读:
    SpringBoot及Vue3.0 登录验证码实现
    SpringBoot 文件上传、下载、显示
    Redis持久化
    Redis持久化之RDB、AOF详解
    SpringBoot AOP 记录操作日志、异常日志
    JAVA后端《持续集成 持续交付 持续部署》
    MySQL Binlog 介绍
    谷歌浏览器chrome即将在2020年底停止支持flash,我们程序员该怎么办
    年薪170万的阿里P8级员工征婚有感--话说阿里真有钱,这员工要求的条件真多
    为什么百度只抓取了首页而不抓取我的网站的内页的原因分析
  • 原文地址:https://www.cnblogs.com/lijintao1025/p/8516032.html
Copyright © 2020-2023  润新知