日常編碼中,代碼的命名是個大的學問。能快速的看懂開源軟件的代碼結(jié)構(gòu)和意圖,也是一項必備的能力。那它們有什么規(guī)律呢?
Java項目的代碼結(jié)構(gòu),能夠體現(xiàn)它的設計理念。Java采用長命名的方式來規(guī)范類的命名,能夠自己表達它的主要意圖。配合高級的IDE,可以減少編碼人員的記憶負擔,靠模糊的匹配就能找到自己所需要的資源。
為了讓大家更好的理解命名的套路,我借鑒了最流行的Java接開源軟件(spring系列,netty,libgdx,guava,logback等等),總結(jié)了10類常見的類命名。大多數(shù)是以后綴形式存在的,也有不少可以組合使用,用來表達多重的意義。
這些單詞很簡單,但可以讓你的類命名看起來更加清爽和專業(yè)。接下來,我將帶大家游覽一遍。為了方便理解,每種類型,我都配備了相應的 示例。
寫代碼,少不了對統(tǒng)一資源的管理,清晰的啟動過程可以有效的組織代碼。為了讓程序運行起來,少不了各種資源的注冊、調(diào)度,少不了公共集合資源的管理。
一般作為程序啟動器使用,或者作為啟動器的基類。通俗來說,可以認為是main函數(shù)的入口。
AbstractBootstrap
ServerBootstrap
MacosXApplicationStarter
DNSTaskStarter
某一類功能的處理器,用來表示某個處理過程,是一系列代碼片段的集合。如果你不知道一些順序類的代碼怎么命名,就可以使用它,顯得高大上一些。
CompoundProcessor
BinaryComparisonProcessor
DefaultDefaultValueProcessor
對有生命狀態(tài)的對象進行管理,通常作為某一類資源的管理入口。
AccountManager
DevicePolicyManager
TransactionManager
表示持有某個或者某類對象的引用,并可以對其進行統(tǒng)一管理。多見于不好回收的內(nèi)存統(tǒng)一處理,或者一些全局集合容器的緩存。
QueryHolder
InstructionHolder
ViewHolder
毫無疑問,工廠模式的命名,耳熟能詳。尤其是Spring中,多不勝數(shù)。
SessionFactory
ScriptEngineFactory
LiveCaptureFactory
Provider = Strategy + Factory Method。它更高級一些,把策略模式和方法工廠揉在了一塊,讓人用起來很順手。Provider一般是接口或者抽象類,以便能夠完成子實現(xiàn)。
AccountFeatureProvider
ApplicationFeatureProviderImpl
CollatorProvider
注冊并管理一系列資源。
ImportServiceRegistrar
IKryoRegistrar
PipelineOptionsRegistrar
一般是核心模塊,用來處理一類功能。引擎是個非常高級的名詞,一般的類是沒有資格用它的。
ScriptEngine
DataQLScriptEngine
C2DEngine
某個服務。太簡單,不忍舉例。范圍太廣,不要濫用哦。
IntegratorServiceImpl
ISelectionService
PersistenceService
某個任務。通常是個runnable
WorkflowTask
FutureTask
ForkJoinTask
為了完成一些統(tǒng)計類或者全局類的功能,有些參數(shù)需要一傳到底。傳播類的對象就可以通過統(tǒng)一封裝的方式進行傳遞,并在合適的地方進行拷貝或者更新。
如果你的程序執(zhí)行,有一些變量,需要從函數(shù)執(zhí)行的入口開始,一直傳到大量子函數(shù)執(zhí)行完畢之后。這些變量或者集合,如果以參數(shù)的形式傳遞,將會讓代碼變得冗長無比。這個時候,你就可以把變量統(tǒng)一塞到Context里面,以單個對象的形式進行傳遞。
在Java中,由于ThreadLocal的存在,Context甚至可以不用在參數(shù)之間進行傳遞。
AppContext
ServletContext
ApplicationContext
傳播,繁殖。用來將context中傳遞的值進行復制,添加,清除,重置,檢索,恢復等動作。通常,它會提供一個叫做propagate的方法,實現(xiàn)真正的變量管理。
TextMapPropagator
FilePropagator
TransactionPropagator
使用多核可以增加程序運行的效率,不可避免的引入異步化。我們需要有一定的手段,獲取異步任務執(zhí)行的結(jié)果,對任務執(zhí)行過程中的關(guān)鍵點進行檢查?;卣{(diào)類API可以通過監(jiān)聽、通知等形式,獲取這些事件。
callback通常是一個接口,用于響應某類消息,進行后續(xù)處理;Handler通常表示持有真正消息處理邏輯的對象,它是有狀態(tài)的;tigger觸發(fā)器代表某類事件的處理,屬于Handler,通常不會出現(xiàn)在類的命名中;Listener的應用更加局限,通常在觀察者模式中用來表示特定的含義。
ChannelHandler
SuccessCallback
CronTrigger
EventListener
Aware就是感知的意思,一般以該單詞結(jié)尾的類,都實現(xiàn)了Aware接口。拿spring來說,Aware 的目的是為了讓bean獲取spring容器的服務。具體回調(diào)方法由子類實現(xiàn),比如ApplicationContextAware。它有點回調(diào)的意思。
ApplicationContextAware
ApplicationStartupAware
ApplicationEventPublisherAware
現(xiàn)在的程序都比較復雜,運行狀態(tài)監(jiān)控已經(jīng)成為居家必備之良品。監(jiān)控數(shù)據(jù)的收集往往需要侵入到程序的邊邊角角,如何有效的與正常業(yè)務進行區(qū)分,是非常有必要的。
表示監(jiān)控數(shù)據(jù)。不要用Monitor了,比較丑。
TimelineMetric
HistogramMetric
Metric
估計,統(tǒng)計。用于計算某一類統(tǒng)計數(shù)值的計算器。
ConditionalDensityEstimator
FixedFrameRateEstimator
NestableLoadProfileEstimator
累加器的意思。用來緩存累加的中間計算結(jié)果,并提供讀取通道。
AbstractAccumulator
StatsAccumulator
TopFrequencyAccumulator
一般用于記錄日志或者監(jiān)控值,通常用于apm中。
VelocityTracker
RocketTracker
MediaTracker
如果你的應用用到了自定義的內(nèi)存管理,那么下面這些名詞是繞不開的。比如Netty,就實現(xiàn)了自己的內(nèi)存管理機制。
與存儲相關(guān),通常表示內(nèi)存分配器或者管理器。如果你得程序需要申請有規(guī)律得大塊內(nèi)存,allocator是你得不二選擇。
AbstractByteBufAllocator
ArrayAllocator
RecyclingIntBlockAllocator
表示一塊內(nèi)存。如果你想要對一類存儲資源進行抽象,并統(tǒng)一管理,可以采用它。
EncryptedChunk
ChunkFactory
MultiChunk
英文是舞臺、競技場的意思。由于Linux把它用在內(nèi)存管理上發(fā)揚光大,它普遍用于各種存儲資源的申請、釋放與管理。為不同規(guī)格的存儲chunk提供舞臺,好像也是非常形象的表示。
關(guān)鍵是,這個詞很美,作為后綴讓類名顯得很漂亮。
BookingArena
StandaloneArena
PoolArena
表示池子。內(nèi)存池,線程池,連接池,池池可用。
ConnectionPool
ObjectPool
MemoryPool
程序收到的事件和信息是非常多的,有些是合法的,有些需要過濾扔掉。根據(jù)不同的使用范圍和功能性差別,過濾操作也有多種形式。你會在框架類代碼中發(fā)現(xiàn)大量這樣的名詞。
一般用在責任鏈模式中。Netty,Spring MVC,Tomcat等都有大量應用。通過將某個處理過程加入到責任鏈的某個位置中,就可以接收前面處理過程的結(jié)果,強制添加或者改變某些功能。就像Linux的管道操作一樣,最終構(gòu)造出想要的結(jié)果。
Pipeline
ChildPipeline
DefaultResourceTransformerChain
FilterChain
過濾器,用來篩選某些滿足條件的數(shù)據(jù)集,或者在滿足某些條件的時候執(zhí)行一部分邏輯。如果和責任鏈連接起來,則通常能夠?qū)崿F(xiàn)多級的過濾。
FilenameFilter
AfterFirstEventTimeFilter
ScanFilter
攔截器,其實和Filter差不多。不過在Tomcat中,Interceptor可以拿到controller對象,但filter不行。攔截器是被包裹在過濾器中。
HttpRequestInterceptor
英文里是評估器的意思??捎糜谂袛嗄承l件是否成立,一般內(nèi)部方法evaluate
會返回bool類型。比如你傳遞進去一個非常復雜的對象,或者字符串,進行正確與否的判斷。
ScriptEvaluator
SubtractionExpressionEvaluator
StreamEvaluator
探測器。用來管理一系列探測性事件,并在發(fā)生的時候能夠進行捕獲和響應。比如Android的手勢檢測,溫度檢測等。
FileHandlerReloadingDetector
TransformGestureDetector
ScaleGestureDetector
除了基本的數(shù)據(jù)結(jié)構(gòu),如數(shù)組、鏈表、隊列、棧等,其他更高一層的常見抽象類,能夠大量減少大家的交流,并能封裝常見的變化。
這個沒啥好說的,就是緩存。大塊的緩存。常見的緩存算法有LRU、LFU、FIFO等。
LoadingCache
EhCacheCache
buffer是緩沖,不同于緩存,它一般用在數(shù)據(jù)寫入階段。
ByteBuffer
RingBuffer
DirectByteBuffer
將相似的組件進行組合,并以相同的接口或者功能進行暴露,使用者不知道這到底是一個組合體還是其他個體。
CompositeData
CompositeMap
ScrolledComposite
用來包裝某個對象,做一些額外的處理,以便增加或者去掉某些功能。
IsoBufferWrapper
ResponseWrapper
MavenWrapperDownloader
用來表示配置信息。說實話,它和Properties的區(qū)別并不大,但由于Option通常是一個類,所以功能可以擴展的更強大一些。它通常比Config的級別更小,關(guān)注的也是單個屬性的值。Param一般是作為參數(shù)存在,對象生成的速度要快一些。
SpecificationOption
SelectOption
AlarmParam
ModelParam
元組的概念。由于Java中缺乏元組結(jié)構(gòu),我們通常會自定義這樣的類。
Tuple2
Tuple3
聚合器,可以做一些聚合計算。比如分庫分表中的sum,max,min等聚合函數(shù)的匯集。
BigDecimalMaxAggregator
PipelineAggregator
TotalAggregator
迭代器。可以實現(xiàn)Java的迭代器接口,也可以有自己的迭代方式。在數(shù)據(jù)集很大的時候,需要進行深度遍歷,迭代器可以說是必備的。使用迭代器還可以在迭代過程中安全的刪除某些元素。
BreakIterator
StringCharacterIterator
某些可以批量執(zhí)行的請求或者對象。
SavedObjectBatch
BatchRequest
限流器,使用漏桶算法或者令牌桶來完成平滑的限流。
DefaultTimepointLimiter
RateLimiter
TimeBasedLimiter
設計模式是名詞的重災區(qū),這里只列出最常使用的幾個。
將抽象部分與它的實現(xiàn)部分分離,使它們都可以獨立地變化。策略模式。相同接口,不同實現(xiàn)類,同一方法結(jié)果不同,實現(xiàn)策略不同。比如一個配置文件,是放在xml里,還是放在json文件里,都可以使用不同的provider去命名。
RemoteAddressStrategy
StrategyRegistration
AppStrategy
將一個類的接口轉(zhuǎn)換為客戶希望的另一個接口,Adapter模式使得原本由于接口不兼容而不能一起工作的那些類一起工作。
不過,相對于傳統(tǒng)的適配器進行api轉(zhuǎn)接,如果你的某個Handler里面方法特別的多,可以使用Adapter實現(xiàn)一些默認的方法進行0適配。那么其他類使用的時候,只需要繼承Adapter,然后重寫他想要重寫的方法就可以了。這也是Adapter的常見用法。
ExtendedPropertiesAdapter
ArrayObjectAdapter
CardGridCursorAdapter
將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數(shù)化,對請求排隊或記錄請求日志,以及支持可撤銷的操作。
用來表示一系列動作指令,用來實現(xiàn)命令模式,封裝一系列動作或者功能。Action一般用在UI操作上,后端框架可以無差別的使用。
在DDD的概念中,CQRS的Command的C,既為Command。
DeleteAction
BoardCommand
表示一系列事件。一般的,在語義上,Action,Command等,來自于主動觸發(fā);Event來自于被動觸發(fā)。
ObservesProtectedEvent
KeyEvent
代理或者委托模式。委托模式是將一件屬于委托者做的事情,交給另外一個被委托者來處理。
LayoutlibDelegate
FragmentDelegate
將一個復雜對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。
構(gòu)建者模式的標準命名。比如StringBuilder。當然StringBuffer是個另類。這也說明了,規(guī)則是人定的,人也可以破壞。
JsonBuilder
RequestBuilder
模板方法類的命名。定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。
JDBCTemplate
代理模式。為其他對象提供一種代理以控制對這個對象的訪問。
ProxyFactory
SlowQueryProxy
寫代碼要涉及到大量的字符串解析、日期解析、對象轉(zhuǎn)換等。根據(jù)語義和使用場合的區(qū)別,它們也分為多種。
轉(zhuǎn)換和解析。一般用于不同對象之間的格式轉(zhuǎn)換,把一類對象轉(zhuǎn)換成另一類。注意它們語義上的區(qū)別,一般特別復雜的轉(zhuǎn)換或者有加載過程的需求,可以使用Resolver。
DataSetToListConverter
LayoutCommandLineConverter
InitRefResolver
MustacheViewResolver
用來表示非常復雜的解析器,比如解析DSL。
SQLParser
JSONParser
用來表示對某個對象進行特別的配置。由于這些配置過程特別的復雜,值得單獨提取出來進行自定義設置。
ContextCustomizer
DeviceFieldCustomizer
格式化類。主要用于字符串、數(shù)字或者日期的格式化處理工作。
DateFormatter
StringFormatter
網(wǎng)絡編程的同學,永遠繞不過去的幾個名詞。
通常用于網(wǎng)絡編程中的數(shù)據(jù)包。
DhcpPacket
PacketBuffer
同樣用戶網(wǎng)絡編程中,用來表示某個協(xié)議。
RedisProtocol
HttpProtocol
編碼解碼器
RedisEncoder
RedisDecoder
RedisCodec
一般用于網(wǎng)絡請求的進和出。如果你用在非網(wǎng)絡請求的方法上,會顯得很怪異。
這個就有意思多了,統(tǒng)一的Controller,Service,Repository,沒什么好說的。但你一旦用了DDD,那就得按照DDD那一套的命名來。
由于DDD不屬于通用編程范疇,它的名詞就不多做介紹了。
都表示工具類,Util一般是無狀態(tài)的,Helper以便需要創(chuàng)建實例才能使用。但是一般沒有使用Tool作為后綴的。
HttpUtil
TestKeyFieldHelper
CreationHelper
看到mode這個后綴,就能猜到這個類大概率是枚舉。它通常把常見的可能性都列到枚舉類里面,其他地方就可以引用這個Mode。
OperationMode
BridgeMode
ActionType
invoker是一類接口,通常會以反射或者觸發(fā)的方式,執(zhí)行一些具體的業(yè)務邏輯。通過抽象出invoke方法,可以在invoke執(zhí)行之前對入?yún)⑦M行記錄或者處理;在invoke執(zhí)行之后對結(jié)果和異常進行處理,是AOP中常見的操作方式。
MethodInvoker
Invoker
ConstructorInvocation
如果你的應用程序,需要經(jīng)過大量的初始化操作才能啟動,那就需要把它獨立出來,專門處理初始化動作。
MultiBackgroundInitialize
ApplicationContextInitializer
它們都是用在多線程之間的,進行數(shù)據(jù)傳遞。
Feture相當于一個占位符,代表一個操作將來的結(jié)果。一般通過get可以直接阻塞得到結(jié)果,或者讓它異步執(zhí)行然后通過callback回調(diào)結(jié)果。
但如果回調(diào)中嵌入了回調(diào)呢?如果層次很深,就是回調(diào)地獄。Java中的CompletableFuture其實就是Promise,用來解決回調(diào)地獄問題。Promise是為了讓代碼變得優(yōu)美而存在的。
根據(jù)一系列條件,獲得相應的同類資源。它比較像Factory,但只處理單項資源。
X509CertSelector
NodeSelector
用來匯報某些執(zhí)行結(jié)果。
ExtentHtmlReporter
MetricReporter
一般用于常量列表。
封裝了一系列g(shù)et和set方法的類。像lombok就有Accessors注解,生成這些方法。但Accessor類一般是要通過計算來完成get和set,而不是直接操作變量。這適合比較復雜的對象存取服務。
ComponentAccessor
StompHeaderAccessor
生成器,一般用于生成代碼,生成id等。
CodeGenerator
CipherKeyGenerator
寫代碼,看源碼,怎么少得了意會和神通?代碼要帶感,命名也風騷。命名起的好,代碼會看起來很爽,大家也都喜歡。
說不清楚的事情,給一段代碼,咱就能懂!就是這么神奇!
其實,寫專業(yè)牛b的代碼,并不需要了解太多的英文單詞,大多數(shù)時候用不著英文4級這么了不起的水平。只需要有限的單詞,就能玩出代碼界好萊塢的感覺。
看完本文之后,翻一翻開源軟件的代碼們,看看是不是這個理?
上面這些命名,高頻率存在于各種框架中。你要是搞懂了這些名詞,閱讀大部分源代碼可以說是一點障礙都沒有了。在同一個場景下,優(yōu)先使用這些名詞,已經(jīng)是大家心照不宣的規(guī)范。
有很多名詞來自于設計模式,但又在特定場合使用了比較特殊的單詞,比如Provider,大家仔細感受下其中的區(qū)別就可以了。
命名是編碼中非常重要的一環(huán),希望大家找到其中的規(guī)律,讓你的代碼功能上強大,顏值上好看;祝大家的薪資水漲船高,配得上你的這份專業(yè)和工匠精神。