前言

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

复杂 or 简单?

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

  • 假日定义

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

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

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

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

  • 假期定义

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

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

逻辑:将假期转变为通用的枚举集合(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();

结语

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

C#编程实践–产假方案优化版的更多相关文章

  1. C#编程实践–帮老婆计算产假方案

    摘要 今天中午午休时,和老婆聊天,老婆还过几天就要请产假了,她在网上问我让我帮她数一下该怎么请假最划算,老婆是个会过日子的人,面对此种要求我当然义不容辞,不过想到这个问题我的第一反应是:这个怎么可以用 ...

  2. 试读《JavaScript语言精髓与编程实践》

    有幸看到iteye的活动,有幸读到<JavaScript语言精髓与编程实践_第2版>的试读版本,希望更有幸能完整的读到此书. 说来读这本书的冲动,来得很诡异,写一篇读后感,赢一本书,其实奖 ...

  3. Python入门经典. 以解决计算问题为导向的Python编程实践

    Python入门经典. 以解决计算问题为导向的Python编程实践(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1juLsew8UiOErRheQPOuTaw 提取 ...

  4. OpenGL编程指南(第七版)

    OpenGL编程指南(第七版) 转自:http://blog.csdn.net/w540982016044/article/details/21287645 在接触OpenGL中,配置显得相当麻烦,特 ...

  5. 2018.6.19 Java核心API与高级编程实践复习总结

    Java 核心编程API与高级编程实践 第一章 异常 1.1 异常概述 在程序运行中,经常会出现一些意外情况,这些意外会导致程序出错或者崩溃而影响程序的正常执行,在java语言中,将这些程序意外称为异 ...

  6. JavaScript DOM编程艺术(第2版)的简单总结

    介绍 JavaScript DOM编程艺术(第2版)主要讲述了 JavaScript.DOM 和 HTML5 的基础知识,着重讲述了 DOM 编程,并通过几个实例演示了具有专业水准的网页开发. 下面介 ...

  7. 高性能javascript学习笔记系列(5) -快速响应的用户界面和编程实践

    参考高性能javascript 理解浏览器UI线程  用于执行javascript和更新用户界面的进程通常被称为浏览器UI线程  UI线程的工作机制可以理解为一个简单的队列系统,队列中的任务按顺序执行 ...

  8. 高性能JavaScript 编程实践

    前言 最近在翻<高性能JavaScript>这本书(2010年版 丁琛译),感觉可能是因为浏览器引擎的改进或是其他原因,书中有些原本能提高性能的代码在最新的浏览器中已经失效.但是有些章节的 ...

  9. 编程实践中C语言的一些常见细节

    对于C语言,不同的编译器采用了不同的实现,并且在不同平台上表现也不同.脱离具体环境探讨C的细节行为是没有意义的,以下是我所使用的环境,大部分内容都经过测试,且所有测试结果基于这个环境获得,为简化起见, ...

随机推荐

  1. 跨境移动互联网的魅力演绎,hao123无论成就下一个条目?

        使用"热"为了描述的情况在目前的移动互联网不夸张,背景下,越来越多的企业试图染指这一新兴领域.只是,巴菲特有句名言------"仅仅有退潮了,才知道谁在裸泳&qu ...

  2. java.lang.IllegalStateException: You need to use a Theme.AppCompat theme

    配置: 中设置theme为 <application android:allowBackup="true" android:icon="@mipmap/ic_lau ...

  3. UVa753/POJ1087_A Plug for UNIX(网络流最大流)(小白书图论专题)

    解题报告 题意: n个插头m个设备k种转换器.求有多少设备无法插入. 思路: 定义源点和汇点,源点和设备相连,容量为1. 汇点和插头相连,容量也为1. 插头和设备相连,容量也为1. 可转换插头相连,容 ...

  4. Java虚拟机类型卸载和类型更新解析(转)

    转自:http://www.blogjava.net/zhuxing/archive/2008/07/24/217285.html [摘要]          前面系统讨论过java 类型加载(loa ...

  5. SyntaxHighlighter代码高亮插件

    SyntaxHighlighter它是Google Code在一个开源项目,主要用于对代码着色页, 使用十分方便,效果也不错,并且差点儿支持常见的全部语言. 使用步骤: 一.下载并解压缩SyntaxH ...

  6. C# LDAP 管理(创建新用户)

    今天用C#实现了一套LDAP域账号的创建和查询,感受挺多. 算是第一次接触LDAP吧,之前曾经做了一个登录的验证,就是查询功能,那个相对比较简单,用到了一个方法就搞定了. 这次的需求是要用编程的方式创 ...

  7. PHP第三个教训 PHP基本数据类型

    学习平台: 1.php七种变量类型 2.isset和empty到这两个功能区分 3.型式试验 4.自己主动类型转换 5.类型转换 注意: 1.通过 变量->方法名 来调用.  $user1 = ...

  8. web富客户端应用下,前端架构、系列(二)。

    序 我们在上面的文章中已经建立起来一个比较简单的 前端架构 虽然这个看上去很简陋. 不过毕竟也是思想的结晶. 从这一篇文章开始,我将陆续完善这一个前端架构.. 重新构思 上一篇我们把前端架构分为3个模 ...

  9. HDU 5037 FROG (贪婪)

    Problem Description Once upon a time, there is a little frog called Matt. One day, he came to a rive ...

  10. iOS根据获取的月和日星座名称

    /** * 依据月和日的下标获取星座名 * * @param monthIndex 月的下标 * @param dayIndex 日的下标 * * @return 星座名 */ - (NSString ...