概述

Null Object 是Martin 大师提出的一种重构手段,其思想就是通过多态(派生一个Null对象)来减少逻辑(if … then …else)的判断。

而.NET中已经有Null Object 的使用原型了——“类型.Empty”。

//1)
String.Empty
//2)
return Enumerable.Empty<ModelValidationResult>();
//3)
return GetRouteDataValue<IEnumerable<RouteData>>(routeData, RouteDataTokenKeys.DirectRouteMatches) ?? Enumerable.Empty<RouteData>();

下面我们就来实现一个Empty。

使用Empty

1)抽取一个接口INullable

理由:仿照《重构》的例子,同时通过一个IsNull来体现是否为空对象。

public interface INullable
{
bool IsNull();
}

2)定义Payer对象

描述:一个支付对象,拥有一个Pay的方法,进行商品的支付。

同时,其实现了Empty模式,代表Null Object。

NewNull方法为一个参考(和原书上讲的对比),可以直接去掉。

public class Payer : INullable
{
#region 实现Null Object 模式 private static readonly Payer _Empty = new NullPayer();
public static Payer Empty
{
get
{
return _Empty;
}
} public static Payer NewNull()
{
return new NullPayer();
} #endregion /// <summary>
/// 支付
/// </summary>
/// <param name="money"></param>
public virtual void Pay(decimal money)
{
// do pay
Console.WriteLine(string.Format("支付:{0}元!", money));
} public virtual bool IsNull()
{
return false;
}
}

3)定义NullPayer,

描述:为了去除“if (payer == null )”,用一个NullPayer进行替换。

实际上就是多态的体现

/// <summary>
/// 空对象
/// </summary>
public class NullPayer : Payer
{
public override bool IsNull()
{
return true;
} public override void Pay(decimal money)
{
//skip do nothing
}
}

4)测试

简单的测试,将Empty方式推向到可以应用的层面。感谢Martin大师!!!

[TestFixture]
public class PayerTests
{
#region INullable接口测试 [Test]
public void InstanceOfPayerWillBeNotNull()
{
var payer = new Payer();
Assert.False(payer.IsNull());
} [Test]
public void InstanceOfNullPayerWillBeNull()
{
var payer = new NullPayer();
Assert.True(payer.IsNull());
} #endregion [Test]
public void EmptyIsInstancOfNullPayer()
{
var payer = Payer.Empty;
Assert.IsInstanceOf<NullPayer>(payer);
} [Test]
public void UserEmptyForPayDoNothing()
{
var payer = DbMethodGetEmptyPayer();
payer.Pay(); payer = DbMethodGetNotNullPayer();
payer.Pay();
} private Payer DbMethodGetEmptyPayer()
{
return Payer.Empty;
} private Payer DbMethodGetNotNullPayer()
{
return new Payer();
} //public void OrigenCode()
//{
// var pay = new Payer();
// if (pay != null)
// {
// pay.Pay(150);
// }
//}
}

使用“Empty 模式”改进 Null Object的更多相关文章

  1. 设计模式:空对象模式(Null Object Pattern)

    设计模式:空对象模式(Null Object Pattern) 背景 群里聊到<ASP.NET设计模式>,这本书里有一个“Null Object Pattern”,大家就闲聊了一下这个模式 ...

  2. 被遗忘的设计模式——空对象模式(Null Object Pattern)

    GoF(四人帮)那本<设计模式 可复用面向对象软件的基础>可谓是设计模式方面的经典之作,其中介绍的23种设计模式, 也可谓是经典中的经典.但是,设计模式的种类绝不仅仅是这23种,除此之外还 ...

  3. 【设计模式 - 21】之空对象模式(Null Object)

    1      模式简介 在空对象模式中,一个空对象取代NULL对象的实例的检查.NULL对象不是检查空值,而是反映一个不做任何动作的关系.这样的NULL对象也可以在数据不可用的时候提供默认的行为. 在 ...

  4. 空对象模式(Null Object Pattern)

    空对象模式:用一个空对象来取代null实例的检查,空对象实现一个不做任何动作的关系.(消除如if(Object == null) 这样的检查null实例代码) 例子: public abstract ...

  5. 设计模式之美:Null Object(空对象)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Null Object 的示例实现. 意图 通过对缺失对象的封装,以提供默认无任何行为的对象替代品. Encapsulate t ...

  6. Java 空对象设计模式(Null Object Pattern) 讲解

    转自:http://www.cnblogs.com/haodawang/articles/5962531.html 有时候我们的代码中为避免 NullPointerException 会出现很多的对N ...

  7. 设计模式之空对象(Null Object)模式

    通过引用Null Object,用于取消业务逻辑中对对象的为空推断 类图: Nullable: package com.demo.user; public interface Nullable { b ...

  8. Introduce Null Object

    今天继续总结<重构>这本书中的一个重构手法,Introduce Null Object.写这个手法是因为它确实很巧妙,在实际编程中经常会遇到这种情况,前人总结出来了这么一个经典的手法,当然 ...

  9. 重学c#系列——string.empty 和 "" 还有null[二十]

    前言 简单整理一下string.empty 和 "" 还有 null的区别. 正文 首先null 和 string.empty 还有 "" 是不一样的. nul ...

随机推荐

  1. XSS的DOS攻击之 server limit dos

    墨西哥同学周末很郁闷的在宾馆上网,发现youtube被ban了,于是写个了tool解决这个问题.顺带想到了一种利用 google 统计的漏洞,写在这里了 http://sirdarckcat.blog ...

  2. [Effective JavaScript 笔记] 第1章:让自己习惯javascript小结

    在这里整理一下,每条对应的提示 第1条:了解使用的js版本 确定应用程序支持的js的版本(浏览器也是应用程序噢) 确保使用的js特性是应用程序支持的(要不写了也运行不了) 总是在严格模式下编写和测试代 ...

  3. 在Linux用户空间做内核空间做的事情

    导读 我相信,Linux 最好也是最坏的事情,就是内核空间(kernel space)和用户空间(user space)之间的巨大差别.如果没有这个区别,Linux 可能也不会成为世界上影响力最大的操 ...

  4. Linux的防火墙--IP Tables

    导读 IP Table已经集成在Linux 2.4及以上版本的内核中,同Windows下的众多“傻瓜”防火墙不同的是,IP Table需要用户自己定制相关规则.下面我就给大家简单介绍一下关于防火墙的基 ...

  5. JdbcTemplate三种常用回调方法

    JdbcTemplate针对数据查询提供了多个重载的模板方法,你可以根据需要选用不同的模板方法. 如果你的查询很简单,仅仅是传入相应SQL或者相关参数,然后取得一个单一的结果,那么你可以选择如下一组便 ...

  6. [Educational Codeforces Round 16]C. Magic Odd Square

    [Educational Codeforces Round 16]C. Magic Odd Square 试题描述 Find an n × n matrix with different number ...

  7. Python socket 详解

    socket()函数用于根据指定的地址族.数据类型和协议来分配一个套接口的描述字及其所用的资源.如果协议protocol未指定(等于0),则使用缺省的连接方式. 对于使用一给定地址族的某一特定套接口, ...

  8. 解决虚拟机 正在决定eht0 的ip信息失败 无链接-- 虚拟机上linux redhat 上网问题

    对于虚拟机上,linux redhat上网的配置方式有三种 一.用setup命令进行配置(具体技巧可查setup命令的使用) 二.直接用 ifconfig eth0  ip地址进行配置 三.进入系统文 ...

  9. Java for LeetCode 028 Implement strStr()

    Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if needle ...

  10. Heap:Moo University - Financial Aid(POJ 2010)

       牛的学校 题目大意:这只Bessie真是太顽皮了,她又搞了个学校,准备招生,准备通过一个考试筛选考生,但是不能招到每个学生,每个学生也不能一定能上学,要资助,问你在一定资金内,怎么收学生,使收到 ...