前言
Clean Code,老圣经一本,是一本如何撰写大家都能轻易看懂的Code,当中最重要的是阅读程式,因此特别开一篇文章聊一聊阅读程式,主要是未来希望能拿来当教育训练用的文件。
以下会用一个题目当範例,当然这也是我常用的面试题,并在后续留下常见的解,请各位体验一下,何谓阅读程式。
5/28 09:30对于许多内容增加了语意修正,解释。
题目
这是会议过后,PM给的客户需求,需求为:
完成以下闰年的规则的Function,无论语言。
答案
以下会列出常见的几种答案,并且在下面注解用中文阅读的状况。
答案1
function isLeap(year) { return ((year % 4) === 0 && (year % 100) !== 0) || (year % 400) === 0;}
公元年为4的倍数 且 公元年非100的倍数, 或 公元年为400的倍数,为闰年。答案2
function isLeap(year) { if (year % 4 === 0 && year % 100 !== 0) return true; else if (year % 400 === 0) return true; else return false;}
公元年为4的倍数 且 公元年非100的倍数,为闰年。公元年为400的倍数,为闰年。剩下则为平年。答案3
function isLeap(year) { if (year % 4 === 0) { if (year % 100 === 0) { if (year % 400 === 0) { return true; } else { return false; } } else { return true; } else { return false; }}
如下图:
答案4
function isLeap(year) { if (year % 400 === 0) return true; else if (year % 100 === 0) return false; else if (year % 4 === 0) return true; else return false;}
公元年为400的倍数,为闰年。其他公元年为100的倍数,为平年。其他公元年为4的倍数,为闰年。其他公元年,为平年。答案5
function isLeap(year) { if (year % 4 !== 0) return false; if (year % 4 === 0 && year % 100 !== 0) return true; if (year % 100 === 0 && year % 400 !== 0) return false; if (year % 400 === 0) return true;}
公元年分非4的倍数,为平年。公元年分为4的倍数但非100的倍数,为闰年。公元年分为100的倍数但非400的倍数,为平年。公元年分为400的倍数为闰年。答案6
function isLeap(year) { if (year % 4 !== 0) return false; else if (year % 100 !== 0) return true; else if (year % 400 !== 0) return false; return true;}
公元年分非4的倍数,为平年。其他公元年为非100的倍数,为闰年。其他公元年为非400的倍数,为平年。其他公元年,为闰年。分析
个人会选择答案5或答案6,原因是,今天PM、客户,在会议后,提出了非常明确的需求,我不建议去做转换(换句话说),这样的行为在我的工作经验中,是具有高风险的,非常常看到,难解的逻辑bug都是放在这种状况内,如果一开始就选择答案5、答案6去撰写程式,一来你会code会完成的非常快,因为只做翻译;二来不可能失误,会失误的话,PM、客户刚开始就是错的,如果真的不满意这样的需求,也应该透过会议讨论修正。
效能争议
对于效能争议,我认为这个争议是非常小的,原因如下:
无论如何撰写这题目永远会是三层判断。若编译上面的所有答案,编译结果都会非常接近。在讨论演算法时,通常是讨论倍数、指数的效能问题,而非讨论一行两行的效能优化。根据我的工作经验,更多时候在讨论效能问题前,更常见的是程式过度术语化、複杂化,造成商业上损失的bug,更为常见,个人是提倡清楚的Code、降低Bug,而非效能摆在第一位。确实有个缺点,在类似JS的环境中,你会将整个档案传送到前端运行,语句的长短,会影响到传输的效能,但个人认为比起bug这样的缺点值得的。结语
这是我第一次在iT邦帮忙发文,未来是否发文,就看有没有我现实工作上讨论到烂掉的话题了,谢谢大家。