• C#编程实践–产假方案优化版


    前言

    既然作为一个踏踏实实学习技术的人,就要有一颗谦卑、虚心和追求卓越的心,我不能一次就写出很完美的代码,但我相信,踏踏实实一步一步的优化,代码就可以变得趋近完美,至少在某一个特定场景下相对完美,这和做人有很类似的道理,这是一种态度。前几天,发了我在博客园的第一篇编码实践《C#编程实践–帮老婆计算产假方案》(简称前文),引来了几位博友(这其中还有几位是以前一起共事几年的同学和同事,感慨大家在技术道路上的坚持和不易)的围观,他们好心点个赞我表示很感激,当然他们也提出了建议,对于这些建议我也不打算置之不理,所以又有了此文。

    复杂 or 简单?

    复杂和简单,在某些时候是个相对的概念。前文中,某些朋友提出我的代码有些复杂。我本着谦虚的态度来进行分析,我必须承认,我写的代码有过度设计之嫌,违反了K.I.S.S原则。我的工作经验导致我常常以中大型项目的思维方式去写代码,会考虑面向对象的设计,考虑架构系统的一些指标以及规范(高可用性、稳定性、可读性、可维护性、可扩展性、可测试性等等),所以有些朋友说我的代码过于复杂,我想我可以比较简洁的去概况我的思路,让大家知道我的初衷。

    • 假日定义

    image

    职责:节日的表达和存储结构

    属性:使用月、日和历法来表示节日

    静态只读字段:表示不可变的常量,代替魔法变量(Magic Number)

    设计参考:参考.net framework BCL的DateTime结构定义

    • 假期定义

    image

    职责:假期的表达和存储结构

    属性:节日、放假规定(提前几天放,一共几天假)

    逻辑:将假期转变为通用的枚举集合(IEnumerable<DateTime>)

    • 逻辑规则

    判断是否假期的规则逻辑,接口如下

       1: public static bool IsHoliday(this DateTime date);
       2: public static bool IsHoliday(this DateTime date, IEnumerable<Holiday> holidays);
    • 结论

    至此,我想,大家认为所谓的复杂,在于两点:

    1. 数据的存储和表示,“我去翻翻日历,用一个集合来存储所有假期日期不就完了嘛!”
    2. 逻辑的关联依赖,IsHoliday的逻辑使用扩展方法表示并与Holidays依赖,其实这里可以进行一定的优化,比如:
       1: public static bool IsHoliday(this DateTime date, Func<DateTime,Boolean> holidayCondition);

    使用委托,此处参考IEnumerable<T>的LINQ扩展方法设计,依赖于委托,让调用者实现具体逻辑

    优化

    我在前文中提到,LINQ查询可以进行一定的优化,我那个查询显然很糟糕,要知道从一个时间段里选出98天的间隔需要两次迭代吗?天哪,记起来了吗?这就是笛卡尔积的数量级啊,我们完全没必要进行SelectMany操作啊对不对,使用一次迭代就可以搞定的查询干嘛要用两次查询呢?对不对,以下是优化过的LINQ查询:

       1: var begin = new DateTime(2014, 1, 1);
       2: var end = new DateTime(2015, 12, 31);
       3: var sample = DateUtility.RangeDay(begin, end);
       4:  
       5: var solutions =
       6:     from iterator in sample
       7:     let last = iterator.AddDays(days - 1)
       8:     let range = DateUtility.RangeDay(iterator, last)
       9:     where last <= end
      10:     select new
      11:     {
      12:         Begin = iterator,
      13:         End = last,
      14:         HolidayCount = range.Count(d => d.IsHoliday())
      15:     };
      16:  
      17: var local = solutions.ToList();

    结语

    写代码很简单,写出优质代码则很难。本来还想再写一个简化版的(因为大家都觉得过于复杂),但时间有限,先到这里了!

  • 相关阅读:
    转:jQuery选择器大全(48个代码片段+21幅图演示)
    转:Web 开发中很实用的10个效果【附源码下载】
    转:在网站开发中很有用的8个 jQuery 效果【附源码】
    转:35个让人惊讶的 CSS3 动画效果演示
    转:总结const、readonly、static三者的区别
    转:C# 深入理解堆栈、堆在内存中的实现
    推荐:Asp.Net MVC 多语言(html+js共用一套资源文件)
    转:HttpModule与HttpHandler详解
    转: ASP.NET MVC 多语言配置
    spring集合类型注入
  • 原文地址:https://www.cnblogs.com/fecktty2013/p/csharp-practice-holidaycalculator-beta.html
Copyright © 2020-2023  润新知