它山之玉能夠重構:身份證號(第四天)

能夠說,到了今天,我才真正能開始作我想要的重構/改進。以前,只是補充測試,調整了一下結構。
是的,很是的緩慢,這竟然被稱爲「敏捷」!? 你說奇怪不奇怪? 
還好,這種節奏適合我這種大齡青年,合用就好,關它是風花仍是雪月。

==》 測試覆蓋

上一次漏掉了最重要的異步,測試覆蓋: 正則表達式

本覺得會秀一個漂亮的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();
        }

==》OK,如今能夠站起來,來杯咖啡,欣賞一下咱們的成果

可維護性提升到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; }
    }
}

(本文版權屬於© 2012 - 2013 予沁安 | 轉載請註明做者和出處

相關文章
相關標籤/搜索