可以說,到了今天,我才真正能開始做我想要的重構/改進。之前,只是補充測試,調整了一下結構。
是的,非常的緩慢,這居然被稱為“敏捷”!? 你說奇怪不奇怪?
還好,這種節奏適合我這種大齡青年,合用就好,關它是風花還是雪月。
==》 測試覆蓋
上一次漏掉了最重要的非同步,測試覆蓋:
本以為會秀一個漂亮的100%覆蓋率的測試出來,人算不如天算,居然有一個方法是75%!
(本文著作權屬於 2012 - 2013 予沁安)
恩,無效的生日沒有測試。
很簡單,就增加一個測試而已,就不在這羅嗦了。直接貼覆蓋率,顯擺一下。
再顯擺一下代碼品質參數:
複雜度 最大的就是構造器了。可維護指標還是不錯的 76分。
==>最佳化改進:屬性,靜態設值和其他
零零碎碎的改進,你可以如前面一樣,基於一個一個測試縱向改,也可以全部改完在一起測試,沒有太大關係,前者是嚴格的測試驅動。但是,我覺得不需太學術化,關鍵是,你的任務足夠小,能在今天完成,那就是合適。
1。 把所有的資訊塊改成屬性方式,因為,一個是Java與C#的區別,第二,把原代碼的緩衝生日的邏輯做到極致(極限編程?呵),一開始就緩衝(構造器中)
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的驗證,因為Regex已經包含了。
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(); }==》OK,現在可以站起來,來杯咖啡,欣賞一下我們的成果
可維護性提高到82,複雜度最高是validate() 3,
完全代碼,是不是很清晰了?
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; } }}
(本文著作權屬於 2012 - 2013 予沁安 | 轉載請註明作者和出處)