<pre id="qonpc"><legend id="qonpc"></legend></pre><em id="qonpc"></em>

      国产精品熟女久久久久浪_国产一区在线观看成人免费_久久久国产一区二区_√禁漫天堂资源中文www_中文字幕av成人在线电影_一级片'在线观看视频_久久人人爽人人片av_www.熟女人妻精品国产

      起名字的軟件與起名字生辰八字查詢

      2025-02-10 12:42:09
      八字起名網(wǎng) > 八字起名 > 起名字的軟件與起名字生辰八字查詢

      本篇文章給大家談?wù)勂鹈值能浖?,以及起名字生辰八字查詢的知識(shí)點(diǎn),希望對(duì)各位有所幫助,不要忘了收藏本站喔。

      文章詳情介紹:

      程序員“頭痛”起名根治指南

      作者:marinewu,騰訊PCG客戶端開發(fā)工程師

      | 導(dǎo)語(yǔ)基于 Readability 的出題閱卷經(jīng)驗(yàn)的一些不完全的具體的命名指南。

      There are only two hard things in Computer Science: cache invalidation and naming things.

      -- Phil Karlton


      軟件開發(fā)中一個(gè)著名的反直覺就是“起名兒”這個(gè)看上去很平凡的任務(wù)實(shí)際上很有難度。身邊統(tǒng)計(jì)學(xué)顯示,越是有經(jīng)驗(yàn)的程序員,越為起名頭痛。給小孩起名兒都沒(méi)這么費(fèi)勁,對(duì)吧,王浩然?

      命名的困難可能來(lái)自于以下幾個(gè)方面:

      信息壓縮:命名的本質(zhì)是把類/方法的信息提煉成一個(gè)或幾個(gè)詞匯,這本身需要對(duì)抽象模型的準(zhǔn)確理解和概括。

      預(yù)測(cè)未來(lái):類/方法的職責(zé)可能會(huì)在未來(lái)有變化,現(xiàn)在起的名字需要考慮未來(lái)可能的變動(dòng)。

      語(yǔ)言能力:缺少正確的語(yǔ)法知識(shí),或是缺少足夠的詞匯量。本來(lái)英文就不是大部分中國(guó)人的母語(yǔ),更甚者,計(jì)算機(jī)的詞匯表不同于日常交流詞匯表,有大量黑話。

      不良設(shè)計(jì):混亂的職責(zé)分布、不清晰的抽象分層、錯(cuò)誤的實(shí)現(xiàn),都會(huì)導(dǎo)致無(wú)法起出好的名字。在這個(gè)意義上,起名字其實(shí)是對(duì)設(shè)計(jì)的測(cè)試: 如果起不出名字來(lái),很可能是設(shè)計(jì)沒(méi)做好 -- 重新想想設(shè)計(jì)吧。

      命名就像寫作,會(huì)寫字不等于會(huì)寫作。而且,命名更多像是一門藝術(shù)[注](此處藝術(shù)的含義取自于 Knuth -- 命名會(huì)訴諸品味和個(gè)人判斷。),不存在一個(gè)可復(fù)制的命名操作手冊(cè)。

      本文描述一些實(shí)用主義的、可操作的、基于經(jīng)驗(yàn)的命名指南,并提供了一個(gè)代碼詞匯表,和部分近義詞辨析。本文沒(méi)有涉及討論名字的形而上學(xué),例如如何做更好的設(shè)計(jì)和抽象以利于命名,也沒(méi)有涉及如何劃分對(duì)象等,也無(wú)意討論分析哲學(xué)。

      命名原則

      命名是一門平衡準(zhǔn)確性和簡(jiǎn)潔性的藝術(shù) -- 名字應(yīng)該包含足夠的信息能夠表達(dá)完整的含義,又應(yīng)該不包含冗余的信息。

      準(zhǔn)確 Precision

      名字最重要的屬性是準(zhǔn)確。名字應(yīng)該告訴用戶這個(gè)對(duì)象/方法的意圖 -- “它是什么” 和 “它能做什么”。 事實(shí)上,它是體現(xiàn)意圖的第一媒介 -- 名字無(wú)法表現(xiàn)含義時(shí)讀者才會(huì)閱讀文檔。

      名字應(yīng)該是有信息量的、無(wú)歧義的。以下一些策略可以增加名字的準(zhǔn)確度:

      可讀

      最基本的語(yǔ)法原理,是一個(gè)類(Class/Record/Struct/... 隨你喜歡)應(yīng)該是一個(gè)名詞,作為主語(yǔ)。一個(gè)方法應(yīng)該是動(dòng)詞,作為謂語(yǔ)。 換言之,類“是什么”,方法“做什么”, 它們應(yīng)該是可讀的,應(yīng)該是 [Object] [Does ...] 式的句子。

      可讀是字面意思,意味著它應(yīng)該是通順的,所以應(yīng)該:

      避免 API 中使用縮寫

      就像是給老板的匯報(bào)中不會(huì)把商業(yè)計(jì)劃寫成 Busi Plan 一樣,也不應(yīng)該在公開 API 中使用一些奇怪的縮寫。現(xiàn)在已經(jīng)不是 1970 年了,沒(méi)有一個(gè)方法不能超過(guò) 8 個(gè)字符的限制。把類/方法的名字寫全,對(duì)讀者好一點(diǎn),可以降低自己被同事打一頓的風(fēng)險(xiǎn)。

      creat 是個(gè)錯(cuò)誤,是個(gè)錯(cuò)誤,是個(gè)錯(cuò)誤!

      但是,首字母縮略詞的術(shù)語(yǔ)是可行并且推薦的,如 Http, Id, Url。

      以下是可用的、得到普遍認(rèn)可的縮寫:

      configuration -> config

      identifier -> id

      specification -> spec

      statistics -> stats

      database -> db (only common in Go)

      regular expression -> re/regex/regexp

      未得到普遍認(rèn)可的縮寫:

      request -> req

      response -> resp/rsp

      service -> svr

      object -> obj

      metadata -> meta

      business -> busi

      req/resp/svr 在服務(wù)名稱中很常見。這非常糟糕。請(qǐng)使用全稱。

      再次說(shuō)明:以上的說(shuō)明是針對(duì) API 名稱,具體包括公開對(duì)象/函數(shù)名字、RPC/Web API 名字。在局部變量使用縮寫不受此影響。

      避免雙關(guān)

      對(duì)類/方法的命名,不要使用 2 表示 To, 4 表示 For。

      func foo2Bar(f *Foo) *Bar // BAD func fooToBar(f *Foo) *Bar // GOOD func to(f *Foo) *Bar // Good if not ambiguous.

      2/4 這種一般只有在大小寫不敏感的場(chǎng)合才會(huì)使用,例如包名 e2e 比 endtoend 更可讀。能區(qū)分大小寫的場(chǎng)合,不要使用 2/4。

      合乎語(yǔ)法

      雖然不能完全符合語(yǔ)法(例如通常會(huì)省略冠詞),但是,方法的命名應(yīng)該盡量符合語(yǔ)法。例如:

      class Car { void tireReplace(Tire tire); // BAD, reads like "Car's tire replaces" void replaceTire(Tire tire); // GOOD, reads like "replace car's tire" }

      關(guān)于命名的語(yǔ)法見“語(yǔ)法規(guī)則”一章。

      使用單一的概念命名

      命名本質(zhì)上是分類(taxonomy)。即,選擇一個(gè)單一的分類,能夠包含類的全部信息,作為名字。

      考慮以下的角度:

      例如,把大象裝進(jìn)冰箱,需要有三步 -- 打冰箱門打開,把大象放進(jìn)去,把冰箱門關(guān)上。但是,這可以用單一的概念來(lái)描述:“放置”。

      class Fridge { public void openDoorAndMoveObjectIntoFridgeAndCloseDoor(Elephant elphant); // BAD public void put(Elephant elphant); // GOOD }應(yīng)該使用所允許的最細(xì)粒度的分類

      避免使用過(guò)于寬泛的類別。例如,這世界上所有的對(duì)象都是“對(duì)象”,但顯然,應(yīng)該使用能夠完整描述對(duì)象的、最細(xì)顆粒度的類別。

      class Fridge { public put(Elephant elephant); // GOOD. public dealWith(Elephant elephant); // BAD: deal with? Anything can be dealt with. How? }

      簡(jiǎn)而言之,名字應(yīng)該是包含所有概念的分類的下確界。

      簡(jiǎn)潔 Simplicity

      名字長(zhǎng)通常會(huì)包含更多信息,可以更準(zhǔn)確地表意。但是,過(guò)長(zhǎng)的名字會(huì)影響可讀性。例如,“王浩然”是一個(gè)比“浩然·達(dá)拉崩吧斑得貝迪卜多比魯翁·米婭莫拉蘇娜丹尼謝莉紅·迪菲特(defeat)·昆圖庫(kù)塔卡提考特蘇瓦西拉松·蒙達(dá)魯克硫斯伯古比奇巴勒·王”可能更好的名字。(來(lái)自于達(dá)啦崩吧)

      在此,我提出一個(gè)可能會(huì)有爭(zhēng)議的觀點(diǎn):所有的編程語(yǔ)言的命名風(fēng)格應(yīng)該是趨同的。不同于通常認(rèn)為 Java 的命名會(huì)傾向于詳盡,Go 的命名會(huì)傾向于精簡(jiǎn),所有的語(yǔ)言對(duì)具體的“名字到底有多長(zhǎng)”的建議應(yīng)該是幾乎一樣的 -- 對(duì)外可見應(yīng)該更詳細(xì),內(nèi)部成員應(yīng)該更精簡(jiǎn)。具體地:

      public,如 public 類的名字、public 方法的名字 - 應(yīng)該詳細(xì)、不使用縮寫、減少依賴上下文。通常是完整名詞短語(yǔ)。

      non-public,如類成員、私有方法 - 不使用縮寫、可以省略上下文。下界是單詞,不應(yīng)該使用單字符。

      local,如函數(shù)的局部變量 - 基本上是風(fēng)格是自由的。不影響可讀性的前提下,例如函數(shù)方法長(zhǎng)度很短,可以使用單字符指代成員。

      上述規(guī)則像是 Go 的風(fēng)格指南。但是,并沒(méi)有規(guī)定 Java 不能這樣做。事實(shí)上,Java 的冗長(zhǎng)是 Java 程序員的自我束縛。即使在 Java 的代碼里,也可以這樣寫:

      public class BazelRuntime { public boolean exec(Command cmd) { String m = cmd.mainCommand(); // YES, you can use single-letter variables in Java. // ... } }

      同樣,在 Go 的代碼中也不應(yīng)該出現(xiàn)大量的無(wú)意義的縮寫,尤其是導(dǎo)出的結(jié)構(gòu)體和方法。

      type struct Runtime {} // package name is bazel, so bazel prefix is unnecessary type struct Rtm {} // BAD. DO NOT INVENT ABBREVIATION!

      當(dāng)然,由于語(yǔ)言特性,在命名風(fēng)格上可能會(huì)有差異。例如,由于 Go 的導(dǎo)入結(jié)構(gòu)體都需要加包前綴,所以結(jié)構(gòu)名中通常不會(huì)重復(fù)包前綴;但 C++/Java 通常不會(huì)依賴包名。但是,上述的原則仍然是成立的 -- 可見度越高,應(yīng)該越少依賴上下文,并且命名越詳盡。

      Google Go Style Guide 是唯一詳盡討論命名長(zhǎng)度的風(fēng)格指南,非常值得參考,并且不限于 Go 編程: https://google.github.io/styleguide/go/decisions#variable-names

      一致 Consistency

      另一個(gè)容易被忽略的命名的黃金原則是一致性。換言之,名字的選取,在項(xiàng)目中應(yīng)該保持一致。遵守代碼規(guī)范,避免這方面的主觀能動(dòng)性,方便別人閱讀代碼。通常情況下,一個(gè)差的、但是達(dá)成共識(shí)的代碼規(guī)范,也會(huì)遠(yuǎn)好于幾個(gè)好的、但是被未達(dá)成共識(shí)的規(guī)范。

      這個(gè)圖我能用到下輩子: [xkcd 927]()

      但是僅符合代碼規(guī)范是不夠的。如同所有的語(yǔ)言,同一個(gè)概念,有多個(gè)正確的寫法。

      考慮以下的例子:

      message Record { int32 start_time_millis = 1; // OK int32 commited_at = 2; // Wait. Why not commit_time? Anything special? int32 update_time = 3; // What unit? Also millis? google.types.Timestamp end_time = 4; // WTF? Why only end_time is typed? }

      幾種都是合理的(雖然不帶單位值得商榷)。但是,如果在一個(gè)代碼中出現(xiàn)了多種風(fēng)格,使用起來(lái)很難預(yù)測(cè)。您也不想使用這樣的 API 吧?

      所以,在修改代碼的時(shí)候,應(yīng)該查看上下文,選擇已有的處理方案。一致性大于其它要求,即使舊有的方案不是最好的,在做局部修改時(shí),也應(yīng)該保持一致。

      另一個(gè)可考慮的建議是項(xiàng)目的技術(shù)負(fù)責(zé)人應(yīng)該為項(xiàng)目準(zhǔn)備項(xiàng)目的專有詞匯表。

      語(yǔ)法規(guī)則類/類型

      類應(yīng)該是名詞形式,通常由單個(gè)名詞或名詞短語(yǔ)組成。其中,主要名詞會(huì)作為名詞短語(yǔ)的末尾。例如 Thread, PriorityQueue, MergeRequestRepository。

      名詞短語(yǔ)通常不使用所有格。如,并非 ServiceOfBook,也不是 BooksService (省略 '),而是 BookService。

      接口

      接口的命名規(guī)則和類相同。除此之外,當(dāng)接口表示可行動(dòng)類型時(shí),可使用另一個(gè)語(yǔ)法,即 Verb-able。例如:

      public interface Serializable { byte[] serialize(); } public interface Copyable { T copy(); } public interface Closable { void close(); }

      (Go 通常不使用這個(gè)命令風(fēng)格。只在 Java/C++ 中使用。)

      輔助類

      只在 Java(注1)中使用。一個(gè)類或概念所有的輔助方法應(yīng)該聚合在同一個(gè)輔助類。這個(gè)類應(yīng)該以被輔助類的復(fù)數(shù)形式出現(xiàn)。不推薦使用 Helper/Utils 后綴表示輔助類。尤其不推薦使用 Utils/Helpers 做類名,把所有的輔助方法包進(jìn)去。如:

      class Collections {} // For Collection class Strings {} // For String class BaseRuleClasses {} // For BaseRuleClass class StringUtils {} // WORSE! class StringHelper {} // WORSE!

      注1: 客觀來(lái)說(shuō),這適用于所有強(qiáng)制 OOP 的語(yǔ)言(所有強(qiáng)制把方法放在類里的語(yǔ)言)。但是除了 Java, 沒(méi)有別的語(yǔ)言這么煩啦。

      方法

      方法通常是謂語(yǔ)(動(dòng)詞),或是 謂賓(動(dòng)詞+名詞) 結(jié)構(gòu)。注意以上語(yǔ)法中,動(dòng)詞都在最前端。例如:

      class Expander { String expand(String attribute); // 主-謂 String expandAndTokenizeList(String attribute, List values); // 主-謂-賓 }

      除此之外,有以下特例值得注意:

      訪問(wèn)器 Getter

      直接使用所 Get 的對(duì)象的名詞形式,即 Foo()。不要使用 GetFoo()。

      Java: 所有的 Getter 都需要一個(gè) get 前綴是來(lái)自于過(guò)時(shí)的 Java Beans Specification,以及 Javaer 的思想鋼印。

      func Counts() int; // GOOD func GetCounts() int; // BAD: UNNECESSARY. 斷言 Predicate

      斷言函數(shù)指返回結(jié)果是布爾型(即真?zhèn)沃担┑暮瘮?shù)。它們通常有以下命名格式:

      系動(dòng)詞: 主-系-表

      即 isAdjective() 或 areAdjective() 格式,表示是否具有某個(gè)二元屬性。類似于 Getter,可以省略系語(yǔ),只使用表語(yǔ),即: adjective()。

      func IsDone() bool {} // OK-ish. But could be better. func Done() bool {} // GOOD. Why bother with is/are? func CheckEnabled() bool { // BAD. Nobody cares if it is "checked". Just tell the user if it is enabled. return enabled; } func Enabled() bool {} // GOOD. 情態(tài)動(dòng)詞: 主-助謂-謂-(賓/表)

      情態(tài)動(dòng)詞也是常見的斷言形式。常見的是以下三個(gè):

      should: 查詢當(dāng)前是否應(yīng)該執(zhí)行給定的實(shí)義動(dòng)詞。

      can: 查詢當(dāng)前類所在狀態(tài)是否可以執(zhí)行給定的實(shí)義動(dòng)詞。某些情況下,也可以使用第三人稱單數(shù)作為更簡(jiǎn)潔的代替。

      must: 特殊形式。不同于前兩者,會(huì)執(zhí)行給定的實(shí)義動(dòng)詞。must 表示執(zhí)行必須成功,否則會(huì)拋出不可恢復(fù)錯(cuò)誤 (throw/panic)。類似于 C++ 中常見的 OrDie 后綴。

      func Compile(s string) Regexp, error // Returns error upon failure func MustCompile(s string) Regexp // Panics upon failure func (r Regexp) CanExpand(s string) bool // Whether s is legal and can be expanded func (r Regexp) Expands(s string) bool // Whether r expands s, i.e. r can expand s. func (r Regexp) ShouldReset() bool // Whether the state requires reset. Does not perform de-facto reset. func (r Regexp) Reset() // De-facto reset.表嘗試: 主-maybe/try-謂-(賓/表)

      上文 "must" 的反面,表示嘗試性的執(zhí)行,并且失敗不會(huì)造成嚴(yán)重后果:

      maybe 前綴用以表示指定的行為有前置條件,也在方法中執(zhí)行。如果前置條件不滿足,不會(huì)執(zhí)行指定行為。通常不會(huì)出現(xiàn)在公開 API。

      try 通常用于 Try-Parse Pattern,用于避免拋出異常。

      void maybeExecute() { if (!predicate()) { return; } // execute } std::unique_ptr ParseOrDie(std::string_view dateTime); bool TryParse(string_view dateTime, DateTime* dateTime);第三人稱單數(shù)

      另一個(gè)常見場(chǎng)景是我們希望表示類擁有某些屬性,但是使用助動(dòng)詞并不合適。如果前文描述,常見的選擇是使用第三人稱單數(shù)的靜態(tài)動(dòng)詞(Stative verb)(注1) 表示類滿足給定斷言。

      func (l *List) Contains(e interface{}) bool func (r Regexp) Expands(s string) bool

      注1: 簡(jiǎn)單地說(shuō),靜態(tài)動(dòng)詞是表示狀態(tài)的動(dòng)詞,與動(dòng)態(tài)動(dòng)詞(Dynamic verb)表示動(dòng)作對(duì)應(yīng)。或言“持續(xù)性動(dòng)詞”。

      一階邏輯 First-order logic, Predicate Logic

      一階邏輯量詞也是常見的前綴:

      all 表示所有對(duì)象滿足給定要求

      any 表示任意對(duì)象滿足給定要求

      none 表示沒(méi)有任何對(duì)象滿足給定要求

      語(yǔ)法: <一階量詞><動(dòng)詞|形容詞>

      class Stream { // Returns whether all elements of this stream match the provided predicate. boolean allMatch(Predicate p); // Returns whether any elements of this stream match the provided predicate. boolean anyMatch(Predicate p); // Returns whether no elements of this stream match the provided predicate. boolean noneMatch(Predicate predicate) }介詞

      介詞經(jīng)常與某些動(dòng)詞固定搭配,因此,通??梢允÷詣?dòng)詞,而只使用介詞作為方法名稱。

      to: 轉(zhuǎn)換至另一對(duì)象,等價(jià)于 convertTo。to 會(huì)產(chǎn)生一個(gè)全新的對(duì)象,通常不持有對(duì)原對(duì)象的引用。

      as: 返回某個(gè)視圖,等價(jià)于 returnViewAs。一個(gè)“視圖(View)” 通常是對(duì)原有對(duì)象的另一角度的抽象,通常會(huì)持有對(duì)原有數(shù)據(jù)的引用,而不會(huì)產(chǎn)生新的數(shù)據(jù)。

      of/from/with:構(gòu)造新對(duì)象,等價(jià)于 createOutOf/createFrom/createWith。見下文“工廠模式”。

      on: 監(jiān)聽事件,等價(jià)于 actUpon。見下文“事件”。

      class Foo { public List toList(); // Convert to (Construct a new instance of) a new List. Creates a new list. public List asList(); // Return a List as a different **view**. Holds reference of the original reference. static Foo of(); // Construct Foo as a factory method. static Foo from(Bar); // Construct Foo from Bar. Foo with(Bar); // Construct a new Foo by replacing Bar with new Bar. void onClick(ClickEvent e); // Act upon click event. }


      參考資料:

      https://testing.googleblog.com/2017/10/code-health-identifiernamingpostforworl.html

      https://journal.stuffwithstuff.com/2016/06/16/long-names-are-long/

      https://journal.stuffwithstuff.com/2009/06/05/naming-things-in-code/

      https://habr.com/en/post/567870/#names_in_engineering

      https://medium.com/wix-engineering/naming-convention-8-basic-rules-for-any-piece-of-code-c4c5f65b0c09

      https://github.com/kettanaito/naming-cheatsheet

      [[Effective Java]] Item 68: Adhere to generally accepted naming conventions


      詞匯表

      下文按用途歸類了常見動(dòng)詞和名詞,并對(duì)同義近義詞進(jìn)行了辨析。

      類/名詞類繼承

      Abstract/Base
      Impl
      Default

      Java

      Interface: 通常不需要額外的表示。不要加 I 前綴,或后綴 FooInterface。

      Abstract class: 通常會(huì)添加 Abstract/Base 前綴以明確屬性。這是因?yàn)?Interface/Impl 是常見的,Class 也是常見的,但是基于繼承的抽象類是特殊的、應(yīng)該予以避免的,應(yīng)該給予特殊標(biāo)記。

      Implementation:

      如果不實(shí)現(xiàn)接口,通常不需要任何特殊修飾符。

      如果以 "is-a" 的方式實(shí)現(xiàn)了某個(gè)接口,那么通常實(shí)現(xiàn)會(huì)以 {InterfaceName}Impl 的方式命名。

      如果一個(gè)類實(shí)現(xiàn)了多個(gè)接口,那么通常這個(gè)類應(yīng)該是以作為主要目標(biāo)的接口為基礎(chǔ)命名。例如 class BazelBuilderImpl implements BazelBuilder, AutoClosable, Serializable。

      如果一個(gè)接口有多個(gè)實(shí)現(xiàn),通常會(huì)基于它們本身的實(shí)現(xiàn)特點(diǎn)命名,并且使用 Impl 后綴。Default 通常用來(lái)命名默認(rèn)的實(shí)現(xiàn),即其它實(shí)現(xiàn)如果不存在會(huì) fallback 到的實(shí)現(xiàn)。如果所有的實(shí)現(xiàn)都是平等地位,那么不要使用 Default 命名。

      // https://github.com/bazelbuild/bazel with some fake examples public interface SkyFunction {} public abstract class AbstractFileChainUniquenessFunction implements SkyFunction {} public class DefaultSkyFunction implements SkyFunction {} public class BazelModuleInspectorFunction implements SkyFunction {} public interface VisibilityProvider {} public final class VisibilityProviderImpl {}C++

      C++ 的 interface 是通過(guò)抽象類不存在基類成員變量模擬。通常接口所有的成員函數(shù)都是公開純虛函數(shù)。

      使用 Impl 表示實(shí)現(xiàn)。

      Abstract class: 通常會(huì)添加 Base 后綴以明確屬性。這是因?yàn)?Interface/Impl 是常見的,Class 也是常見的,但是基于繼承的抽象類是特殊的、應(yīng)該予以避免的,應(yīng)該給予特殊標(biāo)記。

      // levelDB // includes/db.h class DB { public: virtual ~DB(); // MUST! virtual Status Delete(const WriteOptions&, const Slice&) = 0; } // db/db_impl.h class DBImpl : public DB {} // rocksDB // Base class class CacheShardBase {}Go

      Go 的 interface 從來(lái)不是用來(lái)做 "is-a" 定義的。Go 的 interface 契約通過(guò) duck typing 滿足。interface 應(yīng)該在消費(fèi)方定義,而非提供方。因此, interface Foo/struct FooImpl 不應(yīng)該出現(xiàn)

      Go 也并沒(méi)有抽象類,雖然可以將一個(gè)結(jié)構(gòu)體嵌入到另一個(gè)結(jié)構(gòu)體中。所以 Base/Abstract 也極少出現(xiàn)。

      原則上,Go 的類關(guān)系更為簡(jiǎn)化,命名更強(qiáng)調(diào)意義優(yōu)先,因此在命名時(shí)避免使用修飾性前后綴。

      異常

      Exception/Error

      Java

      所有的異常擴(kuò)展應(yīng)該以 Exception 為后綴。所有的錯(cuò)誤應(yīng)該以 Error 為后綴。 對(duì)異常和錯(cuò)誤的區(qū)別請(qǐng)參見 https://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html

      public class IllegalArgumentException; public class OutOfMemoryError;C++

      C++ 的 exception 通常指語(yǔ)法特性,與 throw 對(duì)應(yīng),而 error 可以用來(lái)表示具體的異常錯(cuò)誤。

      // stdlib std::exception; std::runtime_errorGo

      所有的錯(cuò)誤都是 error。因此,所有自定義的對(duì) error 的擴(kuò)展都以 Error 作為后綴。

      os.PathError測(cè)試

      Test

      Java/Go/C++ 均使用 Test 作為測(cè)試類的后綴。

      模塊

      Module/Component

      Module/Component 通常會(huì)在框架中使用。不同的語(yǔ)言/框架對(duì)于 Module/Component 有不同的定義。 在非框架代碼中應(yīng)該減少使用 Module/Componenet 等命名,因?yàn)榭赡芘c已有框架沖突,并且 Module/Componenet 過(guò)于寬泛而缺少實(shí)質(zhì)意義。

      Module/Component 是意義相近的詞,都可以表示“模塊”或者“組件”。兩者雖然有細(xì)微的分別,但是框架通常都顯式(即在文檔中指定,或者通過(guò)框架語(yǔ)義約束)地把它們定義為框架語(yǔ)境下的某些結(jié)構(gòu)層級(jí)。

      總結(jié),Module/Component 命名應(yīng)該注意:

      只應(yīng)該在框架代碼中使用。

      Module/Component 應(yīng)該在框架的語(yǔ)境中給出確切的定義。

      服務(wù)

      Service

      Service 通常用于作為 C-S 架構(gòu)下的服務(wù)提供者的名稱的后綴,如:

      HelloService

      但除此之外,Service 可以表示任何長(zhǎng)期存活的、提供功能的組件。例如:

      BackgroundService // Android 后臺(tái)服務(wù) ExecutorService // 線程池執(zhí)行服務(wù),也是服務(wù)

      BAD: 不要使用 Svr 縮寫。使用全稱。

      容器

      Holder/Container/Wrapper

      Holder/Container/Wrapper 都表示“容器”,具有同一個(gè)意圖:為一個(gè)類增加額外的數(shù)據(jù)/功能,例如:

      添加某些語(yǔ)境下的元數(shù)據(jù)(Decorator 模式)

      做適配以在另一個(gè)環(huán)境中使用(Adapter 模式)

      通常的結(jié)構(gòu)如下:

      class ObjectHolder { private final Object object; // other stuff ... public Object object() {} // Other methods }

      這三個(gè)詞沒(méi)有區(qū)別。在同一個(gè)項(xiàng)目中,應(yīng)該保持一致。

      控制類

      Manager/Controller

      Manager 和 Controller 是同義詞。它們通常用來(lái)表示專門控制某些類的類。

      這兩個(gè)詞有以下幾個(gè)常見場(chǎng)景:

      Manager 管理資源,如 DownloadManager, PackageManager。

      Manager 通常特指管理對(duì)象的生命周期,從創(chuàng)建到銷毀。

      Controller 通常在某些架構(gòu)中,尤其是 MVC (Model-View-Controller)。

      即使如此,Manager/Controller 是無(wú)意義詞匯,出現(xiàn)時(shí)充滿了可疑的味道 -- 類應(yīng)該管理它們自己。 Controller/Manager 多了一層抽象,而這很可能是多余的。 認(rèn)真考慮是否需要 Manager/Controller。

      輔助類

      Util/Utility/Utils/Helper/{ClassName}s

      輔助類是強(qiáng)制 OOP 的語(yǔ)言(i.e. Java) 所需要的特殊類。通常它們是一些輔助方法的合集。

      Java

      將與某個(gè)類型相關(guān)的輔助方法放在一個(gè)類中,并且以復(fù)數(shù)形式命名輔助類。如:

      // Java std lib public final class Strings {} public final class Lists {} public final class Collections {}

      避免使用 Util/Utility/Utils/Helper。它們是無(wú)意義詞匯。

      C++

      使用全局方法。如果擔(dān)心命名污染,將之置入更細(xì)粒度的 namespace。

      Go

      使用全局方法。

      函數(shù)式

      Function/Predicate/Callback

      Function 通常表示任意函數(shù)。 Predicate 表示命題,即通常返回類型為 bool。 Callback 指回調(diào)函數(shù),指將函數(shù)作為參數(shù)傳遞到其它代碼的某段代碼的引用。換言之, Function 可以作為 Callback 使用。因此,Callback 在現(xiàn)代函數(shù)式編程概念流行后,通常很少使用。

      Java

      熟悉 Java 8 開始提供的函數(shù)式語(yǔ)義。如果可以使用標(biāo)準(zhǔn)庫(kù)的語(yǔ)義,不要自己創(chuàng)建名詞。 注意 Function 指單入?yún)ⅰ纬鰠⒌暮瘮?shù)。如果是多入?yún)⒌暮瘮?shù),直接定義 FunctionalInterface 并且按用途命名,例如 OnClickListener.listen(Context, ClickEvent)。

      // java.util.function Predicate // f(T) -> bool Function // f(T) -> R Consumer // f(T) -> void Supplier // f() -> TC++

      first-class 函數(shù)的標(biāo)準(zhǔn)類型為 std::function。

      C++ 表示命名函數(shù)對(duì)象的慣用法是 fun。Stdlib 中會(huì)縮寫 function 為 fun,如 pmem_fun_ref,因此與 stdlib 一致,在代碼中不要使用 fn 或是 func 。

      Go

      Go 通常使用 Func 或是 Fn 表示函數(shù)類型。

      type ProviderFunc func(config ConfigSource, source PassPhraseSource) (Provider, error) type cancelFn func(context.Context) error

      在同一個(gè)項(xiàng)目中,應(yīng)該保持一致。

      作為參數(shù)時(shí),函數(shù)不會(huì)特意標(biāo)明 Fn,而是遵從普通的參數(shù)命名方式:

      func Sort(less func(a, b string) int)

      換言之,函數(shù)是一等公民。

      設(shè)計(jì)模式類

      類/方法通常都按它們的行為模式來(lái)命名。恰好,設(shè)計(jì)模式就歸類抽象了很多行為模式。所以設(shè)計(jì)模式提供了很多好的名字。

      創(chuàng)建式

      Factory: 工廠模式。通常,使用工廠方法即可,不需要一個(gè)額外的工廠類。只有當(dāng)工廠特別復(fù)雜,或者工廠有狀態(tài)時(shí)再考慮使用工廠類。

      Builder:構(gòu)建者模式。一般來(lái)說(shuō) Builder 都是作為 inner class,如

      class Foo { static class FooBuilder {} }行為式Adapter: 適配器

      在 GoF 中 Adapter 本來(lái)是將一個(gè)類封裝以可以被作為另一個(gè)類型被調(diào)用,這樣調(diào)用方不需要額外改變代碼。這種用途通常被內(nèi)化到容器上,見上文[容器類]部分。

      在現(xiàn)代,Adapter 更多地被作為 數(shù)據(jù)類 -> 數(shù)據(jù)類的轉(zhuǎn)化,如常見的 pb -> pb:

      class ProtoAdapter {}Decorator:裝飾器

      在 GoF 中 Decorator 本來(lái)是將一個(gè)類作為抽象類,通過(guò)組合+繼承實(shí)現(xiàn)添加功能。實(shí)際上現(xiàn)代的編程實(shí)踐中往往通過(guò)直接提供一個(gè)容器的封裝提供裝飾功能,見上文 [容器類]部分。 所以 GoF 式 Decorator 并不常見,除非像 Python 在語(yǔ)法層面提供了裝飾器。在 Java 中類似的功能是注解。

      Delegation:委派模式

      GoF 中是非?;镜哪J剑河梢粋€(gè)類負(fù)責(zé)接受請(qǐng)求,并把請(qǐng)求轉(zhuǎn)發(fā)到合適的實(shí)例類中執(zhí)行。

      class RealPrinter {} class Printer { RealPrinter printer; }

      Delegate 非常常見,也提供了兩個(gè)名字,請(qǐng)注意區(qū)分:

      Delegate 是被委任的對(duì)象。

      Delegator 是委任對(duì)象。
      所以,通常情況下 Delegator 在命名中會(huì)更常見,類似于 Dispatcher。Delegate 更多作為一個(gè)類型或是接口被實(shí)現(xiàn)。具體的選擇參見 [編排] 部分。

      Facade: 外觀模式

      GoF 中 Facade Pattern 通常是指為子系統(tǒng)提供一個(gè)更高層的統(tǒng)一界面,屏蔽子系統(tǒng)的獨(dú)有的細(xì)節(jié)。 在現(xiàn)實(shí)中,F(xiàn)acade 通常用來(lái)為非常復(fù)雜的類/系統(tǒng)定義一個(gè)較為簡(jiǎn)化的界面,如:

      // proto, extremely complicated TripResponse message TripResponse { // ... // ... string last_message = 3279; } class TripResponseFacade { private final TripResponse response; Trip trip(); Endpoint source(); // Abstracted and processed Endpoint target(); // Abstracted and processed }

      Facade 與 Adapter 的主要區(qū)別在于 Facade 的主要目的是為了簡(jiǎn)化,或者說(shuō)更高層次的抽象,并且通常簡(jiǎn)化的界面不服務(wù)于專門的對(duì)接類。 Adapter 通常是為了一個(gè)特定的對(duì)接類實(shí)現(xiàn)。

      注意 Facade 命名通常可以省略。僅當(dāng)你的意圖是明確告知用戶這是關(guān)于某個(gè)類的外觀時(shí)使用。

      Proxy:代理模式

      GoF 中代理模式用來(lái)添加一層抽象,以對(duì)實(shí)際類進(jìn)行控制,并添加某些行為(如 lazy/memoized),或是隱藏某些信息(例如可見性或是執(zhí)行遠(yuǎn)程調(diào)用)。

      Proxy 與 Facade 的區(qū)別在于 Proxy 通常是為了額外的控制/記錄等行為,而非只是為了更高的抽象/簡(jiǎn)化。

      注意 Proxy 作為代碼模式時(shí),通常不應(yīng)該出現(xiàn)在命名之中。使用具體的 Proxy 的目的作為命名,如 LazyCar 或是 TracedRuntime,而非 CarProxy 或是 RuntimeProxy。

      Proxy 還有另一個(gè)含義就是真正的“代理”,如代理服務(wù)器。在這種情況下,使用 Proxy 是合適且應(yīng)該的。這也是另一個(gè)為什么代理模式不應(yīng)該用 Proxy 命名的原因。

      Iterator: 迭代器

      時(shí)至今日仍然最常見的模式之一。Interator 有以下兩個(gè)術(shù)語(yǔ),不要混淆:

      Iterable: 迭代容器

      Iterator: 迭代器

      Visitor: 訪問(wèn)者模式

      訪問(wèn)者模式用來(lái)遍歷一個(gè)結(jié)構(gòu)內(nèi)的多個(gè)對(duì)象。對(duì)象提供 accept(Visitor) 方法,調(diào)用 Visitor.visit 方法。

      即使如此,Visitor 應(yīng)該并不常見,因?yàn)樗梢院?jiǎn)單地被函數(shù)式的寫法替換:

      class Car { void accept(Consumer visitor); // No longer need to define Visitor class. }Observer/Observable: 觀察者模式

      Observer/Publisher/Subscriber/Producer/Consumer

      時(shí)至今日最常見的模式之一。和事件驅(qū)動(dòng)編程(Event-based)有緊密關(guān)系 -- Oberservable 發(fā)布消息,所有注冊(cè)的 Obeserver 會(huì)接收消息。 Publisher/Subscriber 也是類似的,它們的區(qū)別在于 Observer 模式往往是強(qiáng)綁定的 -- 注冊(cè)和分發(fā)通常在 Observable 類中實(shí)現(xiàn); 而 PubSub 模式通常有專門的 Message Broker,即 Publisher 與 Subscriber 是完全解耦的。

      PubSub 與 Producer/Consumer 的區(qū)別是:

      Publisher/Subscriber: 在事件流系統(tǒng)中,表示 1:N 廣播/訂閱。

      Producer/Consumer: 在整個(gè)流系統(tǒng)中,專指 1:1 生產(chǎn)/消費(fèi)。Producer/Consumer 也是 Pub/Sub 系統(tǒng)的組件(廣播也是一對(duì)一廣播的)。

      有些系統(tǒng)(Kafka)使用 Consumer Group 表示 Subscriber。

      所有的消息注冊(cè)的模式由三部分組成:

      Notification: 消息本身

      Sender:消息發(fā)送者/注冊(cè)

      Receiver: 消息接收者

      關(guān)于命名參見 [事件] 部分。

      Strategy:策略模式

      Strategy/Policy

      策略模式在 GoF 中用以指定某個(gè)行為在不同場(chǎng)景下的不同實(shí)現(xiàn),作為“策略”。

      Strategy 模式往往不是很顯式?,F(xiàn)代通常使用 Strategy 表示實(shí)際的“策略”,即對(duì)信息不同的處理策略,而不采取 Strategy 模式的含義。

      在“策略”這個(gè)語(yǔ)義中,Strategy/Policy 沒(méi)有區(qū)別。在同一個(gè)項(xiàng)目中,應(yīng)該保持一致

      Command:命令模式

      命令模式在 GoF 中以類開代表實(shí)際行動(dòng),將行動(dòng)封裝,以支持重復(fù)、取消等操作。

      Command 在現(xiàn)代編程實(shí)踐中可以通過(guò)簡(jiǎn)單的函數(shù)式方案替換,如:

      Function command; // Java std::function command; // C++ type Command func(T*) T* // Go

      現(xiàn)代通常使用 Command 表示實(shí)際的“命令”,而不采取 Command 模式的含義。

      Null Object 模式

      Tombstone

      Null Object 模式不在 GoF 當(dāng)中。它是一個(gè)用來(lái)代替 null 的 object,對(duì)其所有的操作都會(huì)被吞掉。 Null Object 主要是為了避免空指針。 合理的零值,例如 go time.Time = 0,也可以理解為一種 Null Object。

      通常會(huì)有一個(gè)專門的對(duì)象表示 Null Object??梢越栌?Tombstone 表示 Null Object。

      Object Pool 對(duì)象池模式

      Pool

      對(duì)象池模式不在 GoF 當(dāng)中。它是將一系列昂貴的對(duì)象創(chuàng)建好放在一個(gè)池子中,并使用戶通過(guò)向池子申請(qǐng)對(duì)象,而不再自己手動(dòng)地創(chuàng)建/銷毀對(duì)象。最著名的池化的例子是線程池,即 ThreadPool。

      Pool 通常用來(lái)表示對(duì)象池子,例如 ThreadPool, ConnectionPool。

      Arena

      Arena 是指 Region-based memory management,是指一片連續(xù)的內(nèi)存空間,用戶在其中分配創(chuàng)建對(duì)象,管理內(nèi)存。

      前/后綴并發(fā)/異步

      Concurrent
      Synchronized
      Async

      有時(shí)候我們需要特別標(biāo)明一個(gè)類是線程安全的。通常這是特意為了與另一個(gè)線程不安全的實(shí)現(xiàn)做區(qū)分。典型的例子是 HashMap 和 ConcurrentHashMap。如果一個(gè)類只是單純是線程安全的,那么通常不需要在名字里特意說(shuō)明,在文檔里說(shuō)明即可。

      例如:

      /** This class is designed to be thread safe. */ class SomeClassThreadSafe {} /** This class is immutable thus thread safe. */ class SomeClassImmutable {}

      Concurrent 通常是用來(lái)說(shuō)明該類是線程安全的前綴。Synchronized 是另一個(gè)在 Java 中可用的標(biāo)明類是線程安全的前綴。但是,這通常說(shuō)明這個(gè)類是通過(guò) synchronized 機(jī)制來(lái)保證線程安全的,所以只在 Java 中使用。

      另一個(gè)常見的場(chǎng)景是同一個(gè)方法有兩種實(shí)現(xiàn):同步阻塞和異步不阻塞的。在這種情況下,通常會(huì)命名異常不阻塞的方法為 {synchronizedMethod}Async,例如:

      public T exec(); public Future execAsync();

      如果一個(gè)異步的方法并沒(méi)有對(duì)應(yīng)的同步方法,通常不需要加 Async 后綴。

      在 Go 中,如果一個(gè)方法是意圖在其它協(xié)程中異步執(zhí)行,不需要加 Async 后綴。

      緩存/惰性

      Cached/Buffered
      Lazy
      Memoized

      名詞辨析:

      Cached 表示獲取的對(duì)象會(huì)被緩存,保留一段時(shí)間,在緩存期間不會(huì)重新獲取。

      Buffered 與 Cached 同義。

      Lazy 表示這個(gè)對(duì)象會(huì)被在第一次調(diào)用時(shí)創(chuàng)建,之后一直保留

      Memoized 通常表示執(zhí)行結(jié)果會(huì)在第一次計(jì)算后被記憶,之后不會(huì)再重復(fù)計(jì)算

      注意 Buffered 不應(yīng)該與 Buffer 混淆。 Buffer 作為名詞專指“緩沖區(qū)”。
      注意 Cached 不應(yīng)該與 Cache 混淆。 Cache 作為名詞專指“緩存”。

      Cached/Buffered 應(yīng)該在項(xiàng)目中是一致的。 Cached/Lazy/Memoized 取決于對(duì)象是被獲取的,還是創(chuàng)建的,還是計(jì)算獲得的。

      不可變性

      Mutable
      Immutable

      Mutable 顯式地聲明一個(gè)類是可變的,Immutable 顯式地聲明一個(gè)類是不可變的。 通常情況下,類似于并發(fā)安全性,是否可變應(yīng)該在類文檔中說(shuō)明,而不應(yīng)該在類名中,顯得臃腫。只有當(dāng)一個(gè)類同時(shí)有可變/不可變版本時(shí),可以使用 Class/ImmutableClass。

      存儲(chǔ)/數(shù)據(jù)/處理數(shù)據(jù)類

      Object
      Data
      Value
      Record
      Entity
      Instance

      上面幾個(gè)都可以用來(lái)表示一個(gè)表示數(shù)據(jù)的類。但是這些詞是典型的“無(wú)意義詞匯”,如果把它們從名字中刪除,仍然可以表示完整意義,那么應(yīng)該刪掉。

      class CarObject {} // Bad class CarEntity {} // Bad class CarInstance {} // Bad class Car {} // Good class MapKey {} class MapValue {} // OK. Couldn't be shortened. class LoggingMetricsData {} // Bad class LoggingMetricsValue {} // Bad class LoggingMetricsRecord {} // Bad class Logging Metrics {} // Good class DrivingRecord {} // OK. Couldn't be shortened.

      Statistics/Stats

      表示“統(tǒng)計(jì)數(shù)據(jù)”。 Stats 是公認(rèn)的可用的 Statistics 的縮寫,Java/C++/Go 均可。

      存儲(chǔ)

      Storage
      Database
      Store
      DB

      Cache

      Verbs:
      - save/store/put

      Storage/Database/Store/DB 都可以作為“存儲(chǔ)服務(wù)”,即廣義上的“數(shù)據(jù)庫(kù)”(不是必須是完整的 DBMS)。 其中,在 C++/Go 中 DB 是常見且可接受的。在 Java 中通常使用全稱。

      項(xiàng)目?jī)?nèi)應(yīng)該選擇一個(gè)術(shù)語(yǔ)保持一致。

      save/store/put 在數(shù)據(jù)庫(kù)類中是同義詞。同一個(gè)項(xiàng)目中應(yīng)該保持一致

      數(shù)據(jù)格式

      Schema
      Index
      Format
      Pattern

      名詞辨析:

      Schema 借用數(shù)據(jù)庫(kù)的概念,指數(shù)據(jù)的結(jié)構(gòu)模式。

      Index 借用數(shù)據(jù)庫(kù)的概念,專指數(shù)據(jù)的索引

      Format/Pattern 通常是泛指的“模式/格式”概念。實(shí)際出現(xiàn)時(shí),F(xiàn)ormat/Pattern 往往和字符串相關(guān),如 Java 使用 Pattern 表示正則表達(dá)式。在非公共代碼中,F(xiàn)ormat/Pattern 通常過(guò)于寬泛,應(yīng)該考慮選用更細(xì)化的名詞。

      哈希

      Hash/Digest/Fingerprint/Checksum

      Hash/Digest 哈希是一種將任何數(shù)據(jù)映射到一個(gè)較小的空間的方法。映射通常被稱為哈希函數(shù)(Hash Function),映射值通常被稱為摘要(Digest)。

      Hash(Data) = Digest

      Checksum 出自編碼論,可以理解為一種特殊的哈希函數(shù),用來(lái)檢查文件的完整性。換言之,如果一份數(shù)據(jù)出現(xiàn)了任何變動(dòng),Checksum 應(yīng)該期待會(huì)改變。(但是 Checksum 實(shí)際上并不要求唯一性,見 Fingerpint)

      Fingerprint 類似于 Checksum,但是 Fingerprint 通常更嚴(yán)格,它通常要求最少有 64-bit,使得任何兩個(gè)文件只要不同,幾乎(概率意義上接近 2^-64)不可能有同一份指紋,即唯一性。(但是 Fingerprint 的定義不要求密碼安全性即 cryptographic)

      所以 Checksum 只是作為文件變更校驗(yàn),而 Fingerprint 可以作為數(shù)據(jù)的唯一標(biāo)記。

      在命名時(shí),優(yōu)先使用 Fingerprint/Checksum,或其它特定指定用途的術(shù)語(yǔ)。當(dāng)以上均不合適時(shí),回退到更泛化的概念,即 Digest。

      流式編程

      Stream
      Source/Sink
      Pipe/Piped

      流式編程通常有自己的專有詞匯表。具體地:

      Stream 表示流式

      Source 表示數(shù)據(jù)源(輸入),Sink 表示 數(shù)據(jù)匯(輸出)。

      動(dòng)詞詞匯表,如 map/reduce/join/filter/iterate/do/window/key/evict/peek/trigger/slide/...

      原則是:選擇你的團(tuán)隊(duì)里最常使用的流式處理系統(tǒng)所使用的詞匯表。

      狀態(tài)

      State/Status

      很諷刺地,很多人認(rèn)為這兩個(gè)詞有區(qū)別,但是他們認(rèn)為區(qū)別的點(diǎn)各不相同。見下文參考文獻(xiàn)。筆者傾向于認(rèn)為它們其實(shí)沒(méi)什么本質(zhì)區(qū)別。

      鼓勵(lì)使用 State 表示狀態(tài)。因?yàn)?HTTP 和 RPC 已經(jīng)占用了 Status 這個(gè)術(shù)語(yǔ),為了避免誤解,使用 State 表示自定義狀態(tài)。

      參考:

      https://stackoverflow.com/questions/1162816/naming-conventions-state-versus-status

      https://softwareengineering.stackexchange.com/questions/219351/state-or-status-when-should-a-variable-name-contain-the-word-state-and-w

      鼓勵(lì)使用 State: https://google.aip.dev/216

      計(jì)數(shù)

      Num/Count/Size/Length/Capacity

      Num/Count 表示數(shù)量,但不強(qiáng)制是某個(gè) collection 的長(zhǎng)度。推薦使用 Count。

      Size/Length 表示容器1的當(dāng)前容量。遵循語(yǔ)言慣例,通常使用 Size。

      Capacity 通常表示容器的最大容量。

      方法/動(dòng)詞

      動(dòng)詞是句子的精髓。選擇精準(zhǔn)的動(dòng)詞是代碼可讀性的關(guān)鍵。 本章對(duì)動(dòng)作做了分類,并且提供了部分備選。如果動(dòng)詞有反義詞,它們會(huì)被聚合在一個(gè)詞條中。 本章的詞匯有兩種:

      動(dòng)詞

      以執(zhí)行一個(gè)動(dòng)作為主的某些行為類,即 -er 模式,如 Producer。 -able 模式,如 Writable 是類似的,因?yàn)椴辉儋樖觥?/p>創(chuàng)建/提供

      Producer/Provider/Supplier/Generator/Constructor/Factory
      Builder.build

      Verbs:

      create/from/of/with/valueOf/instance/getInstance/newInstance/getFoo/newFoo

      get/peek

      make/generate

      創(chuàng)建/提供名詞辨析:

      Producer/Supplier/Provider 同義詞,都表示“提供一個(gè)對(duì)象”。這些提供者可能是惰性的(Lazy)。實(shí)例未必由這些提供者創(chuàng)建(雖然通常是)。

      它們對(duì)應(yīng)的動(dòng)詞是工廠方法的常見命名,即:

      create/from/of/with/valueOf/instance/getInstance/newInstance/getFoo/newFoo

      推薦在項(xiàng)目中使用同一種命名。推薦使用 of/from,更短。

      Generator 通常專指某些需要經(jīng)過(guò)計(jì)算的、特殊的對(duì)象,例如 ID。

      對(duì)應(yīng)的動(dòng)詞是 generate,強(qiáng)調(diào)全新生成。

      Constructor 通常是指一個(gè)復(fù)雜對(duì)象的構(gòu)建器,不是指構(gòu)造函數(shù)。它通常用于比 Builder 更復(fù)雜的構(gòu)建 (Builder 通常不會(huì)附帶邏輯)。

      Factory 是專職的工廠類。當(dāng)工廠方法較為復(fù)雜,需要抽出,或者有狀態(tài)的工廠時(shí)使用。

      對(duì)應(yīng)上文工廠方法的常見命名。

      Builder 見前文 [Builder 構(gòu)建者模式]

      動(dòng)詞辨析:

      get vs peek

      get 是廣義的“獲取”,在絕大部分場(chǎng)景下適用

      peek 也是“獲取”對(duì)象,但是這里強(qiáng)調(diào)的是對(duì)原對(duì)象無(wú)副作用。在函數(shù)式編程中會(huì)用來(lái)作為不破壞數(shù)據(jù)流的旁路操作。

      create vs make vs generate

      同義詞,表創(chuàng)建。推薦在項(xiàng)目中保持一致。

      消費(fèi)

      Consumer.accept/consume/poll

      消費(fèi)名詞:

      Consumer 是最常見的“消費(fèi)者”,通常表示某個(gè)數(shù)據(jù)流的終端消費(fèi)方。

      對(duì)應(yīng)的動(dòng)詞是 accept 或是 consume,遵守所使用消息隊(duì)列框架的命名風(fēng)格,否則,項(xiàng)目?jī)?nèi)保持一致。

      poll 特指數(shù)據(jù)是通過(guò)輪詢(poll),即 Consumer 通常主動(dòng)獲取消息,而非被推送(push)后處理。

      注意區(qū)分輪 xun 中文的歧義:

      poll 翻譯為輪詢,指一個(gè)客戶端間斷性地向外進(jìn)行獲取數(shù)據(jù)的行為策略。

      round-robin 翻譯為輪循,指以單一的方向循環(huán)接受信息/資源的分發(fā)策略。

      注意輪詢是 poll 不是 pull,雖然后者直覺上是“拉取,但 poll 強(qiáng)制間斷性地主動(dòng)地采樣/獲取數(shù)據(jù),是正式的計(jì)算機(jī)術(shù)語(yǔ)。

      查找

      Verbs:
      - find/search/query

      同義詞。推薦在項(xiàng)目中保持一致。 具體地,這幾個(gè)詞實(shí)際上有細(xì)微的不一致。通常情況下它們可能有以下區(qū)分:

      find 查詢單個(gè)結(jié)果,search 查詢一列符合條件的結(jié)果

      find 表示“找到”,即終態(tài),search 表“搜索”,即行為。

      query 表示“查詢”,類似于 search,但是暗示可能會(huì)有更高的成本。
      但是,不要做這種程度的細(xì)分,大部分人認(rèn)為它們是同義詞。

      參考 https://stackoverflow.com/questions/480811/semantic-difference-between-find-and-search

      拷貝

      Verbs:
      - copy/clone

      同義詞。遵循語(yǔ)言慣例。

      Java 使用 clone。 Go/C++ 使用 copy。

      添加

      Verbs:
      - add/append/put/insert/push

      動(dòng)詞辨析:

      append 專指添加到列表末。

      insert 強(qiáng)調(diào)可以插入到列表的任何位置。

      add 是通用的列表添加方案,add(E) 等同于 append,add(index, E) 等同于 insert。addAll 用于批量添加。

      put 通常用于列表之外的添加場(chǎng)景。如 map, iostream。

      push 僅用于某些數(shù)據(jù)結(jié)構(gòu),如棧。

      對(duì)于自定義的可添加 api,應(yīng)該貼近底層的標(biāo)準(zhǔn)庫(kù)的數(shù)據(jù)結(jié)構(gòu)所使用的動(dòng)詞。作為泛用的添加,使用 add。

      更新

      Verbs:
      - set/update/edit

      同義詞。在代碼 API 中使用 set,在 RPC API 中使用 update。

      刪除

      Verbs:
      - remove/delete/erase/clear/pop

      動(dòng)詞辨析:

      remove/delete/erase 是同義詞。嚴(yán)格來(lái)說(shuō),remove 指移除,即暫時(shí)從容器中取出放置在一邊,delete/erase 指刪除,即將對(duì)象整個(gè)清除。但是在日常編程中不需要做這種區(qū)分。通常,代碼 API 中使用 remove(或依語(yǔ)言慣例),RPC API 中使用 delete 作為標(biāo)準(zhǔn)方法。

      clear 通常表示 1) 清理列表,等效于 removeAll 2)清理狀態(tài),即恢復(fù)類到初始化狀態(tài)。

      pop 只在棧/隊(duì)列等數(shù)據(jù)結(jié)構(gòu)中使用,通常會(huì)返回對(duì)象并從數(shù)據(jù)結(jié)構(gòu)中移除。

      編排

      Scheduler/Dispatcher/Coordinator/Orchestrator/Delegator
      - Verb: schedule/dispatch/orchestrate

      Scheduler/Dispatcher 均借用于操作系統(tǒng)概念。

      名詞辨析:

      Scheduler: 通常 Scheduler 用于分發(fā)中長(zhǎng)期 Job。換言之,Scheduler 通常涉及到資源分配。

      對(duì)應(yīng)動(dòng)詞為 schedule

      Dispatcher: 通常只負(fù)責(zé)接受事件,采用某些固定的策略分發(fā)任務(wù),例如 round-robin。不涉及資源分配。

      對(duì)應(yīng)動(dòng)詞為 dispatch

      Coordinator: 通常作為 Scheduler/Dispatcher 的同義詞。鑒于其模糊性,推薦使用更細(xì)化的 Scheduler/Dispatcher

      對(duì)應(yīng)動(dòng)詞為 coordinate

      Orchstrator:執(zhí)行比簡(jiǎn)單的分發(fā),即 scheduler/dispatcher 更復(fù)雜的任務(wù)/流程編排。通常,這些任務(wù)有前后依賴關(guān)系,會(huì)形成一個(gè)有向無(wú)環(huán)圖。

      對(duì)應(yīng)動(dòng)詞為 orchestrate。 Orchestrator 的輸出通常是工作流,即 Workflow。

      Delegator: 專指委任。雖然形式類似,但是 Delegator 強(qiáng)調(diào)單純的委任。參見 [Delegation: 委派模式]。

      對(duì)應(yīng)動(dòng)詞為 delegate,但通常不會(huì)使用。

      檢查/驗(yàn)證

      Validator/Checker/Verifier
      - Verb: validate/check/verify/assert

      Validation/Verification 的明確區(qū)分來(lái)自于軟件測(cè)試。

      Validation 通常指對(duì)產(chǎn)品符合用戶/顧客預(yù)期的驗(yàn)證。外部用戶會(huì)參與。

      Verification 通常指產(chǎn)品合規(guī)/符合給定規(guī)范。通常是內(nèi)部流程。

      在程序中,不沿用這種區(qū)分。通常:

      Validator 用于輸入檢測(cè)

      Verifier 用于運(yùn)行的不變量檢測(cè)

      具體地:

      check 用于輸入校驗(yàn)。 validate 用于復(fù)雜的輸入校驗(yàn)。

      assert/verify 用于不變量驗(yàn)證,尤其在單元測(cè)試中

      public void process(String s, ComplicatedObject co) { checkNotNull(s); // check validateComplicatedObject(co); // validate } @Test public void testProcess() { process("ss", co); Truth.assertThat(...); // assert verifyZeroInvocations(co); // verify }執(zhí)行/操作

      Task/Job/Runnable

      Executor/Operator/Processor/Runner
      - Verb: exec/execute/do/process/run

      名詞辨析:

      Runnable 是泛用的“帶上文的可執(zhí)行代碼塊”。

      Task 粒度比 Job 更細(xì)

      Job 通常是耗時(shí)更長(zhǎng)的任務(wù)

      但是,推薦不做區(qū)分,認(rèn)為它們都是同義詞。使用 Task 或者 Job 作為類名。

      名詞辨析: Processor/Executor/Operator 是從計(jì)算機(jī)架構(gòu)借用的概念。

      Executor: 常見。通常對(duì)應(yīng) Job/Task

      對(duì)應(yīng) execute。 exec 是可接受的公認(rèn)的縮寫。

      Operator: 通常對(duì)應(yīng)某些具體的操作類。更多使用本義,即操作符。

      對(duì)應(yīng) do。

      Processor:更多在文本文檔(work/document processor)、數(shù)據(jù)處理(data processor) 語(yǔ)境下使用。

      對(duì)應(yīng) process。

      Runner: 通常對(duì)應(yīng) Runnable

      對(duì)應(yīng) run

      但是,推薦不做區(qū)分,認(rèn)為它們都是同義詞。日常編程中,使用 Executor 作為 Job 執(zhí)行器。

      開啟 vs 關(guān)閉

      toggle/switch/enable/disable/turnOn/turnOff/activate/deactivate

      二元狀態(tài)的開啟關(guān)閉。上述全是同義詞。

      在項(xiàng)目中保持統(tǒng)一。注意比起 toggle(bool) 和 switch(bool),更推薦分離的 enable/disable。

      讀取 vs 寫入

      Reader/Prefetcher/Fetcher/Downloader/Loader
      - Verb: read/get/fetch/load/retrieve
      Writer/Uploader
      - Verb: write/upload

      Lifecycle:
      - open/close

      名詞辨析:

      Reader 通常是從 stdio/文件/其它 Source 中讀取。

      對(duì)應(yīng)動(dòng)詞 read

      Fetcher 通常是從遠(yuǎn)端拉取數(shù)據(jù)

      對(duì)應(yīng)動(dòng)詞 fetch

      Downloader 類似于 Fetcher,但是通常內(nèi)容是文件等 blob,而非結(jié)構(gòu)化數(shù)據(jù)

      對(duì)應(yīng)動(dòng)詞 download

      Prefetcher 強(qiáng)調(diào)預(yù)熱拉取,通常是拉取到緩存中。

      對(duì)應(yīng)動(dòng)詞 prefetch 或是簡(jiǎn)單的 fetch

      Loader 是泛用詞匯,表示廣義的“加載”。通??梢员硎旧鲜龅娜魏我环N。

      對(duì)應(yīng)動(dòng)詞 load

      Retrieve 是 Fetch 的同義詞。

      具體地,fetch/load 是有語(yǔ)義的細(xì)微差別。但是,不需要做具體的細(xì)分。

      優(yōu)先使用 read/fetch/download,當(dāng)均不合適時(shí),回退到 load。

      序列化 vs 反序列化

      Serializer
      - Verb: serialize/pack/marshal
      Deserializer
      - Verb: deserialize/unpack/unmarshal

      動(dòng)詞辨析:

      pack 指打包,將數(shù)據(jù)打包為一個(gè)不可拆分的(通常是不透明的)對(duì)象

      serialize 指序列化,將數(shù)據(jù)轉(zhuǎn)換為可以被存儲(chǔ)/傳輸?shù)模ㄍǔJ嵌M(jìn)制)格式。

      marshal 強(qiáng)調(diào)意圖 -- 將一個(gè)對(duì)象從程序 A 轉(zhuǎn)移到程序 B 中。

      但是,不需要做這個(gè)區(qū)分??梢哉J(rèn)為它們都是同義詞。按語(yǔ)言慣例使用:

      C++: Serialize

      Java: Serialize

      Go: Marshal

      Python: Pack

      注意反序列化是 deserialize, 比 unserialize 更常見。 但 pack -> unpack, marshal -> unmarshal。

      https://en.wikipedia.org/wiki/Marshalling_(computer_science)

      https://en.wikipedia.org/wiki/Serialization

      轉(zhuǎn)換

      Applier/Converter/Transformer/Mapper
      - Verb: apply/convert/transform/map/to/translate

      可以認(rèn)為它們都是同義詞。在項(xiàng)目中應(yīng)該保持一致。 嚴(yán)格來(lái)說(shuō),Mapper 更多指同一數(shù)據(jù)的兩種形式的雙向映射,例如數(shù)據(jù)庫(kù)存儲(chǔ)和運(yùn)行時(shí)對(duì)象。 在 Applier/Converter/Transformer 中,Applier 最為常見,因?yàn)樵醋栽O(shè)計(jì)模式。 Mapper 在框架中較常見。

      匹配

      Filter/Matcher
      - Verb: query/filter/match

      可以認(rèn)為它們都是同義詞。 在項(xiàng)目中應(yīng)該保持一致。

      事件

      Event

      Listener/Notifier Verbs: notify
      Observer/Observable Verbs: observe
      Handler Verbs: handle
      Publisher/Subscriber
      Publisher/Consumer

      在 [Observer Pattner: 觀察者模式] 中已經(jīng)解釋。

      Observer 是正宗的觀察者

      Listner/Notifier 通??梢杂脕?lái)作為 Observer/Observable 的同義詞。但是 Listener 也可能表示其它含義,如 TraceListener,視框架而定。

      Handler 也是同義詞。它與 Listener/Observer 的區(qū)別在于,它表示唯一的事件處理器。而 Listener/Observer 可能有多個(gè)。

      Publisher/Subscriber: 在事件流系統(tǒng)中,表示 1:N 廣播/訂閱。

      Producer/Consumer: 在整個(gè)流系統(tǒng)中,專指 1:1 生產(chǎn)/消費(fèi)。

      見 https://stackoverflow.com/questions/42471870/publish-subscribe-vs-producer-consumer

      文本處理

      Regex/Pattern/Template

      Pruner/Stripper/Trimmer
      Formatter/Prettier
      Resolver/Parser/Expander

      - Verb: compile/parse/resolve/expand
      - Verb: format/split/separate/merge/join

      通常,一個(gè)程序中有 20% 的代碼在處理字符串。所以與文本相關(guān)的內(nèi)容非常多。這里沒(méi)有列出全部。

      “模板”名詞解析:

      Regex 專指正則表達(dá)式。另一個(gè)常見的縮寫是 Regexp。應(yīng)該與語(yǔ)言保持一致。C++ 使用 Regex。Go 使用 Regexp。

      編譯使用 compile。 正則本身就是一種 formal language,因此使用 compile 是正統(tǒng)。

      匹配對(duì)應(yīng)動(dòng)詞為 expand/match/match

      Pattern 在 Java 中表示正則表達(dá)式。雖然 Pattern 可能通指“模式”,但是通常不在編程中使用。

      編譯使用 compile

      對(duì)應(yīng)動(dòng)詞為 match/split

      Template 指模板,通常不是正則形式的,而是簡(jiǎn)單的匹配替換模板,如 HTML 模板。

      對(duì)應(yīng)動(dòng)詞為 expand

      “修剪”動(dòng)名詞解析:

      Pruner.prune: 指清理掉過(guò)時(shí)的、不應(yīng)存在的內(nèi)容

      Stripper.strip: 指清理掉多余的、過(guò)度生長(zhǎng)的內(nèi)容

      Trimmer.trim: 泛指修剪,使其更好看。

      但是,Prune/Strip/Trim 在編程中通常認(rèn)為是同義詞。它們通常情況下:

      Strip/Trim 指去掉頭尾的多余空格

      Prune 可能會(huì)進(jìn)行其它的裁剪

      語(yǔ)言可能會(huì)為之賦予特殊含義,例如在 Java 11 中,Trim 會(huì)清理掉所有的普通空格,而 Strip 會(huì)清理掉所有的 Unicode 空格。

      https://stackoverflow.com/questions/51266582/difference-between-string-trim-and-strip-methods-in-java-11

      “格式化”動(dòng)名詞解析:

      Formatter.format 是將對(duì)象進(jìn)行格式化。通用名詞。

      Prettier.pprint 專指將數(shù)據(jù)整理為便于人類可讀的的輸出格式。典型的例子是 Python 的 pprint。

      “解析”動(dòng)名詞解析:

      Expander.expand 通常用于 DSL/Schema 解析,專指將某些 DSL 展開,如變量替換,展開 glob。

      Parser.parse 類似于 parse,但強(qiáng)調(diào)將文本進(jìn)行句法解析,形成格式化的中間層表示。借用了編譯器術(shù)語(yǔ)。

      Resolver.resolve Resolve 通常指從人類可讀的定義(可能有歧義或不精確)向機(jī)器可讀的定義(精確的、可解析的)的轉(zhuǎn)換。例如,域名 -> ip 的解析,依賴包的版本號(hào)的解析(打平)。(!) resolve 不同于 expand/parse 的文本解析。這是一個(gè)相同中文不同英文的易混淆例子。

      生命周期

      Lifecycle

      Initializer/Finalizer

      Verb:
      - init/setup/prepare
      - pause/resume
      - start/begin
      - end/terminate/stop/halt
      - destroy/release/shutdown/teardown

      生命周期解析: 一個(gè)對(duì)象的生命周期,稱為 Lifecycle,通常有以下流程:

      創(chuàng)建。通常由語(yǔ)言特性支持,不屬于生命周期管理范圍。

      初始化:init。init 是 initialize 的全稱,通常用來(lái)初始化一個(gè)類到可用狀態(tài)。應(yīng)該盡量避免創(chuàng)建之外的額外初始化步驟,一個(gè)對(duì)象應(yīng)該盡可能在創(chuàng)建后就處于已初始化狀態(tài)。額外的狀態(tài)會(huì)讓這個(gè)類更難正確使用。

      setup/prepare 是 init 的同義詞。應(yīng)該在項(xiàng)目?jī)?nèi)統(tǒng)一,推薦為 init。setUp 通常在測(cè)試中使用,用于作為每個(gè)測(cè)試用例設(shè)計(jì)的前置步驟。

      init vs prepare: 具體地細(xì)分,init 的語(yǔ)義通常指“在類生命周期層面處在正??蓤?zhí)行狀態(tài)”,prepare 的語(yǔ)義通常指“在業(yè)務(wù)層面做好準(zhǔn)備”

      開始: start/begin。通常用于這個(gè)對(duì)象正式開始正常工作,即切換到 running 狀態(tài)。在切換到其它狀態(tài)之前這個(gè)類會(huì)一直保持在 running 狀態(tài)。

      start/begin 是同義詞。通常使用 start 作為動(dòng)詞“開始”,使用 begin 作為列表的頭。

      暫停: pause。pause 應(yīng)該使得類暫停運(yùn)行,從 running 狀態(tài)切換到 paused 狀態(tài)。這段時(shí)間這個(gè)類應(yīng)該不再工作。

      恢復(fù):resume。resume 與 pause 是成對(duì)的。 resume 會(huì)恢復(fù) paused 到 running 狀態(tài)。通常,pause/resume 可以無(wú)限次隨時(shí)切換。

      停止:stop/end/terminate/halt。停止類運(yùn)行,與 start 對(duì)應(yīng)。通常情況下,一個(gè)類 stop 意味著不會(huì)再重新啟動(dòng)。通常情況下,停止?fàn)顟B(tài)的類應(yīng)該拒絕任何請(qǐng)求。

      stop/end/terminate/halt 是同義詞。不要做區(qū)分處理,在項(xiàng)目中保持一致。

      銷毀:destroy/release/shutdown/teardown/exit。徹底銷毀對(duì)象。此后,對(duì)象不再處于可用狀態(tài)。

      destroy/release/shutdown/teardown 是近義詞。具體地:

      destroy 強(qiáng)調(diào)銷毀對(duì)象。

      release 強(qiáng)調(diào)釋放資源。

      teardown 通常與 setup 對(duì)應(yīng)。

      exit 通常指程序退出。

      shutdown 是通用“徹底關(guān)閉”的動(dòng)詞。當(dāng) destroy/release 不合適時(shí),回退到 shutdown。

      使用 gracefullyShutdown 表示優(yōu)雅關(guān)閉。這通常意味著是前幾個(gè)行為的集合:停止服務(wù)、釋放資源、刷新緩沖區(qū)、銷毀對(duì)象。

      計(jì)算

      Calculator

      Verb:
      - compute/calculate/calc

      使用 Calculator 而非 Computer 表示某個(gè)運(yùn)算的執(zhí)行器。Computer 雖然也是“計(jì)算器”,但是在代碼語(yǔ)境下有歧義。

      compute/calculate/calc 可以認(rèn)為是同義詞。如果是 Calculator,使用 calculate。其它情況下,使用 compute。

      元數(shù)據(jù)(配置/環(huán)境/...)

      Option/Config/Configuration/Setting/Preference/Property/Parameter/Argument

      Context/Environment

      Info/Metadata/Manifest/Version

      配置名詞解析: 這個(gè)有類似的名詞辨析,但是它們?cè)诰幊虝r(shí)通常認(rèn)為都是“配置”的同義詞。它們還會(huì)出現(xiàn)在用戶界面,尤其是 Settings/Options/Preferences。

      在編程的角度,Option/Config/Configuration 是同義詞,均表示配置。慣例使用 Options 作為子類定義一個(gè)類所需的配置,尤其是作為依賴注入時(shí)。

      使用 Property 表示單個(gè)屬性, 而且通常是 k-v 結(jié)構(gòu)。換言之,Option/Config 通常由多個(gè) Properties 組織。只有當(dāng) Property 是動(dòng)態(tài)屬性時(shí),才定義特殊的 Property 類,否則,在 Option 中定義具體的域表示 Property。

      struct Options { int fur_layer_count; // Good int fur_layer_count_property; // Bad! Property unnecessary struct ColorProperty { int a; int r; int g; int b; } // Bad! Prefer Color. ColorProperty color; }

      參數(shù)解析:

      Parameter:通常表示在接口處定義的參數(shù)

      Argument:指實(shí)際傳入接口的參數(shù)

      例如:

      func foo(param string) foo(arg)

      https://stackoverflow.com/questions/156767/whats-the-difference-between-an-argument-and-a-parameter

      上下文名詞辨析:

      Context 指上下文,通常用于在 API 之間傳遞與一次執(zhí)行相關(guān)的信息。在 RPC 處理中非常常見,例如 https://pkg.go.dev/context 。

      Environment 指環(huán)境。這個(gè)名詞從系統(tǒng)環(huán)境變量而來(lái)。通常,這表示在程序啟動(dòng)后保持穩(wěn)定的環(huán)境數(shù)據(jù),不隨所執(zhí)行的內(nèi)容(如 rpc 請(qǐng)求)變化而變化。

      元數(shù)據(jù)辨析:

      Info 泛指信息。而元數(shù)據(jù)相當(dāng)于特定的“關(guān)于數(shù)據(jù)”的信息。

      Metadata 標(biāo)準(zhǔn)用語(yǔ),專指元數(shù)據(jù)。避免使用 Info 代表元數(shù)據(jù)。

      Manifest 專指文件清單,描述一個(gè)模塊中的文件/功能/其它組成結(jié)構(gòu)的列表。Manifest 來(lái)自于貨運(yùn)術(shù)語(yǔ),Ship Manifest 用以列出所有的船員和船隊(duì)所有的船只。

      Version 專指程序的版本元數(shù)據(jù),例如 TrpcVersion。如果一個(gè)類專指版本,使用 Version 是最精確合適的。

      作者:piikee | 分類:八字起名 | 瀏覽:2 | 評(píng)論:0
      永春县| 青河县| 五峰| 越西县| 甘孜县| 拜泉县| 元谋县| 南康市| 阜宁县| 五指山市| 五常市| 长顺县| 安陆市| 凤凰县| 偃师市| 中江县| 滨海县| 东山县| 富顺县| 安化县| 潞城市| 库尔勒市| 广饶县| 芦溪县| 德庆县| 松潘县| 正镶白旗| 额敏县| 汽车| 鄯善县| 朔州市| 饶平县| 巴东县| 寿光市| 仁化县| 乡宁县| 乳山市| 阜阳市| 青岛市| 上栗县| 乌鲁木齐市|