它山之玉可以重构:身份证号4(第四天)
可以说,到了今天,我才真正能开始做我想要的重构/改进。之前,只是补充测试,调整了一下结构。
是的,非常的缓慢,这居然被称为“敏捷”!? 你说奇怪不奇怪?
还好,这种节奏适合我这种大龄青年,合用就好,关它是风花还是雪月。
==》 测试覆盖
上一次漏掉了最重要的异步,测试覆盖:
本以为会秀一个漂亮的100%覆盖率的测试出来,人算不如天算,居然有一个方法是75%!
(本文版权属于© 2012 - 2013 予沁安)
恩,无效的生日没有测试。
很简单,就增加一个测试而已,就不在这罗嗦了。直接贴覆盖率,显摆一下。
再显摆一下代码质量参数:
复杂度 最大的就是构造器了。可维护指标还是不错的 76分。
==>优化改进:属性,静态设值和其他
零零碎碎的改进,你可以如前面一样,基于一个一个测试纵向改,也可以全部改完在一起测试,没有太大关系,前者是严格的测试驱动。但是,我觉得不需太学术化,关键是,你的任务足够小,能在今天完成,那就是合适。
1。 把所有的信息块改成属性方式,因为,一个是Java与C#的区别,第二,把原代码的缓冲生日的逻辑做到极致(极限编程?呵),一开始就缓冲(构造器中)
1 2 3 4 | public string CardNumber { get ; private set ; } public string AddressCode { get ; private set ; } public DateTime BirthDate { get ; private set ; } public Gender Gender { get ; private set ; } |
2。数据解析放在构造器中,并且独立成方法,只是在构造器中调用
1 2 3 4 5 6 | void extract() { AddressCode = CardNumber.Substring(0, 6); Gender = (( int ) CardNumber[CARD_NUMBER_LENGTH - 2])%2 == 0 ? Gender.Female : Gender.Male; BirthDate = extract_birth_date(); } |
日期足够复杂,所以又独立出方法
1 2 3 4 5 6 7 8 9 10 11 | public DateTime extract_birth_date() { try { return DateTime.ParseExact(CardNumber.Substring(6, 8), BIRTH_DATE_FORMAT, null ); } catch (Exception e) { throw new ApplicationException( "身份证的出生日期无效" ); } } |
3。从之前的代码分析参数,看到构造器复杂度太高,主要是几个验证。做一个改进,一个提出验证方法,二个去掉null, empty的验证,因为正则表达式已经包含了。
1 2 3 4 5 6 7 8 | private void validate( string cardNumber) { if (!SOCIAL_NUMBER_PATTERN.IsMatch(cardNumber)) throw new ApplicationException( "Card Number has wrong charactor(s)." ); if (cardNumber[CARD_NUMBER_LENGTH - 1] != verifier.verify(cardNumber)) throw new ApplicationException( "Card Number verified code is not match." ); } |
1 2 3 4 5 6 | public SocialID(String cardNumber) { validate(cardNumber); CardNumber= cardNumber; extract(); } |
==》OK,现在可以站起来,来杯咖啡,欣赏一下我们的成果
可维护性提高到82,复杂度最高是validate() 3,
完全代码,是不是很清晰了?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | using System; using System.Text.RegularExpressions; namespace Skight.eLiteWeb.Domain { public enum Gender { Female, Male } public class SocialID { private static Verifier verifier = new Verifier(); private static String BIRTH_DATE_FORMAT = "yyyyMMdd" ; private static int CARD_NUMBER_LENGTH = 18; private static Regex SOCIAL_NUMBER_PATTERN = new Regex( @"^[0-9]{17}[0-9X]$" ); public SocialID(String cardNumber) { validate(cardNumber); CardNumber= cardNumber; extract(); } private void validate( string cardNumber) { if (!SOCIAL_NUMBER_PATTERN.IsMatch(cardNumber)) throw new ApplicationException( "Card Number has wrong charactor(s)." ); if (cardNumber[CARD_NUMBER_LENGTH - 1] != verifier.verify(cardNumber)) throw new ApplicationException( "Card Number verified code is not match." ); } void extract() { AddressCode = CardNumber.Substring(0, 6); Gender = (( int ) CardNumber[CARD_NUMBER_LENGTH - 2])%2 == 0 ? Gender.Female : Gender.Male; BirthDate = extract_birth_date(); } public DateTime extract_birth_date() { try { return DateTime.ParseExact(CardNumber.Substring(6, 8), BIRTH_DATE_FORMAT, null ); } catch (Exception e) { throw new ApplicationException( "身份证的出生日期无效" ); } } public string CardNumber { get ; private set ; } public string AddressCode { get ; private set ; } public DateTime BirthDate { get ; private set ; } public Gender Gender { get ; private set ; } } } |
皓月碧空,漫野如洗,行往卓越的路上
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步