zoukankan      html  css  js  c++  java
  • 使用“Empty 模式”改进 Null Object

    概述

    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(100);
    
            payer = DbMethodGetNotNullPayer();
            payer.Pay(100);
        }
    
        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);
        //    }
        //}
    }
  • 相关阅读:
    图片轮播切换
    php用get_meta_tags轻松获取网页的meta信息
    PHP创建桌面快捷方式实例
    php 获取网站根目录的写法
    php mkdir 创建多级目录实例代码
    php计算剩余时间的自定义函数
    php实现获取汉字的首字母实例
    PDO封装函数
    Struts动态表单(DynamicForm)
    [WPF]静态资源(StaticResource)和动态资源(DynamicResource)
  • 原文地址:https://www.cnblogs.com/pengzhen/p/3801277.html
Copyright © 2011-2022 走看看