国产成人乱无码视频,无码AV日韩一二三区,欧美精品成人,黄色一级视频欧美,亚洲三级色,亚洲中字无码AV电影在线观看,国产精品福利导航,青青草国产精品久久久久

起名打分測試免費打分以及起名字打分最準確免費

2025-03-06 00:10:54
八字起名網 > 八字起名 > 起名打分測試免費打分以及起名字打分最準確免費

本篇文章給大家談談起名打分測試免費打分,以及起名字打分最準確免費的知識點,希望對各位有所幫助,不要忘了收藏本站喔。

文章詳情介紹:

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

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

| 導語基于 Readability 的出題閱卷經驗的一些不完全的具體的命名指南。

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

-- Phil Karlton


軟件開發中一個著名的反直覺就是“起名兒”這個看上去很平凡的任務實際上很有難度。身邊統計學顯示,越是有經驗的程序員,越為起名頭痛。給小孩起名兒都沒這么費勁,對吧,王浩然?

命名的困難可能來自于以下幾個方面:

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

預測未來:類/方法的職責可能會在未來有變化,現在起的名字需要考慮未來可能的變動。

語言能力:缺少正確的語法知識,或是缺少足夠的詞匯量。本來英文就不是大部分中國人的母語,更甚者,計算機的詞匯表不同于日常交流詞匯表,有大量黑話。

不良設計:混亂的職責分布、不清晰的抽象分層、錯誤的實現,都會導致無法起出好的名字。在這個意義上,起名字其實是對設計的測試: 如果起不出名字來,很可能是設計沒做好 -- 重新想想設計吧。

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

本文描述一些實用主義的、可操作的、基于經驗的命名指南,并提供了一個代碼詞匯表,和部分近義詞辨析。本文沒有涉及討論名字的形而上學,例如如何做更好的設計和抽象以利于命名,也沒有涉及如何劃分對象等,也無意討論分析哲學。

命名原則

命名是一門平衡準確性和簡潔性的藝術 -- 名字應該包含足夠的信息能夠表達完整的含義,又應該不包含冗余的信息。

準確 Precision

名字最重要的屬性是準確。名字應該告訴用戶這個對象/方法的意圖 -- “它是什么” 和 “它能做什么”。 事實上,它是體現意圖的第一媒介 -- 名字無法表現含義時讀者才會閱讀文檔。

名字應該是有信息量的、無歧義的。以下一些策略可以增加名字的準確度:

可讀

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

可讀是字面意思,意味著它應該是通順的,所以應該:

避免 API 中使用縮寫

就像是給老板的匯報中不會把商業計劃寫成 Busi Plan 一樣,也不應該在公開 API 中使用一些奇怪的縮寫。現在已經不是 1970 年了,沒有一個方法不能超過 8 個字符的限制。把類/方法的名字寫全,對讀者好一點,可以降低自己被同事打一頓的風險。

creat 是個錯誤,是個錯誤,是個錯誤!

但是,首字母縮略詞的術語是可行并且推薦的,如 Http, Id, Url。

以下是可用的、得到普遍認可的縮寫:

configuration -> config

identifier -> id

specification -> spec

statistics -> stats

database -> db (only common in Go)

regular expression -> re/regex/regexp

未得到普遍認可的縮寫:

request -> req

response -> resp/rsp

service -> svr

object -> obj

metadata -> meta

business -> busi

req/resp/svr 在服務名稱中很常見。這非常糟糕。請使用全稱。

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

避免雙關

對類/方法的命名,不要使用 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 這種一般只有在大小寫不敏感的場合才會使用,例如包名 e2e 比 endtoend 更可讀。能區分大小寫的場合,不要使用 2/4。

合乎語法

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

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

關于命名的語法見“語法規則”一章。

使用單一的概念命名

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

考慮以下的角度:

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

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

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

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

簡而言之,名字應該是包含所有概念的分類的下確界

簡潔 Simplicity

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

在此,我提出一個可能會有爭議的觀點:所有的編程語言的命名風格應該是趨同的。不同于通常認為 Java 的命名會傾向于詳盡,Go 的命名會傾向于精簡,所有的語言對具體的“名字到底有多長”的建議應該是幾乎一樣的 -- 對外可見應該更詳細,內部成員應該更精簡。具體地:

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

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

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

上述規則像是 Go 的風格指南。但是,并沒有規定 Java 不能這樣做。事實上,Java 的冗長是 Java 程序員的自我束縛。即使在 Java 的代碼里,也可以這樣寫:

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

同樣,在 Go 的代碼中也不應該出現大量的無意義的縮寫,尤其是導出的結構體和方法。

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

當然,由于語言特性,在命名風格上可能會有差異。例如,由于 Go 的導入結構體都需要加包前綴,所以結構名中通常不會重復包前綴;但 C++/Java 通常不會依賴包名。但是,上述的原則仍然是成立的 -- 可見度越高,應該越少依賴上下文,并且命名越詳盡。

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

一致 Consistency

另一個容易被忽略的命名的黃金原則是一致性。換言之,名字的選取,在項目中應該保持一致。遵守代碼規范,避免這方面的主觀能動性,方便別人閱讀代碼。通常情況下,一個差的、但是達成共識的代碼規范,也會遠好于幾個好的、但是被未達成共識的規范。

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

但是僅符合代碼規范是不夠的。如同所有的語言,同一個概念,有多個正確的寫法。

考慮以下的例子:

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? }

幾種都是合理的(雖然不帶單位值得商榷)。但是,如果在一個代碼中出現了多種風格,使用起來很難預測。您也不想使用這樣的 API 吧?

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

另一個可考慮的建議是項目的技術負責人應該為項目準備項目的專有詞匯表。

語法規則類/類型

類應該是名詞形式,通常由單個名詞或名詞短語組成。其中,主要名詞會作為名詞短語的末尾。例如 Thread, PriorityQueue, MergeRequestRepository。

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

接口

接口的命名規則和類相同。除此之外,當接口表示可行動類型時,可使用另一個語法,即 Verb-able。例如:

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

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

輔助類

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

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

注1: 客觀來說,這適用于所有強制 OOP 的語言(所有強制把方法放在類里的語言)。但是除了 Java, 沒有別的語言這么煩啦。

方法

方法通常是謂語(動詞),或是 謂賓(動詞+名詞) 結構。注意以上語法中,動詞都在最前端。例如:

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

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

訪問器 Getter

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

Java: 所有的 Getter 都需要一個 get 前綴是來自于過時的 Java Beans Specification,以及 Javaer 的思想鋼印。

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

斷言函數指返回結果是布爾型(即真偽值)的函數。它們通常有以下命名格式:

系動詞: 主-系-表

即 isAdjective() 或 areAdjective() 格式,表示是否具有某個二元屬性。類似于 Getter,可以省略系語,只使用表語,即: 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. 情態動詞: 主-助謂-謂-(賓/表)

情態動詞也是常見的斷言形式。常見的是以下三個:

should: 查詢當前是否應該執行給定的實義動詞。

can: 查詢當前類所在狀態是否可以執行給定的實義動詞。某些情況下,也可以使用第三人稱單數作為更簡潔的代替。

must: 特殊形式。不同于前兩者,會執行給定的實義動詞。must 表示執行必須成功,否則會拋出不可恢復錯誤 (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" 的反面,表示嘗試性的執行,并且失敗不會造成嚴重后果:

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

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

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

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

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

注1: 簡單地說,靜態動詞是表示狀態的動詞,與動態動詞(Dynamic verb)表示動作對應。或言“持續性動詞”。

一階邏輯 First-order logic, Predicate Logic

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

all 表示所有對象滿足給定要求

any 表示任意對象滿足給定要求

none 表示沒有任何對象滿足給定要求

語法: <一階量詞><動詞|形容詞>

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

介詞經常與某些動詞固定搭配,因此,通??梢允÷詣釉~,而只使用介詞作為方法名稱。

to: 轉換至另一對象,等價于 convertTo。to 會產生一個全新的對象,通常不持有對原對象的引用。

as: 返回某個視圖,等價于 returnViewAs。一個“視圖(View)” 通常是對原有對象的另一角度的抽象,通常會持有對原有數據的引用,而不會產生新的數據。

of/from/with:構造新對象,等價于 createOutOf/createFrom/createWith。見下文“工廠模式”。

on: 監聽事件,等價于 actUpon。見下文“事件”。

class Foo { public List<T> toList(); // Convert to (Construct a new instance of) a new List. Creates a new list. public List<T> 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


詞匯表

下文按用途歸類了常見動詞和名詞,并對同義近義詞進行了辨析。

類/名詞類繼承

Abstract/Base
Impl
Default

Java

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

Abstract class: 通常會添加 Abstract/Base 前綴以明確屬性。這是因為 Interface/Impl 是常見的,Class 也是常見的,但是基于繼承的抽象類是特殊的、應該予以避免的,應該給予特殊標記。

Implementation:

如果不實現接口,通常不需要任何特殊修飾符。

如果以 "is-a" 的方式實現了某個接口,那么通常實現會以 {InterfaceName}Impl 的方式命名。

如果一個類實現了多個接口,那么通常這個類應該是以作為主要目標的接口為基礎命名。例如 class BazelBuilderImpl implements BazelBuilder, AutoClosable, Serializable。

如果一個接口有多個實現,通常會基于它們本身的實現特點命名,并且使用 Impl 后綴。Default 通常用來命名默認的實現,即其它實現如果不存在會 fallback 到的實現。如果所有的實現都是平等地位,那么不要使用 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 是通過抽象類不存在基類成員變量模擬。通常接口所有的成員函數都是公開純虛函數。

使用 Impl 表示實現。

Abstract class: 通常會添加 Base 后綴以明確屬性。這是因為 Interface/Impl 是常見的,Class 也是常見的,但是基于繼承的抽象類是特殊的、應該予以避免的,應該給予特殊標記。

// 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 從來不是用來做 "is-a" 定義的。Go 的 interface 契約通過 duck typing 滿足。interface 應該在消費方定義,而非提供方。因此, interface Foo/struct FooImpl 不應該出現。

Go 也并沒有抽象類,雖然可以將一個結構體嵌入到另一個結構體中。所以 Base/Abstract 也極少出現。

原則上,Go 的類關系更為簡化,命名更強調意義優先,因此在命名時避免使用修飾性前后綴。

異常

Exception/Error

Java

所有的異常擴展應該以 Exception 為后綴。所有的錯誤應該以 Error 為后綴。 對異常和錯誤的區別請參見 https://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html

public class IllegalArgumentException; public class OutOfMemoryError;C++

C++ 的 exception 通常指語法特性,與 throw 對應,而 error 可以用來表示具體的異常錯誤。

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

所有的錯誤都是 error。因此,所有自定義的對 error 的擴展都以 Error 作為后綴。

os.PathError測試

Test

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

模塊

Module/Component

Module/Component 通常會在框架中使用。不同的語言/框架對于 Module/Component 有不同的定義。 在非框架代碼中應該減少使用 Module/Componenet 等命名,因為可能與已有框架沖突,并且 Module/Componenet 過于寬泛而缺少實質意義。

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

總結,Module/Component 命名應該注意:

只應該在框架代碼中使用。

Module/Component 應該在框架的語境中給出確切的定義。

服務

Service

Service 通常用于作為 C-S 架構下的服務提供者的名稱的后綴,如:

HelloService

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

BackgroundService // Android 后臺服務 ExecutorService // 線程池執行服務,也是服務

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

容器

Holder/Container/Wrapper

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

添加某些語境下的元數據(Decorator 模式)

做適配以在另一個環境中使用(Adapter 模式)

通常的結構如下:

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

這三個詞沒有區別。在同一個項目中,應該保持一致。

控制類

Manager/Controller

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

這兩個詞有以下幾個常見場景:

Manager 管理資源,如 DownloadManager, PackageManager。

Manager 通常特指管理對象的生命周期,從創建到銷毀。

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

即使如此,Manager/Controller 是無意義詞匯,出現時充滿了可疑的味道 -- 類應該管理它們自己。 Controller/Manager 多了一層抽象,而這很可能是多余的。 認真考慮是否需要 Manager/Controller。

輔助類

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

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

Java

將與某個類型相關的輔助方法放在一個類中,并且以復數形式命名輔助類。如:

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

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

C++

使用全局方法。如果擔心命名污染,將之置入更細粒度的 namespace。

Go

使用全局方法。

函數式

Function/Predicate/Callback

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

Java

熟悉 Java 8 開始提供的函數式語義。如果可以使用標準庫的語義,不要自己創建名詞。 注意 Function 指單入參、單出參的函數。如果是多入參的函數,直接定義 FunctionalInterface 并且按用途命名,例如 OnClickListener.listen(Context, ClickEvent)。

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

first-class 函數的標準類型為 std::function。

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

Go

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

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

在同一個項目中,應該保持一致。

作為參數時,函數不會特意標明 Fn,而是遵從普通的參數命名方式:

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

換言之,函數是一等公民。

設計模式類

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

創建式

Factory: 工廠模式。通常,使用工廠方法即可,不需要一個額外的工廠類。只有當工廠特別復雜,或者工廠有狀態時再考慮使用工廠類。

Builder:構建者模式。一般來說 Builder 都是作為 inner class,如

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

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

在現代,Adapter 更多地被作為 數據類 -> 數據類的轉化,如常見的 pb -> pb:

class ProtoAdapter<S, T extends Message> {}Decorator:裝飾器

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

Delegation:委派模式

GoF 中是非?;镜哪J剑河梢粋€類負責接受請求,并把請求轉發到合適的實例類中執行。

class RealPrinter {} class Printer { RealPrinter printer; }

Delegate 非常常見,也提供了兩個名字,請注意區分:

Delegate 是被委任的對象。

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

Facade: 外觀模式

GoF 中 Facade Pattern 通常是指為子系統提供一個更高層的統一界面,屏蔽子系統的獨有的細節。 在現實中,Facade 通常用來為非常復雜的類/系統定義一個較為簡化的界面,如:

// 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 的主要區別在于 Facade 的主要目的是為了簡化,或者說更高層次的抽象,并且通常簡化的界面不服務于專門的對接類。 Adapter 通常是為了一個特定的對接類實現。

注意 Facade 命名通常可以省略。僅當你的意圖是明確告知用戶這是關于某個類的外觀時使用。

Proxy:代理模式

GoF 中代理模式用來添加一層抽象,以對實際類進行控制,并添加某些行為(如 lazy/memoized),或是隱藏某些信息(例如可見性或是執行遠程調用)。

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

注意 Proxy 作為代碼模式時,通常不應該出現在命名之中。使用具體的 Proxy 的目的作為命名,如 LazyCar 或是 TracedRuntime,而非 CarProxy 或是 RuntimeProxy。

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

Iterator: 迭代器

時至今日仍然最常見的模式之一。Interator 有以下兩個術語,不要混淆:

Iterable: 迭代容器

Iterator: 迭代器

Visitor: 訪問者模式

訪問者模式用來遍歷一個結構內的多個對象。對象提供 accept(Visitor) 方法,調用 Visitor.visit 方法。

即使如此,Visitor 應該并不常見,因為它可以簡單地被函數式的寫法替換:

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

Observer/Publisher/Subscriber/Producer/Consumer

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

PubSub 與 Producer/Consumer 的區別是:

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

Producer/Consumer: 在整個流系統中,專指 1:1 生產/消費。Producer/Consumer 也是 Pub/Sub 系統的組件(廣播也是一對一廣播的)。

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

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

Notification: 消息本身

Sender:消息發送者/注冊

Receiver: 消息接收者

關于命名參見 [事件] 部分。

Strategy:策略模式

Strategy/Policy

策略模式在 GoF 中用以指定某個行為在不同場景下的不同實現,作為“策略”。

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

在“策略”這個語義中,Strategy/Policy 沒有區別。在同一個項目中,應該保持一致

Command:命令模式

命令模式在 GoF 中以類開代表實際行動,將行動封裝,以支持重復、取消等操作。

Command 在現代編程實踐中可以通過簡單的函數式方案替換,如:

Function<T, T> command; // Java std::function<const T&(const T&)> command; // C++ type Command func(T*) T* // Go

現代通常使用 Command 表示實際的“命令”,而不采取 Command 模式的含義。

Null Object 模式

Tombstone

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

通常會有一個專門的對象表示 Null Object??梢越栌?Tombstone 表示 Null Object。

Object Pool 對象池模式

Pool

對象池模式不在 GoF 當中。它是將一系列昂貴的對象創建好放在一個池子中,并使用戶通過向池子申請對象,而不再自己手動地創建/銷毀對象。最著名的池化的例子是線程池,即 ThreadPool。

Pool 通常用來表示對象池子,例如 ThreadPool, ConnectionPool。

Arena

Arena 是指 Region-based memory management,是指一片連續的內存空間,用戶在其中分配創建對象,管理內存。

前/后綴并發/異步

Concurrent
Synchronized
Async

有時候我們需要特別標明一個類是線程安全的。通常這是特意為了與另一個線程不安全的實現做區分。典型的例子是 HashMap 和 ConcurrentHashMap。如果一個類只是單純是線程安全的,那么通常不需要在名字里特意說明,在文檔里說明即可。

例如:

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

Concurrent 通常是用來說明該類是線程安全的前綴。Synchronized 是另一個在 Java 中可用的標明類是線程安全的前綴。但是,這通常說明這個類是通過 synchronized 機制來保證線程安全的,所以只在 Java 中使用。

另一個常見的場景是同一個方法有兩種實現:同步阻塞和異步不阻塞的。在這種情況下,通常會命名異常不阻塞的方法為 {synchronizedMethod}Async,例如:

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

如果一個異步的方法并沒有對應的同步方法,通常不需要加 Async 后綴。

在 Go 中,如果一個方法是意圖在其它協程中異步執行,不需要加 Async 后綴。

緩存/惰性

Cached/Buffered
Lazy
Memoized

名詞辨析:

Cached 表示獲取的對象會被緩存,保留一段時間,在緩存期間不會重新獲取。

Buffered 與 Cached 同義。

Lazy 表示這個對象會被在第一次調用時創建,之后一直保留

Memoized 通常表示執行結果會在第一次計算后被記憶,之后不會再重復計算

注意 Buffered 不應該與 Buffer 混淆。 Buffer 作為名詞專指“緩沖區”。
注意 Cached 不應該與 Cache 混淆。 Cache 作為名詞專指“緩存”。

Cached/Buffered 應該在項目中是一致的。 Cached/Lazy/Memoized 取決于對象是被獲取的,還是創建的,還是計算獲得的。

不可變性

Mutable
Immutable

Mutable 顯式地聲明一個類是可變的,Immutable 顯式地聲明一個類是不可變的。 通常情況下,類似于并發安全性,是否可變應該在類文檔中說明,而不應該在類名中,顯得臃腫。只有當一個類同時有可變/不可變版本時,可以使用 Class/ImmutableClass。

存儲/數據/處理數據類

Object
Data
Value
Record
Entity
Instance

上面幾個都可以用來表示一個表示數據的類。但是這些詞是典型的“無意義詞匯”,如果把它們從名字中刪除,仍然可以表示完整意義,那么應該刪掉。

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

表示“統計數據”。 Stats 是公認的可用的 Statistics 的縮寫,Java/C++/Go 均可。

存儲

Storage
Database
Store
DB

Cache

Verbs:
- save/store/put

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

項目內應該選擇一個術語保持一致。

save/store/put 在數據庫類中是同義詞。同一個項目中應該保持一致。

數據格式

Schema
Index
Format
Pattern

名詞辨析:

Schema 借用數據庫的概念,指數據的結構模式。

Index 借用數據庫的概念,專指數據的索引。

Format/Pattern 通常是泛指的“模式/格式”概念。實際出現時,Format/Pattern 往往和字符串相關,如 Java 使用 Pattern 表示正則表達式。在非公共代碼中,Format/Pattern 通常過于寬泛,應該考慮選用更細化的名詞。

哈希

Hash/Digest/Fingerprint/Checksum

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

Hash(Data) = Digest

Checksum 出自編碼論,可以理解為一種特殊的哈希函數,用來檢查文件的完整性。換言之,如果一份數據出現了任何變動,Checksum 應該期待會改變。(但是 Checksum 實際上并不要求唯一性,見 Fingerpint)

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

所以 Checksum 只是作為文件變更校驗,而 Fingerprint 可以作為數據的唯一標記。

在命名時,優先使用 Fingerprint/Checksum,或其它特定指定用途的術語。當以上均不合適時,回退到更泛化的概念,即 Digest。

流式編程

Stream
Source/Sink
Pipe/Piped

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

Stream 表示流式

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

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

原則是:選擇你的團隊里最常使用的流式處理系統所使用的詞匯表。

狀態

State/Status

很諷刺地,很多人認為這兩個詞有區別,但是他們認為區別的點各不相同。見下文參考文獻。筆者傾向于認為它們其實沒什么本質區別。

鼓勵使用 State 表示狀態。因為 HTTP 和 RPC 已經占用了 Status 這個術語,為了避免誤解,使用 State 表示自定義狀態。

參考:

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

鼓勵使用 State: https://google.aip.dev/216

計數

Num/Count/Size/Length/Capacity

Num/Count 表示數量,但不強制是某個 collection 的長度。推薦使用 Count。

Size/Length 表示容器1的當前容量。遵循語言慣例,通常使用 Size。

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

方法/動詞

動詞是句子的精髓。選擇精準的動詞是代碼可讀性的關鍵。 本章對動作做了分類,并且提供了部分備選。如果動詞有反義詞,它們會被聚合在一個詞條中。 本章的詞匯有兩種:

動詞

以執行一個動作為主的某些行為類,即 -er 模式,如 Producer。 -able 模式,如 Writable 是類似的,因為不再贅述。

創建/提供

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

Verbs:

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

get/peek

make/generate

創建/提供名詞辨析:

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

它們對應的動詞是工廠方法的常見命名,即:

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

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

Generator 通常專指某些需要經過計算的、特殊的對象,例如 ID。

對應的動詞是 generate,強調全新生成。

Constructor 通常是指一個復雜對象的構建器,不是指構造函數。它通常用于比 Builder 更復雜的構建 (Builder 通常不會附帶邏輯)。

Factory 是專職的工廠類。當工廠方法較為復雜,需要抽出,或者有狀態的工廠時使用。

對應上文工廠方法的常見命名。

Builder 見前文 [Builder 構建者模式]

動詞辨析:

get vs peek

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

peek 也是“獲取”對象,但是這里強調的是對原對象無副作用。在函數式編程中會用來作為不破壞數據流的旁路操作。

create vs make vs generate

同義詞,表創建。推薦在項目中保持一致。

消費

Consumer.accept/consume/poll

消費名詞:

Consumer 是最常見的“消費者”,通常表示某個數據流的終端消費方。

對應的動詞是 accept 或是 consume,遵守所使用消息隊列框架的命名風格,否則,項目內保持一致

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

注意區分輪 xun 中文的歧義:

poll 翻譯為輪詢,指一個客戶端間斷性地向外進行獲取數據的行為策略。

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

注意輪詢是 poll 不是 pull,雖然后者直覺上是“拉取,但 poll 強制間斷性地主動地采樣/獲取數據,是正式的計算機術語。

查找

Verbs:
- find/search/query

同義詞。推薦在項目中保持一致。 具體地,這幾個詞實際上有細微的不一致。通常情況下它們可能有以下區分:

find 查詢單個結果,search 查詢一列符合條件的結果

find 表示“找到”,即終態,search 表“搜索”,即行為。

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

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

拷貝

Verbs:
- copy/clone

同義詞。遵循語言慣例。

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

添加

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

動詞辨析:

append 專指添加到列表末。

insert 強調可以插入到列表的任何位置。

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

put 通常用于列表之外的添加場景。如 map, iostream。

push 僅用于某些數據結構,如棧。

對于自定義的可添加 api,應該貼近底層的標準庫的數據結構所使用的動詞。作為泛用的添加,使用 add。

更新

Verbs:
- set/update/edit

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

刪除

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

動詞辨析:

remove/delete/erase 是同義詞。嚴格來說,remove 指移除,即暫時從容器中取出放置在一邊,delete/erase 指刪除,即將對象整個清除。但是在日常編程中不需要做這種區分。通常,代碼 API 中使用 remove(或依語言慣例),RPC API 中使用 delete 作為標準方法。

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

pop 只在棧/隊列等數據結構中使用,通常會返回對象并從數據結構中移除。

編排

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

Scheduler/Dispatcher 均借用于操作系統概念。

名詞辨析:

Scheduler: 通常 Scheduler 用于分發中長期 Job。換言之,Scheduler 通常涉及到資源分配。

對應動詞為 schedule

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

對應動詞為 dispatch

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

對應動詞為 coordinate

Orchstrator:執行比簡單的分發,即 scheduler/dispatcher 更復雜的任務/流程編排。通常,這些任務有前后依賴關系,會形成一個有向無環圖。

對應動詞為 orchestrate。 Orchestrator 的輸出通常是工作流,即 Workflow。

Delegator: 專指委任。雖然形式類似,但是 Delegator 強調單純的委任。參見 [Delegation: 委派模式]。

對應動詞為 delegate,但通常不會使用。

檢查/驗證

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

Validation/Verification 的明確區分來自于軟件測試。

Validation 通常指對產品符合用戶/顧客預期的驗證。外部用戶會參與。

Verification 通常指產品合規/符合給定規范。通常是內部流程。

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

Validator 用于輸入檢測

Verifier 用于運行的不變量檢測

具體地:

check 用于輸入校驗。 validate 用于復雜的輸入校驗。

assert/verify 用于不變量驗證,尤其在單元測試中

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 }執行/操作

Task/Job/Runnable

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

名詞辨析:

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

Task 粒度比 Job 更細

Job 通常是耗時更長的任務

但是,推薦不做區分,認為它們都是同義詞。使用 Task 或者 Job 作為類名。

名詞辨析: Processor/Executor/Operator 是從計算機架構借用的概念。

Executor: 常見。通常對應 Job/Task

對應 execute。 exec 是可接受的公認的縮寫。

Operator: 通常對應某些具體的操作類。更多使用本義,即操作符。

對應 do。

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

對應 process。

Runner: 通常對應 Runnable

對應 run

但是,推薦不做區分,認為它們都是同義詞。日常編程中,使用 Executor 作為 Job 執行器。

開啟 vs 關閉

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

二元狀態的開啟關閉。上述全是同義詞。

在項目中保持統一。注意比起 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 中讀取。

對應動詞 read

Fetcher 通常是從遠端拉取數據

對應動詞 fetch

Downloader 類似于 Fetcher,但是通常內容是文件等 blob,而非結構化數據

對應動詞 download

Prefetcher 強調預熱拉取,通常是拉取到緩存中。

對應動詞 prefetch 或是簡單的 fetch

Loader 是泛用詞匯,表示廣義的“加載”。通常可以表示上述的任何一種。

對應動詞 load

Retrieve 是 Fetch 的同義詞。

具體地,fetch/load 是有語義的細微差別。但是,不需要做具體的細分。

優先使用 read/fetch/download,當均不合適時,回退到 load。

序列化 vs 反序列化

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

動詞辨析:

pack 指打包,將數據打包為一個不可拆分的(通常是不透明的)對象

serialize 指序列化,將數據轉換為可以被存儲/傳輸的(通常是二進制)格式。

marshal 強調意圖 -- 將一個對象從程序 A 轉移到程序 B 中。

但是,不需要做這個區分。可以認為它們都是同義詞。按語言慣例使用:

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

轉換

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

可以認為它們都是同義詞。在項目中應該保持一致。 嚴格來說,Mapper 更多指同一數據的兩種形式的雙向映射,例如數據庫存儲和運行時對象。 在 Applier/Converter/Transformer 中,Applier 最為常見,因為源自設計模式。 Mapper 在框架中較常見。

匹配

Filter/Matcher
- Verb: query/filter/match

可以認為它們都是同義詞。 在項目中應該保持一致。

事件

Event

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

在 [Observer Pattner: 觀察者模式] 中已經解釋。

Observer 是正宗的觀察者

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

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

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

Producer/Consumer: 在整個流系統中,專指 1:1 生產/消費。

見 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

通常,一個程序中有 20% 的代碼在處理字符串。所以與文本相關的內容非常多。這里沒有列出全部。

“模板”名詞解析:

Regex 專指正則表達式。另一個常見的縮寫是 Regexp。應該與語言保持一致。C++ 使用 Regex。Go 使用 Regexp。

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

匹配對應動詞為 expand/match/match

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

編譯使用 compile

對應動詞為 match/split

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

對應動詞為 expand

“修剪”動名詞解析:

Pruner.prune: 指清理掉過時的、不應存在的內容

Stripper.strip: 指清理掉多余的、過度生長的內容

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

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

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

Prune 可能會進行其它的裁剪

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

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

“格式化”動名詞解析:

Formatter.format 是將對象進行格式化。通用名詞。

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

“解析”動名詞解析:

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

Parser.parse 類似于 parse,但強調將文本進行句法解析,形成格式化的中間層表示。借用了編譯器術語。

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

生命周期

Lifecycle

Initializer/Finalizer

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

生命周期解析: 一個對象的生命周期,稱為 Lifecycle,通常有以下流程:

創建。通常由語言特性支持,不屬于生命周期管理范圍。

初始化:init。init 是 initialize 的全稱,通常用來初始化一個類到可用狀態。應該盡量避免創建之外的額外初始化步驟,一個對象應該盡可能在創建后就處于已初始化狀態。額外的狀態會讓這個類更難正確使用。

setup/prepare 是 init 的同義詞。應該在項目內統一,推薦為 init。setUp 通常在測試中使用,用于作為每個測試用例設計的前置步驟。

init vs prepare: 具體地細分,init 的語義通常指“在類生命周期層面處在正常可執行狀態”,prepare 的語義通常指“在業務層面做好準備”

開始: start/begin。通常用于這個對象正式開始正常工作,即切換到 running 狀態。在切換到其它狀態之前這個類會一直保持在 running 狀態。

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

暫停: pause。pause 應該使得類暫停運行,從 running 狀態切換到 paused 狀態。這段時間這個類應該不再工作。

恢復:resume。resume 與 pause 是成對的。 resume 會恢復 paused 到 running 狀態。通常,pause/resume 可以無限次隨時切換。

停止:stop/end/terminate/halt。停止類運行,與 start 對應。通常情況下,一個類 stop 意味著不會再重新啟動。通常情況下,停止狀態的類應該拒絕任何請求。

stop/end/terminate/halt 是同義詞。不要做區分處理,在項目中保持一致。

銷毀:destroy/release/shutdown/teardown/exit。徹底銷毀對象。此后,對象不再處于可用狀態。

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

destroy 強調銷毀對象。

release 強調釋放資源。

teardown 通常與 setup 對應。

exit 通常指程序退出。

shutdown 是通用“徹底關閉”的動詞。當 destroy/release 不合適時,回退到 shutdown。

使用 gracefullyShutdown 表示優雅關閉。這通常意味著是前幾個行為的集合:停止服務、釋放資源、刷新緩沖區、銷毀對象。

計算

Calculator

Verb:
- compute/calculate/calc

使用 Calculator 而非 Computer 表示某個運算的執行器。Computer 雖然也是“計算器”,但是在代碼語境下有歧義。

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

元數據(配置/環境/...)

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

Context/Environment

Info/Metadata/Manifest/Version

配置名詞解析: 這個有類似的名詞辨析,但是它們在編程時通常認為都是“配置”的同義詞。它們還會出現在用戶界面,尤其是 Settings/Options/Preferences。

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

使用 Property 表示單個屬性, 而且通常是 k-v 結構。換言之,Option/Config 通常由多個 Properties 組織。只有當 Property 是動態屬性時,才定義特殊的 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; }

參數解析:

Parameter:通常表示在接口處定義的參數

Argument:指實際傳入接口的參數

例如:

func foo(param string) foo(arg)

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

上下文名詞辨析:

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

Environment 指環境。這個名詞從系統環境變量而來。通常,這表示在程序啟動后保持穩定的環境數據,不隨所執行的內容(如 rpc 請求)變化而變化。

元數據辨析:

Info 泛指信息。而元數據相當于特定的“關于數據”的信息。

Metadata 標準用語,專指元數據。避免使用 Info 代表元數據。

Manifest 專指文件清單,描述一個模塊中的文件/功能/其它組成結構的列表。Manifest 來自于貨運術語,Ship Manifest 用以列出所有的船員和船隊所有的船只。

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

作者:piikee | 分類:八字起名 | 瀏覽:45 | 評論:0
主站蜘蛛池模板: 日韩精品无码免费专网站| 成人欧美日韩| 8090成人午夜精品| 77777亚洲午夜久久多人| 亚洲色图欧美一区| 黄网站欧美内射| 2020极品精品国产 | 国产成人综合久久精品下载| 国产99久久亚洲综合精品西瓜tv| 高清不卡一区二区三区香蕉| 真人高潮娇喘嗯啊在线观看| 欧美日本在线观看| 92精品国产自产在线观看| 欧美日韩一区二区在线免费观看| 免费亚洲成人| 日韩精品中文字幕一区三区| 久草视频中文| 亚洲一道AV无码午夜福利| 久久久精品国产SM调教网站| 国产手机在线ΑⅤ片无码观看| 老色鬼欧美精品| 一级一级一片免费| 91蜜芽尤物福利在线观看| 国产成人精品亚洲77美色| 好吊色国产欧美日韩免费观看| 激情综合网激情综合| 久久国产免费观看| 日韩亚洲综合在线| 国产日产欧美精品| 亚洲视频一区| 欧美三级视频网站| 婷婷综合色| 2020极品精品国产| 黄色网站在线观看无码| 亚洲成人在线网| 亚洲网综合| 岛国精品一区免费视频在线观看| 996免费视频国产在线播放| 岛国精品一区免费视频在线观看 | 在线日韩日本国产亚洲| 午夜性爽视频男人的天堂| 欧美激情第一欧美在线| 青青草91视频| 欧美色综合网站| 中日韩一区二区三区中文免费视频| 国产成人8x视频一区二区| 国产成人高清在线精品| 欧美在线视频不卡第一页| 亚洲水蜜桃久久综合网站| 亚洲第一成年免费网站| 日本国产在线| 一级毛片在线播放免费观看| 国产福利小视频高清在线观看| 中文字幕精品一区二区三区视频| 久久国产精品77777| 欧美成人精品一级在线观看| 国产视频久久久久| 日韩 欧美 小说 综合网 另类 | 美女啪啪无遮挡| 女人一级毛片| 五月激情婷婷综合| 性欧美精品xxxx| 欧美成人手机在线视频| 免费啪啪网址| 成人国产三级在线播放| 欧美日在线观看| 91在线精品免费免费播放| 在线看免费无码av天堂的| 久青草免费视频| 国产成年女人特黄特色毛片免| 五月天久久综合国产一区二区| 国产成人亚洲无码淙合青草| 久久6免费视频| 一本大道无码日韩精品影视| 美女裸体18禁网站| 四虎在线高清无码| 欧美一级在线| 亚洲系列无码专区偷窥无码| 国产三级国产精品国产普男人| 国产成在线观看免费视频| 国产精品一线天| 国产成人三级|