`

谈NullObject模式

    博客分类:
  • java
阅读更多
    知道这个模式还是通过《重构》,这个模式的出现还是了为了解决代码重复的坏味道。在项目中很经常见到类似下面这样的代码:
java 代码
 
  1. if(prj.getProjectId==null)  
  2.     plan.setCost(0.0);  
  3. else  
  4.     plan.setCost(prj.getCost());  

   我们在很多地方有类似的检查对象是否为null,如果为null,需要一个默认值等等这样的场景。显然,代码重复是坏味道,怎么消除这个坏味道呢?答案就是使用NullObject替代之,Null Object继承原对象。
java 代码
 
  1. class NullProject extends Project{  
  2.    public boolean isNull(){  
  3.       return true;  
  4.    }  
  5. }  
  6. class Project{  
  7.    private double cost;  
  8.    private String projectId;  
  9.    .  
  10.    public boolean isNull(){  
  11.         return false;  
  12.    }  
  13. }  

那么,原来的代码可以改写为:
java 代码
 
  1. if(prj.isNull())  
  2.     plan.setCost(0.0);  
  3. else  
  4.     plan.setCost(prj.getCost());  

    如果Null Object的引入仅仅是带来这个好处,似乎没有理由让我们多敲这么多键盘。问题的关键是类似上面这样的判断也许出现在很多处,那么有价值的技巧出现了,我们在NullObject覆写getCost,提供缺省值:
java 代码
 
  1. class NullProject extends Project{  
  2.    public boolean isNull(){  
  3.       return true;  
  4.    }  
  5.    public double getCost(){  
  6.       return 0.0;        
  7.    }  
  8. }  

    因此,检查对象是否为null的代码可以去掉if...else了:

java 代码
  1. plan.setCost(prj.getCost());  

    请注意,只有那些大多数客户端代码都要求null object做出相同响应时,这样的行为才有意义。比如我们这里当工程id为null,很多地方要求费用就默认为0.0。 特殊的行为我们仍然使用isNull进行判断。
    当然,另外在需要返回NullObject的地方,你应该创建一个null object以替代一般的对象,我们可以建立一个工厂方法:
java 代码
 
  1. class Project{  
  2.    private double cost;  
  3.    private String projectId;  
  4.    .  
  5.    public boolean isNull(){  
  6.         return false;  
  7.    }  
  8.    public Project createNullProject(){  
  9.         return new NullProject();  
  10.    }  
  11. }  

   Null Object模式带来的好处:减少了检查对象是否为null的代码重复,提高了代码的可读性,通常这些Null Object也可以为单元测试带来简便。
分享到:
评论

相关推荐

    从实例谈面向对象编程、工厂模式和重构

    如果不谈设计,设计出 来的播放器可能很简单: 程序代码 public class MediaPlayer { private void PlayMp3() { MessageBox.Show("Play the mp3 file."); } private void PlayWav() { MessageBox.Show(...

    二十三种设计模式【PDF版】

    主要是介绍各种格式流行的软件设计模式,对于程序员的进一步提升起推进作用,有时间可以随便翻翻~~ 23种设计模式汇集 如果你还不了解设计模式是什么的话? 那就先看设计模式引言 ! 学习 GoF 设计模式的重要性 ...

    浅谈C#单例模式的实现和性能对比

    C#单例模式的实现和性能对比 单例模式是软件工程中使用最多的几种模式之一,它是一种只能存在一个实例的类,在C#中,更准确的说法是在每个AppDomain之中只能存在一个实例的类。单例模式的实现方式有很多种,本文将...

    SQL Server误区30日谈 第13天 在SQL Server 2000兼容模式下不能使用DMV

    在上述示例中,`SELECT * FROM sys.dm_db_index_physical_stats (DB_ID('DMVTest'), OBJECT_ID('DMVTest..t1'), NULL, NULL, 'DETAILED')` 就能在80兼容模式的DMVTest数据库中成功执行。 总结来说,SQL Server的...

    浅谈JavaScript函数的四种存在形态_.docx

    // 弹出的是 object,此时的 this 表示 object ``` 在这个例子中,`o.foo()`的调用使得`this`指代`o`对象。 3. **构造器形态**: 构造器是通过`new`关键字来创建新对象的函数。在构造器内部,`this`指向新创建的...

    重构-改善既有代码的设计(中文版)

     Introduce Null Object 引入Null对象   Introduce Assertion 引入断言  Chapter 10:Making Method Calls Simpler 简化方法调用   Rename Method 重命名方法   Add Parameter 添加参数   Remove ...

    谈一谈javascript中继承的多种方式

    当尝试访问一个对象的属性时,如果该对象本身没有这个属性,就会去其原型(`__proto__`)上查找,如果原型也没有,就会继续查找原型的原型,直到找到该属性或者查找到原型链的顶部(即`null`)。这就是原型链的工作...

    浅谈spring ioc的注入方式及注入不同的数据类型

    浅谈Spring IoC的注入方式及注入不同的数据类型 Spring IoC(Inversion of Control,控制反转)是一种软件设计模式,它可以将对象之间的依赖关系进行解耦,提高系统的灵活性和可维护性。在Spring框架中,IoC是其...

    Javascript浅谈之引用类型

    3. 函数作为单独的表达式调用,如`foo()`,`this`在严格模式下是undefined,在非严格模式下是全局对象(ES5)或undefined(ES6+)。 4. 使用`.call()`、`.apply()`或`.bind()`方法,可以显式设置`this`的值。 理解...

    Spring.net框架

    t.InvokeMember(prop.propertyName, ........BindingFlags.SetProperty, null, o, new Object[] {p})利用反射机制对创建出来的对象设置属性值。 我们的Factory就是利用这种方式根据配置文件动态加载程序集,动态创建...

    浅谈asp.net Forms身份验证详解

    protected void btnLogin_Click(object sender, EventArgs e) { string username = txtUsername.Text; string password = txtPassword.Text; SampleUser user = SampleUser.GetUser(username); if (user != ...

    浅谈Javascript中的对象和继承

    此外,JavaScript还提供了其他继承模式,如`call`、`apply`和`bind`方法来改变函数的上下文,实现基于原型的继承,以及ES6引入的类(`class`)语法,虽然在语法层面更像传统的面向对象语言,但其本质仍然是基于原型...

    windows 程序设计

    Microsoft Windows版本3.1是1992年4月发布的,其中包括的几个重要特性是TrueType字体技术(给Windows带来可缩放的轮廓字体)、多媒体(声音和音乐)、对象连结和嵌入(OLE:Object Linking and Embedding)和通用...

    net学习笔记及其他代码应用

    答:string str = null 是不给他分配内存空间,而string str = \"\" 给它分配长度为空字符串的内存空间。 25.请详述在dotnet中类(class)与结构(struct)的异同? 答:Class可以被实例化,属于引用类型,是分配在内存的...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    6.1.7 null关键字 145 6.2 巧妙使用类中的属性 147 6.2.1 在类中给每个变量一个初始值 147 6.2.2 定义自己的引用 147 6.2.3 使用点操作符的技巧 148 6.2.4 类的数组 149 6.3 小结:Java其实是个类和对象的世界...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    6.1.7 null关键字 145 6.2 巧妙使用类中的属性 147 6.2.1 在类中给每个变量一个初始值 147 6.2.2 定义自己的引用 147 6.2.3 使用点操作符的技巧 148 6.2.4 类的数组 149 6.3 小结:Java其实是个类和对象的世界...

Global site tag (gtag.js) - Google Analytics