NULL OBJECT模式

本文介绍了一种用于简化代码并避免空引用错误的方法——NULL对象模式。通过具体示例展示了如何在Book类中实现NULL对象模式,使代码更加简洁。同时,文章还探讨了.NET框架中Stream类的NULL对象模式实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Employee e = DB.GetEmployee(“Bob”);

If(e != null && e.IsTimeToday(today))

 e.Pay();

上述代码的用法很常见,我们从数据库中查找名为Bob的员工,如果该对象不存在,返回null,如果存在,判断是它的发薪日,就调用Pay方法。&&操作可以保证仅当第一个表达式为真时才执行第二个表达式。然而有些时候我们总会忘记对null的检查而导致程序出错。有什么方法可以避免这些判断语句呢?这里可以提供一种解决方案,即NULL OBJECT模式。NULL OBJECT模式提供了当对象为空时的行为,但是它什么也没有做。灵活的使用NULL OBJECT模式可以简化我们的代码。

对于如何理解和应用NULL OBJECT模式,以一个简单的例子来说明一下。

ContractedBlock.gifExpandedBlockStart.gifCode
public abstract class Book
{
      
public abstract bool Borrowable () ;
      
public abstract void Borrow(); 

      
public static readonly Book NULL;
      
private sealed class NullBook:Book
      { 
           
public override bool Borrowable()
           {
                
return false;
            }

           
public override void Borrow()
           {

            }
      }
}

有了上面的类,我们在程序中就可以这样来应用:

Book b = DB.GetBookByID(“1000”);

If(b. Borrowable())

{

       b.Borrow();

}

由上可以看出,在程序中我们可以直接使用Book的实例,而不用判断它的引用是否为空,因为无论如何,它都返回一个有效的对象。在以前的代码中,如果调用Book的地方很多,那么每个地方都会充斥着判断其引用是否为空的代码。有了NULL OBJECT我们的代码精简了不少。

FCL中也有用NULL OBJECT模式的例子。在System.IO中关于Stream的实现中就用到了该模式,我们来看看它的实现:

ContractedBlock.gifExpandedBlockStart.gifCode
public abstract class Stream : MarshalByRefObject, IDisposable
{
    
public abstract bool CanRead { get; }
    
public abstract bool CanSeek { get; }
    
public abstract bool CanWrite { get; }
    
public abstract long Length { get; }
    
public abstract long Position { getset; }

    
public abstract void Flush();
    
public abstract int Read([In, Out] byte[] buffer, int offset, int count);
    
public virtual int ReadByte();
    
public abstract long Seek(long offset, SeekOrigin origin);
    
public abstract void SetLength(long value);
    [HostProtection(SecurityAction.LinkDemand, Synchronization
=true)]
    
public static Stream Synchronized(Stream stream);
    
public abstract void Write(byte[] buffer, int offset, int count);
    
public virtual void WriteByte(byte value);

    
public static readonly Stream Null;
    
private sealed class NullStream : Stream
    {
        
internal NullStream();
        
public override void Flush();
        
public override int Read([In, Out] byte[] buffer, int offset, int count);
        
public override int ReadByte();
        
public override long Seek(long offset, SeekOrigin origin);
        
public override void SetLength(long length);
        
public override void Write(byte[] buffer, int offset, int count);
        
public override void WriteByte(byte value);

        
// Properties
        public override bool CanRead { get; }
        
public override bool CanSeek { get; }
        
public override bool CanWrite { get; }
        
public override long Length { get; }
        
public override long Position { getset; }

    }
}

 

转载于:https://www.cnblogs.com/qinwater/archive/2009/01/05/1369758.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值