上一次漏掉了最重要的異步,測試覆蓋: 正則表達式
本覺得會秀一個漂亮的100%覆蓋率的測試出來,人算不如天算,竟然有一個方法是75%! 編程
(本文版權屬於© 2012 - 2013 予沁安) c#
恩,無效的生日沒有測試。 異步
很簡單,就增長一個測試而已,就不在這羅嗦了。直接貼覆蓋率,顯擺一下。 測試
再顯擺一下代碼質量參數: 優化
複雜度 最大的就是構造器了。可維護指標仍是不錯的 76分。 spa
零零碎碎的改進,你能夠如前面同樣,基於一個一個測試縱向改,也能夠所有改完在一塊兒測試,沒有太大關係,前者是嚴格的測試驅動。可是,我以爲不需太學術化,關鍵是,你的任務足夠小,能在今天完成,那就是合適。 code
1。 把全部的信息塊改爲屬性方式,由於,一個是Java與C#的區別,第二,把原代碼的緩衝生日的邏輯作到極致(極限編程?呵),一開始就緩衝(構造器中) blog
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。數據解析放在構造器中,而且獨立成方法,只是在構造器中調用
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("身份證的出生日期無效"); } }3。從以前的代碼分析參數,看到構造器複雜度過高,主要是幾個驗證。作一個改進,一個提出驗證方法,二個去掉null, empty的驗證,由於正則表達式已經包含了。
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."); }
public SocialID(String cardNumber) { validate(cardNumber); CardNumber= cardNumber; extract(); }
可維護性提升到82,複雜度最高是validate() 3, ci
徹底代碼,是否是很清晰了?
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; } } }