Unity 遊戲框架:命名的力量--變量

變量的命名入門

你們先來試着理解一下這段代碼:git

var todoList = new TodoList();
todoList.Todos = new List<Todo>();

var todo = new Todo() { Id = 0, Finished = false, Content = "測試" };

todoList.Todos.Add(todo)

todo.Finished = true;

代碼自己很簡單,就算不用去看 TodoList 類和 Todo 類的定義,也是能夠讀懂以上代碼的。github

那這是如何作到的呢?數組

答案就是:進行合適的命名。框架

而達到以上代碼的效果的主要是變量的命名。編輯器

由於以上出現的類都是 Model 類,而 Model 則是用來描述業務是什麼,而 Model 類中大部分代碼則是變量。
好比 這是一個 TodoList App (待辦事項),其中:工具

  • 有待辦事項列表
  • 待辦事項列表有待辦事項
  • 待辦事項能夠完成和未完成。
  • 待辦事項能夠編輯文本。

以上幾點通常是咱們接收到任務並理解業務以後梳理出來的。若是設計成代碼結構,結構大體以下:測試

  • 待辦事項列表
    • 待辦事項
      • 完成/未完成
      • 文本

很天然 Model 的代碼就寫出來了,代碼以下。編碼

TodoList.cs插件

public class TodoList
{
	public List<Todo> Todos;
}

Todo.csdebug

public class Todo
{
	public int Id;

	public bool Finished;

	public string Content;

}

爲了讓以上類更容易地在其餘文件中理解,筆者在命名上作了哪些工做呢?

TodoList 類中的 Todos 變量:

  • Todos 是複數,說明其類型多是數組、List 或者其餘的集合。
  • Todos 首字母大寫,說明訪問權限是 public 類型的。
  • Todos 名字自己是一個名詞,解釋成中文則是:要作的事(待辦事項),自己準確地傳達了變量的意思。

Todo 類

  • Id,和 Todos 同樣,傳達了訪問權限,和意思(標識),可是沒有傳達其類型。不過,無論是 int 仍是 string 都無所謂。
  • Finished,也是同樣的,public 權限、意思(完成了)。一樣也沒有傳達其類型,不過這裏能夠這樣理解,Finish 是動詞,加上 ed 則是過去式,有時態說明有狀態,這個狀態只有兩個,完成和未完成,因此是 bool 類型,這是筆者的一個習慣,固然也能夠命名爲 IsFinish,等等。
  • Content,中文意思是內容,也就是文本內容,通常爲 string 類型,由於首字母大寫,因此也是 public 權限。

簡單幾行代碼,就能夠傳達這麼多信息,因此 命名是一門藝術

小結

在對一個變量進行命名的時候,無非要思考如下三點:

  • 描述
  • 權限
  • 類型

權限和類型的表達很容易,由於關於這方面的方法論(套路)是固定的,能夠很容易掌握的。

比較考驗功底的是變量的描述,是須要長期進行訓練的。

描述、權限、類型

接下來以這三點爲主,分別進行方法論的介紹。

先從最簡單的來,最簡單的則是 權限 的表達

權限

權限指的是訪問權限,在 C# 中有 public、private、protected、internal 類型。

這裏在進行變量命名時分爲兩種。

  • 可外部訪問的 public 和 internal。
  • 和不可被外部訪問的 private 和 protected。

權限的表達,筆者本身的習慣是,可被外部訪問的變量採用首字母大寫。

好比:

public string Name;
internal static int ReferenceCount;

而不可被外部訪問的變量採用 m 前綴。

好比:

private string mShowedText;
protected int mMgrId;

這是筆者長期的一個習慣,也是筆者本身維護的 QFramework 的命名規範。

因此關於權限的表達很是簡單,依靠代碼規範就能搞定了,規範怎麼定就怎麼用。

這一點是最最最容易達到的。

若是各位尚未開始在乎命名這件事情,從權限開始上手是最容易的。

類型

變量是有類型的,最好呢是把類型可以表達出來。

類型的表達,固然這也能夠依照某些代碼規範來解決的。

好比匈牙利式的代碼規範:

private int m_nAge;   // n 表明數量
private string m_strName // str 表明 string

不過這種規範須要適應一段時間,這裏筆者不太推薦新手用這種規範解決類型表達問題。

而是採用一種比較簡潔、優雅的方式,來表達變量的類型。

好比:

public int Age;

Age 年齡,很容易想到是 int 類型。

public string Name;

Name 名字很容易想到是 string 類型。

public int PetCount;
public int PetNumber;

寵物數量,很容易想到是 int 類型。

public bool Completed;

Completed 完成了,是 bool 類型。

而這部分的詳細內容會在接下來的一個小節中詳細介紹。

描述

關於變量的描述的內容就比較多了,可是原則很簡單,就兩個字:準確。

爲變量命名時最重要的考慮事項是,該名字要徹底、準確地描述出該變量所表明的事物。——《代碼大全》

如何達到準確呢?這部分也會在接下來的一個小節中介紹。

在本小節,先給你們對變量所用的詞類型進行簡單的分類:

  • 事物
    • string
      • Name
      • NickName
    • int
      • Age
      • XXXCount
      • Times
  • 狀態
    • 過去式
      • Finished
    • 進行時
      • Waiting
    • 一些不推薦使用的(IsXXX):
      • IsFinished
      • IsFinish
      • IsWaiting
    • 形容詞
      • active
  • 其餘
    • C# 中特有的 委託、事件 等。
      • OnXXXFinished
      • OnBeforeDestroy
      • OnLoadDone
      • OnLoadStart

因此在以後詳細講述變量的描述表達部分會根據這三點來進行介紹。

小結

讀者讀到這裏,權限的表達是最容易作到的,若是沒有意識到的童鞋們,能夠在工做中開始權限的表達訓練了。

權限的表達比較適合做爲變量名訓練的的第一步。

關於權限部分的內容就到此完結了,下文中再也不贅述。

而剩下的類型和描述用兩個大章節進行詳細介紹。

咱們先搞定相對較容易的類型的表達,這樣好讓你們掌握並快速在工做中實踐。

類型的表達

關於集合(List、Array、Dictionary 等等)

List、Array 可使用名詞的複數來搞定。

好比:

var todos = new List<Todo>();
var todos = new Todo[]{};

也能夠將集合類型做爲後綴表達

var todoList = new List<Todo>();
var todoArray = new List<Todo>();

Dictionary

由於是 key-value 類型的集合,可使用 xxx4yyy方式命名(4 = for),這是筆者我的習慣,不強制。

var todo4Id = new Dictionary<string,Todo>();

也可使用類型做爲後綴。

var todoDict = new Dictionary<string,Todo>();

可是 key-value 類型使用 類型做爲後綴表達效果較差,因此推薦 xxx4yyy 方式。

其餘的集合類型,好比 Queue、Stack 等,也一樣能夠採用類型後綴的方式。

var panelStack = new Stack<UIPanel>();
var msgQueue = new Queue<Msg>();

Stack 和 Queue 是技術概念,因此通常會在框架/插件/工具層使用,在業務層使用得較少。

集合類型部分介紹到這裏。

數值/數據類型、string/char 等 (事物)

數值類型(int/flout/double):

int 類型常見的後綴詞(限定詞):

Number

var todoNumber = todos.Length;

Index

var todoIndex = todos.IndexOf(todo);

Count

var todoCount = todos.Count;

int 類型常見的前綴詞:

num

var numTodos = todos.Length;  // number of todos 縮寫,不太經常使用。

float/double 類型常見的後綴詞
Average、Sum 等。

var ageAverage = ageSum / peopleCount;

這種類型的後綴詞和前綴詞在計算時常常會用到。

這裏叫作計算限定詞。
下面列出經常使用的計算限定詞:

Count、Number、Num、Index、Total、Sum、Average、Max、Min、Record 等。

《代碼大全》建議,除了 Num 以外其餘的都建議放到後綴

還有一些數值類型的名字自己就表達了其類型。

age(int)、times(int) 等。

數據類型(string/char):

數據類型沒什麼好說的,只能儘可能選取名字自己就表達其類型的這種名字,而這部分的內容算是描述的表達部分,這裏先列出一部分:

username(string)、password(string)、name(string)、content(string)、title(string)、description(string)、id(int/string) 等。

bool、枚舉(狀態)

bool 類型:

  • 使用動詞 + 時態。
    • done
    • finished
    • completed
    • updating
    • enabled
  • 使用 Is + 名詞。
    • isEnemy
  • 形容詞
    • active

給 bool 類型取名的原則很簡單,只要表示其狀態只有兩種就好。
好比 GameObject 要麼爲 激活狀態 (active 爲 true) ,要麼爲 未激活狀態 (active 爲 false)。符合這樣的就是一個很好的 bool 變量名,不可能有第三個狀態的。

再好比,一個任務要麼完成(finished 爲 true),要麼爲未完成(finished 爲 false)。

枚舉

枚舉部分要分兩個部分講,一個是定義部分,一個是變量部分。
枚舉的定義:

// 事件
public enum UIMainPanelEvent
{
	// 事件監聽
	OnModelDataChanged,
	
	// 指令 (動賓短語、動詞)
	UpdateView
}

// 狀態 (與 bool 類型同樣)
public enum ResLoadState
{
	LoadBegan,
	Loading,
	LoadEnded,
}

// 結果 (名詞、形容詞)
public enum ResLoadResult
{
	Success,
	Fail,
}

定義部分和 bool 類型很像,好比 ModelDataChanged 就是 動詞 + 時態的方式。

Unity 特有的 GameObject、Transform、Button、Image 等

GameObject heroObj;
GameObject heroGameObj;
Transform  heroTrans;
Button btnEnterMainPanel;
Image logoImage;

以上爲常見的前綴、和後綴。

關於類型的表達介紹就到這裏。

小結

到這裏咱們對類型的表達進行了詳盡的介紹。
筆者關於類型表達的方法論也都所有介紹完了,你們能夠筆者的方法論爲準進行練習,在此基礎上進行不斷思考改進稱爲本身的方法論。

思考什麼呢?
思考如何讓別人(或本身)在別的文件中使用變量就能猜到其類型呢?
因此筆者介紹的方法論不是重點也不是權威,重點是不斷進行思考。

描述的表達

終於到了重頭戲了。
描述的表達是可以考驗一個開發者功底的工做。

對於 Model 類的變量命名。

  • 要想有一個好的描述,必須很是瞭解業務的。
  • 由於只有很是瞭解業務了,才能找到很是準確的描述。

就像本 Chat 的開頭的入門那樣:

  • 業務最起碼應該是梳理過一次的,梳理成本身能理解。
  • 梳理過一次以後要再進行一次結構化的梳理,這樣比較好轉化爲代碼。
  • 結構化梳理以後才能定義 Model 類和其變量。

以上對各位的要求會比較高,因此筆者這裏建議,你們熟練掌握了了權限和類型的表達後在進行描述的練習。

而在這以前,本 Chat 也只是介紹了 Model 的變量命名。
這是由於 Model 的變量定義是相對容易的。可是咱們的工做不僅有定義 Model,還有好多其餘的類須要咱們定義,而定義類多少要定義一些變量。而本 Chat 不能覆蓋全部的變量命名場景,因此會給出一些準則和練習步驟來給你們參考。

練習步驟一: 代碼部分所有爲英文。

在 Unity 中少數的須要顯示在編輯器上提供參數調整的變量能夠用一些中文漢字。而剩餘的最好是所有使用英文。
這裏最好是在編碼時隨手備着一個查詞軟件,能夠經過鍵盤快捷鍵快速查詢的。要養成這個習慣。到最好發現,在某一個領域或某種業務經常使用的詞彙就那些,本身都記住了,不多會再編碼時使用查詞軟件。

練習步驟二: 業務命名而不是技術命名

這個標題是筆者本身理解的,《代碼大全》的描述是變量名應該描述的是 what 而不是 how。也就是變量是什麼而不是怎麼作。
由於業務概念是現實的模擬,而技術概念只是手段。因此筆者理解爲爲了業務命名而不是爲技術命名。

要理解此準則很是簡單。摘抄《代碼大全》的一段話給你們理解:

一個好記的名字反映的一般都是問題,而不是解決方案。一個好名字一般表達的是「什麼」(what),而不是「如何」(how)。通常而言,若是一個名字反映了計算的某些方面而不是問題自己,那麼它反映的就是「how」而非「what」了。請避免選取這樣的名字,而應該在名字中反映出問題自己。

一條員工數據記錄能夠稱做 inputRecord 或者 employeeData。inputRecord 是一個反映輸入、記錄這些計算概念的計算機術語。employeeData 則指的是問題領域,與計算世界無關。與此相似,對一個用於表示打印狀態的位域來講,bitFlag 就要比 printerReady 更具計算機特徵。在財務軟件裏,calculateValue 的計算痕跡(how) 也要比 sum (what) 明顯。

書中原文解釋的很清楚了,再也不多說了。

練習步驟三:分清楚什麼時候用技術命名

這裏要說一點注意的,要分清楚在哪一個層。舉一個筆者框架中的 SerializeHelper (序列化器),序列化是技術概念,是「怎麼作?」 (how),可是它能夠作遊戲數據的存儲等操做。那麼它爲何不叫作 DataSaver/DataLoader 這些名字呢?

這是由於 SerializeHelper 這個類不在業務層,而是在框架層。框架自己提供的更多的是工具。

小結

練習步驟給出了 一、二、3,很容易上手,命名這件事自己比較容易掌握,可貴是初學者很是不在乎。老手呢通常趟坑躺多了天然就會意識到。而初學者再去趟一下這些坑有點浪費時間,不如一開始就意識到命名這件事的重要性。

到此呢,權限、類型、描述的練習步驟和原則(準則)都給了。接下來簡單聊聊,爲何要命名和如何更容易地落實命名這件事到工做中呢?

爲何要命名?

代碼的本質是信息,其承載着信息,這個信息能夠被編譯器理解,也要被人理解。

首先你,代碼要被編譯器理解,這是最基本的要求,也表明着開發者能和計算機溝通,讓計算機幫忙處理任務。

其次呢,是要被人理解。

這些人多是:

  • 本身(平常)
    • 與本身朝夕相處時間最長的就是這些代碼了,若是代碼很是容易讀懂而且整潔,天天的工做狀態都會不同。
    • 在 debug 時候,仍是要去讀代碼的,好的代碼是更容易被閱讀的,容易被閱讀 debug 所花費的時間就會減小。
    • 增長功能,也仍是同樣須要閱讀代碼的,以上同理。
    • 使本身對項目的理解更深入、清晰。
  • 同事(協做)
    • 一樣代碼被容易閱讀,同事的效率也有所提高,也會獲得同事的承認,
  • leader(晉升)
    • 不少團隊有代碼 review 的文化,好的代碼更容易得到上級和同事的承認。
    • 獲得同事和上級的承認,晉升就是很天然的事情了。
  • 來接手項目的人(離職)
    • 離職的時間也會被節省,不會被拖着問這是什麼那是什麼。
  • 全部開發者(開源)
    • 節省很是多人的時間,時間就是生命。
  • 讀者(教學,正在讀本 chat 的各位則是這個範圍的)

最終受益最多的仍是本身,而投入的只不過每一個變量多花費了幾秒的思考時間而已。

總之協做這個詞有一個協字,能夠理解成妥協的協,也能夠理解成協助的協。

給變量合適的命名既是一種妥協也是一種協助。

這就是爲何筆者單開一個 chat 來寫一個你們認爲如此簡單的事情。

如何落地變量的命名

單寫這一小節是但願你們不是隻讀一讀這篇 chat 就完事了,而是要把變量的命名這件事情落實到本身產出的代碼上去。

在工做中養成一個習慣的阻礙有不少。
最多見的緣由就是項目時間緊。

這個問題很好解決,只要訓練的時機根據實際狀況進行調整就行了。

對於初學者或者項目很是緊急的開發者,在第一遍寫邏輯的時候,變量能夠先隨便命名(按照本身的習慣),可是隻要當前的測試點驗證經過或者功能點完成,就應該回過頭把變量的名字好好想下,進行從新命名。通常 IDE 都帶重構功能,只要改一個地方,其餘代碼部分會所有跟着更改。

這樣作的目的是爲了防止同一時間作兩件事情。

  • 邏輯編寫
  • 變量命名

對於命名新手來講,同一時間作兩件事情會很吃力。
自己邏輯編寫就很吃力了,再加上須要思考的變量命名,會更加吃力。
因此對於命名新手要求同一時間只思考一件事情。

對於時間很是緊急的開發者,若是進行命名的思考會影響項目的進度,那仍是等項目不急的時候再落實就行了。

只要能作到,在進行邏輯編寫時,只考慮如何完成或者如何實現就行了。
在變量命名時,只專一於如何取個合適的名字,只考慮變量的描述、類型、權限就好。
以下:

  • 變量的命名是否準確描述?
  • 變量的命名是否表達了類型?
  • 變量的命名是否表示了權限?

這樣堅持一段時間後,就能作到同一時間就能夠作兩件事情。

初學者們只要記住一點就夠了:

  • 合適的命名能夠不在建立變量的時候完成。

可是最終目標仍是將進行合適的命名這件事情養成習慣,在建立變量的同時就已經爲變量取了一個很是合適的名字。

最後,很是感謝 QFramework 的 邊上海 邊前輩對此專欄的勘誤和提供的一些很是有價值的建議。

更多內容

相關文章
相關標籤/搜索