天天看點

代碼規範、如何寫出好代碼代碼規範、如何寫出好代碼

轉載請注明出處:

http://blog.csdn.net/gane_cheng/article/details/52152497

http://www.ganecheng.tech/blog/52152497.html (浏覽效果更好)

代碼規範、如何寫出好代碼

上大學以來,每當看到好的文章,第一反應都是使用浏覽器的收藏功能,收藏下來,久而久之,收藏的網址越來越多。雖然浏覽器收藏夾也有檔案夾的功能可以分門别類,但是終究沒有部落格的Tag好用,而且隻能收藏網址。内容被原作者修改,或者網址失效都是經常發生的事兒。考慮到CSDN應該輕易不會倒閉,還有呂兄和琥哥兩位大神的親身表率,特開通CSDN部落格。

作為一個程式員,肯定希望能寫出一手好代碼,看起來賞心悅目,又易于了解。既友善日後自己回來翻閱一眼就能明白代碼在幹什麼,又能讓接手的人很快上手,看到精妙的地方,不由自主地發出由衷的感歎,悄無聲息地改變别人不好的習慣。

如何才能寫出好代碼呢?

在一次講座上,我聽了一位程式設計大神的看法,在這裡分享給大家。

好的代碼應該至少具備下面這6個特點:

  1. 使用空行來分割邏輯
  2. 使用注釋和花括号
  3. 不用的代碼和引用删除
  4. 不要用中文拼音做變量名
  5. 可用,清晰優雅,高效
  6. 多寫代碼,多思考

使用空行來分割邏輯

一般代碼超過30行左右,我們就在考慮,要不要把這些代碼封裝到一個方法中去。但是即使把這一大段代碼扔到一個方法中去,在主函數裡調用這個方法,也不能保證以後不會修改這個方法了。是以為了自己和他人,還是有必要對比較長的代碼做一些處理。

一般即使是一個方法裡面的代碼,邏輯也是可以分成一小塊一小塊的,這個時候我們在這些邏輯中間加上空行,就能告訴别人,我這個代碼這裡,兩個空行中間的代碼關聯比較大。

看下面的代碼,在沒有添加任何注釋的情況下,因為有空行來分割邏輯,倒也不是一步就吓退想要看你代碼的人。

private void tsm_open_file_Click(object sender, EventArgs e)
{
    this.Text = "數字簽名工具 - 添加檔案中,請稍候...";
    if (recordList.Count > )
    {
        MessageBox.Show("最多支援20個檔案一次性簽名。");
        return;
    }

    OpenFileDialog openFileDialog = new OpenFileDialog();
    openFileDialog.Filter = "程式檔案|*.exe;*.dll|可執行檔案|*.exe|動态連結庫|*.dll";
    openFileDialog.RestoreDirectory = true;
    openFileDialog.FilterIndex = ;
    openFileDialog.Multiselect = true;

    if (openFileDialog.ShowDialog() == DialogResult.OK)
    {
        String[] fileNames = openFileDialog.FileNames;
        for (int i = ; i < fileNames.Length; i++)
        {
            String oldPath = fileNames[i];

            if (canAddFile(oldPath) == false)
            {
                MessageBox.Show(String.Format("檔案{0}不能添加,因為已經有同名檔案了。", oldPath));
                continue;
            }

            FileInfo fileInfo = new FileInfo(oldPath);

            Record record = new Record();
            record.FilePath = oldPath;
            record.AddTime = DateTime.Now;
            record.FileSize = fileInfo.Length;
            record.Progress = "0% 新添加";
            String md5 = MD5Util.getMD5(oldPath);
            if (md5 == null)
            {
                MessageBox.Show(String.Format("檔案{0}的MD5值計算失敗,請檢視檔案是否被其他程式占用,或稍後再試。", oldPath));
                continue;
            }
            record.MD5 = md5;

            recordList.Add(record);
            int index = this.dataGridView.Rows.Add();
            this.dataGridView.Rows[index].Cells[].Value = Path.GetFileName(record.FilePath);
            this.dataGridView.Rows[index].Cells[].ToolTipText = record.FilePath;
            this.dataGridView.Rows[index].Cells[].Value = record.AddTime.ToString();
            this.dataGridView.Rows[index].Cells[].Value = FileSizeUtil.getFileSizeWithUnit(record.FileSize);
            this.dataGridView.Rows[index].Cells[].Value = record.Progress;
            this.dataGridView.Rows[index].Cells[].Value = record.MD5;
            this.dataGridView.Rows[index].Cells[].Value = "";
        }
    }
    this.Text = "數字簽名工具";
}
           

使用注釋和花括号

在軟體開發的生命周期中,文檔應該是一直伴随着的。這樣,後面接手的人看文檔就知道當時發生了什麼。如果項目組有使用文檔來規範開發,那就要去遵守這個規定。但是文檔也有一個問題,就是代碼修改之後就要去修改文檔,萬一文檔沒有更新,接手的人反而會受到誤導。

文檔是個好習慣,在堅持更新項目文檔的同時,還要記得更新代碼的注釋,敲完代碼後随手加上的簡短的幾個字,會提高看代碼的效率好多倍。

當你焦頭爛額的猜測原來編碼的人是怎麼想的時候,看到下面添加了注釋的代碼,是不是有一種謝天謝地的感覺。

/// <summary>
/// 執行點選事件
/// </summary>
/// <param name="sender">控件</param>
/// <param name="e">事件</param>
private void tsm_open_file_Click(object sender, EventArgs e)
{
    //最大數量驗證
    this.Text = "數字簽名工具 - 添加檔案中,請稍候...";
    if (recordList.Count > )
    {
        MessageBox.Show("最多支援20個檔案一次性簽名。");
        return;
    }

    //彈出檔案選擇框
    OpenFileDialog openFileDialog = new OpenFileDialog();
    openFileDialog.Filter = "程式檔案|*.exe;*.dll|可執行檔案|*.exe|動态連結庫|*.dll";
    openFileDialog.RestoreDirectory = true;
    openFileDialog.FilterIndex = ;
    openFileDialog.Multiselect = true;

    //傳回選中的檔案
    if (openFileDialog.ShowDialog() == DialogResult.OK)
    {
        String[] fileNames = openFileDialog.FileNames;
        for (int i = ; i < fileNames.Length; i++)
        {
            //記錄檔案路徑
            String oldPath = fileNames[i];

            //檢視是否能添加
            if (canAddFile(oldPath) == false)
            {
                MessageBox.Show(String.Format("檔案{0}不能添加,因為已經有同名檔案了。", oldPath));
                continue;
            }

            //得到檔案資訊
            FileInfo fileInfo = new FileInfo(oldPath);

            //構造記錄對象
            Record record = new Record();
            record.FilePath = oldPath;
            record.AddTime = DateTime.Now;
            record.FileSize = fileInfo.Length;
            record.Progress = "0% 新添加";
            String md5 = MD5Util.getMD5(oldPath);
            if (md5 == null)
            {
                MessageBox.Show(String.Format("檔案{0}的MD5值計算失敗,請檢視檔案是否被其他程式占用,或稍後再試。", oldPath));
                continue;
            }
            record.MD5 = md5;

            //添加到清單,顯示到頁面上
            recordList.Add(record);
            int index = this.dataGridView.Rows.Add();
            this.dataGridView.Rows[index].Cells[].Value = Path.GetFileName(record.FilePath);
            this.dataGridView.Rows[index].Cells[].ToolTipText = record.FilePath;
            this.dataGridView.Rows[index].Cells[].Value = record.AddTime.ToString();
            this.dataGridView.Rows[index].Cells[].Value = FileSizeUtil.getFileSizeWithUnit(record.FileSize);
            this.dataGridView.Rows[index].Cells[].Value = record.Progress;
            this.dataGridView.Rows[index].Cells[].Value = record.MD5;
            this.dataGridView.Rows[index].Cells[].Value = "";
        }
    }
    this.Text = "數字簽名工具";
}
           

花括号{}在代碼中一般是有兩種形式:

  • 一種是Visual Studio中C++源碼編輯器預設的上下對齊式
int main()
{
    cout<<"我是C++"<<endl;
}
           
  • 一種是Eclipse中Java源碼編輯器預設的左花括号末尾排放式
public class HelloWorld { 
    public static void main(String args[]) { 
        System.out.println("我是Java"); 
    } 
}
           

C++預設方式,更容易看清代碼層次;Java預設方式減少占用的行數。

個人更加傾向于上下對齊式。但是個人意見需要服從團隊約定。你所在的團隊使用哪種方式,你就要使用哪種方式,和大家保持統一。

并且這兩種預設方式在內建開發環境IDE中都是可以調節的。比如Java的代碼,我平時這樣排版。

public class HelloWorld
{
    public static void main(String args[])
    {
        System.out.println("我是Java");
    }
}
           

不用的代碼和引用删除

我們寫代碼時,需要修改代碼時經常注釋之前的代碼,然後把自己的代碼加上去。但是又不确定自己的代碼100%正确,不敢删掉注釋的代碼,因為可能還會換為原來的代碼。

這樣導緻的後果是以後如果沒有看出注釋代碼的問題,反而覺得很有道理的話,真的會将你的代碼重新用注釋代碼換回來。

我們寫代碼要相信自己,該删的時候就要删掉。要學會使用SVN或者是Git來進行版本控制。即使目前版本删掉了,復原到之前版本依然能夠找回來。大可不必擔心真的會删掉了,這樣萬一有什麼變故,也還是能夠找回來的。

我們也會經常注意到編輯器行首有很多黃色的感歎号warning提示。雖然不影響程式正常運作,但是看着就是有點不雅觀,而且過多沒有使用的引用,或者外部包,架構,庫等等也會拖慢程式的運作速度。幹掉這些無用的東西既能淨化我們的心靈,還能減少不易察覺的隐患。

不要用中文拼音做變量名

現在C#和Java都支援中文變量名,類名。可以試着玩一玩,但是真的不要用到項目中,不隻是說中文,還有中文拼音。使用有意義的英文作為變量名更有利于溝通,和外國人溝通友善,和中國人溝通也友善。曾經看到有人設計資料庫,字段名全部使用中文拼音縮寫,令人費解,而且非常别扭,大概隻有自己能看懂吧。

英文變量名也不要用a,b,c,d作為變量名,使用有意義的單詞全稱一眼就知道這個變量,這個類是做什麼用的。大家都很忙,沒時間猜來猜去。

可用,清晰優雅,高效

具體到一個實際的功能,代碼是可用的,看起來清晰優雅的,運作起來高效的才是好代碼的标準。

  • 要做到這三點,首先要明确需求,考慮全面一點,從正确性,邊界值,反例三個角度去思考問題,定下詳細的需求,掌握需求方的意圖。
  • 其次,需要先做一個Demo,用于雙方進一步确認需求。沒有Demo,雙方都不是很确定對方有沒有get√到我的意思。有了Demo,絕大部分需求都可以确定下來了。一個粗糙的成品好過一個精美的半成品。不要過早優化,先把粗糙的成品做出來,後續慢慢優化。
  • 最後,具體到代碼,很多時候都需要調試代碼,不要一上來就斷點調試,先看一遍代碼,檢查代碼邏輯,理一理思路,然後采用二分法設定斷點輸出日志,快速定位問題代碼。優化時,确定一個優化的基準,優化之後有對比,用資料來告訴别人優化的效果。

多寫代碼,多思考

多寫代碼,多思考;多喝熱水,多鍛煉。

好的代碼是在一定代碼量的基礎上積累起來的,寫的時候要多加思考,不能不知道自己在幹什麼。

程式員長時間坐在椅子上,對脊椎傷害很大,脖子僵硬。建議多喝熱水,多活動。寫代碼一小時就要停下來休息一下,走一走,動一動。多鍛煉身體,身體是革命的本錢。

繼續閱讀