天天看點

繼續說一說昨天提到的那個代碼重構

繼續說一說昨天提到的那個代碼重構

(因為那段代碼是錯的,現已修正)。下面再說一下這段代碼的特點和問題,歡迎有興趣并能看到詩的博友斧正。

而仔細看昨天那段代碼,除了行數多外,從效率上來說基本已是無懈可擊。這麼說有什麼依據,憑什麼說這個代碼很優化?那麼我們來看一下.NET Framework

1.1中QuoteJScriptString(string)方法的實作:

繼續說一說昨天提到的那個代碼重構

public static string QuoteJScriptString(string value)

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

{

繼續說一說昨天提到的那個代碼重構

    StringBuilder strbQuoted = new StringBuilder(value.Length + 5);

繼續說一說昨天提到的那個代碼重構

    for ( int i = 0; i < value.Length; i++)

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

        char ch = value[i];

繼續說一說昨天提到的那個代碼重構

        if (ch <= '"')

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

            switch(ch)

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                case '\t':

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                    strbQuoted.Append(@"\t");

繼續說一說昨天提到的那個代碼重構

                    continue;

繼續說一說昨天提到的那個代碼重構

                }

繼續說一說昨天提到的那個代碼重構

                case '\n':

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                    strbQuoted.Append(@"\n");

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                case '\v':

繼續說一說昨天提到的那個代碼重構

                case '\f':

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                    strbQuoted.Append(value[i]);

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                case '\r':

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                    strbQuoted.Append(@"\r");

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                case '"':

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                    strbQuoted.Append("\\\"");

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

            }

繼續說一說昨天提到的那個代碼重構

        }

繼續說一說昨天提到的那個代碼重構

        else

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

            if (ch == '\'')

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                strbQuoted.Append(@"\'");

繼續說一說昨天提到的那個代碼重構

                continue;

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

            if (ch == '\\')

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                strbQuoted.Append(@"\\");

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

        strbQuoted.Append(value[i]);

繼續說一說昨天提到的那個代碼重構

    }

繼續說一說昨天提到的那個代碼重構

    return strbQuoted.ToString();

繼續說一說昨天提到的那個代碼重構

}

要想知道自己寫的代碼是否是業餘水準,我認為可以參考一下上面這段代碼

繼續說一說昨天提到的那個代碼重構

。這段代碼我覺得唯一有意義的地方就是建立StringBuilder對象的時候,給出了Capacity的大小,而且也僅此這一點顯得和業餘水準之間有了一點點的差距。至于為什麼判斷ch

<= '"',我沒有太明白,是因為swith中case太多會有什麼效率問題嗎?雖然'"'是ASCII中順序裡的第二個可列印字元(不算Space),但是這樣将ch的檢測路徑分開,我沒有覺得有什麼大的意義。

那麼2.0中的QuoteJScriptString有什麼特點呢?一是:修改了bug,給QuoteJScriptString添加了一個forUrl的bool參數,訓示轉換時是否轉換"%"為其escape(JScript中的全局函數)形式。因為如果當你把腳本代碼使用到link的href中時,IE會自動的unescape這個字元串,再作為代碼解析執行。看下面的示例:

繼續說一說昨天提到的那個代碼重構

<a href="JavaScript: alert('%25%');">click</a>

如果在IE中你點選了click後,你覺得MsgBox裡會顯示啥?是"%25%"嗎?實際上顯示的是:"%%"。這就是為什麼新版的方法要添加forUrl開關參數的原因,是為了修複bug。二是:優化了QuoteJScriptString方法的效率,除了繼續沿用了建立StringBuilder那個地方外,還有三點。1)

做了參數合法性檢查;2) 消除了不必要的StringBuilder執行個體的建立;3)

對于不用替換的字元,使用區段處理代替了逐字處理。

    既然都說昨天那段挺不錯了,那麼還重構個頭啊?其實重構隻是一個镢頭了

繼續說一說昨天提到的那個代碼重構

。至于考證代碼是不是微軟原版的,我隻能說:别人看到了詩

繼續說一說昨天提到的那個代碼重構

,有的人看到屎

繼續說一說昨天提到的那個代碼重構

。真的要重構,也就主要是節省點代碼了,我相信程式員都是很懶的,即使打字再快,畢竟我們也不是打字員哈。給一個重構後的版本,代碼如下:

繼續說一說昨天提到的那個代碼重構

public static string QuoteJScript(string value, bool forUrl)

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

    if (StringHelper.IsEmpty(value))

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

        return string.Empty;

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

    StringBuilder strbQuoted = null;

繼續說一說昨天提到的那個代碼重構

    int i, position;

繼續說一說昨天提到的那個代碼重構

    i = position = 0;

繼續說一說昨天提到的那個代碼重構

    const string QUOTED_CHARS= "\t\n\v\f\r\"%'\\";

繼續說一說昨天提到的那個代碼重構

    string  [] QUOTED_STRINGS = 

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

{ @"\t", @"\n", @"\v", @"\f", @"\r", @"\""", @"%25", @"\'", @"\\" };

繼續說一說昨天提到的那個代碼重構

    for ( ; i < value.Length; i++)

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

        int index = QUOTED_CHARS.IndexOf(ch);

繼續說一說昨天提到的那個代碼重構

        if ( index >= 0 )

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

            if ( ch != '%' || ( ch == '%' && forUrl ) )

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                if ( strbQuoted == null )

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                    strbQuoted = new StringBuilder(value.Length + 5);

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                if ( i-position >= 1 )

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                    strbQuoted.Append(value, position, i-position);

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

                strbQuoted.Append(QUOTED_STRINGS[index]);

繼續說一說昨天提到的那個代碼重構

                position = i + 1;

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

    if (strbQuoted == null)

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

        return value;

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

    if ( i-position >= 1 )

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

        strbQuoted.Append(value, position, i-position);

繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構
繼續說一說昨天提到的那個代碼重構

最後有一個有趣的問題,你認為Fx 1.1和2.0中兩個QuoteJScriptString是同一個人寫的嗎?你覺得這種重構方式好不好?是你會怎麼做呢?

本文轉自部落格園鳥食軒的部落格,原文連結:http://www.cnblogs.com/birdshome/,如需轉載請自行聯系原部落客。

繼續閱讀