使用Null Object设计模式

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 在ESFramework的设计实现中,很多地方都用到了Null Object设计模式。Null Object模式的含义在于,提供一个对象给指定的类型,用以代替这个对象为空的情况。 Null Object提供了“什么也不做”的行为,隐藏来自它的合作者的细节。

   在ESFramework的设计实现中,很多地方都用到了Null Object设计模式。Null Object模式的含义在于,提供一个对象给指定的类型,用以代替这个对象为空的情况。 Null Object提供了“什么也不做”的行为,隐藏来自它的合作者的细节。
   对于如何理解和应用该模式,通过一个实例就能很好的进行说明。这一节我们在讨论消息分派器,消息分派器使用了前述的日志记录器,并且通过属性来注入具体的日志记录器对象。

         private  IEsfLogger esfLogger;
        
public  IEsfLogger EsfLogger
        {
            
set
            {
                
this .esfLogger  =  value;
            }
        }    

    现在假设,我们在消息分派器内部的多个地方使用日志记录器来进行日志记录,我们总要写这样的语句:

     if  ( this .esfLogger  !=   null )
     {
          
this .esfLogger.Log();  // 记录日志
     }

    也就是说,在使用之前,我们都要判断一下日志记录器的引用是否为空,如果不为空才可以调用其Log方法。如果调用日志记录器进行日志记录的地方很多,那么每个地方都会充斥着这种判断其引用是否为空的代码。有没有办法来避免这所有的判断语句了,有!那就是使用Null Object设计模式。
    ESFramework为每种必要的组件都提供了对应的Null Object类型,这些类型的名字以“Empty”作为前缀。比如IEsfLogger对应的Null Object类型就是EmptyEsfLogger,EmptyEsfLogger实现的Log方法什么也不用做:

        public   void  Log( string  errorType , string  msg,  string  location, ErrorLevel level)
        {
            
// Do Nothing !
        }

   有了EmptyEsfLogger,我们就可以象这样来设计消息分派器的日志记录器属性:

        private  IEsfLogger esfLogger  =   new  EmptyEsfLogger();
        
public  IEsfLogger EsfLogger
        {
            
set
            {
                
if  (value  !=   null )
                {
                    
this .esfLogger  =  value  ??   new  EmptyEsfLogger();
                }
            }
        }

   首先,将esfLogger字段的默认值设为一个Null Object。其次,当调用者每次试图将EsfLogger属性设置为null时,也将一个Null Object赋值给该字段。
   如此一来,在消息分配器内部,我们就可以非常方便的直接使用日志记录器,而不用再判断其引用是否为空,因为无论如何,它总是指向一个有效的对象,即使这个对象是Null Object。

    除了常见的组件装配可以使用Null Object模式外,还有一个非常适合使用Null Object模式的场合,那就是“事件”。你是否还记得,我们每次触发事件时都需要判断其是否为空,这也是非常琐碎的事情,我们仍然可以通过Null Object模式来简化它。比如某个类中定义了一个事件:

public   event  CbSimple SomeOneConnected;

在类的构造函数中,可以使用Null Object来初始化它:

this .SomeOneConnected  +=   delegate  { };

这样,在每次触发事件时就不用再判断其是否为null了:

this .SomeOneConnected();  // 不用再判断是否为null,直接触发事件

   灵活地使用Null Object设计模式,可以使得我们的代码更加简洁和精炼。


注:本文节选自我的书稿 《.NET通信框架的设计、实现与应用》





 

相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
目录
相关文章
|
5月前
|
设计模式 监控 Java
并发设计模式实战系列(8):Active Object
🌟 大家好,我是摘星!🌟今天为大家带来的是并发设计模式实战系列,第8章,废话不多说直接开始~
84 0
并发设计模式实战系列(8):Active Object
|
5月前
|
设计模式 安全 Java
并发设计模式实战系列(12):不变模式(Immutable Object)
🌟 大家好,我是摘星!🌟今天为大家带来的是并发设计模式实战系列,第十二章,废话不多说直接开始~
100 0
|
JavaScript 前端开发
为什么typeof null 是object
为什么typeof null 是object
203 1
|
设计模式 Java API
【设计模式】JAVA Design Patterns——Active Object(活动对象设计模式)
【设计模式】JAVA Design Patterns——Active Object(活动对象设计模式)
|
JavaScript 前端开发
js基础语法:包括变量声明、数据类型(Number, String, Boolean, Null, Undefined, Symbol, Object)、运算符、流程控制语句(if...else, switch, for, while, do...while)等。具体案例使用演示
js基础语法:包括变量声明、数据类型(Number, String, Boolean, Null, Undefined, Symbol, Object)、运算符、流程控制语句(if...else, switch, for, while, do...while)等。具体案例使用演示
161 1
|
JavaScript 前端开发
为什么typeof null == 'object' 为true?
为什么typeof null == 'object' 为true?
101 0
|
JavaScript 前端开发
JavaScript基础语法:包括变量声明、数据类型(Number, String, Boolean, Null, Undefined, Symbol, Object)、运算符、流程控制语句(if...else, switch, for, while, do...while)等。
JavaScript基础语法:包括变量声明、数据类型(Number, String, Boolean, Null, Undefined, Symbol, Object)、运算符、流程控制语句(if...else, switch, for, while, do...while)等。
149 0
|
设计模式 uml
空对象模式(Null Object Pattern)
空对象模式(Null Object Pattern)不属于GoF设计模式,但是它作为一种经常出现的模式足以被视为设计模式了。其具体定义为设计一个空对象取代NULL对象实例的检查。NULL对象不是检查控制,而是反映一个不做任何动作的关系。这样的NULL对象也可以在数据不可用的时候提供默认的行为,属于行为型设计模式。
214 0
|
JavaScript 前端开发 Java
为什么使用typeof判断数据类型的时候null出来是object?
为什么使用typeof判断数据类型的时候null出来是object?
|
设计模式 算法 Java
Object 类详解--代码块--单例设计模式
Object 类详解--代码块--单例设计模式
122 0

热门文章

最新文章