banner
biuaxia

biuaxia

"万物皆有裂痕,那是光进来的地方。"
github
bilibili
tg_channel

【轉載】優秀開源軟體的類,都是怎麼命名的?

title: 【轉載】優秀開源軟體的類,都是怎麼命名的?
date: 2021-08-12 14:57:51
comment: false
toc: true
category:

  • 技巧
    tags:
  • 轉載
  • 開源
  • 軟體
  • 命名

本文轉載自:優秀開源軟體的類,都是怎麼命名的?


日常編碼中,代碼的命名是個大的學問。能快速的看懂開源軟體的代碼結構和意圖,也是一項必備的能力。那它們有什麼規律呢?

Java 專案的代碼結構,能夠體現它的設計理念。Java 採用長命名的方式來規範類的命名,能夠自己表達它的主要意圖。配合高級的 IDE,可以減少編碼人員的記憶負擔,靠模糊的匹配就能找到自己所需要的資源。

為了讓大家更好的理解命名的套路,我借鑒了最流行的 Java 接開源軟體(spring 系列,netty,libgdx,guava,logback 等等),總結了 10 類常見的類命名。大多數是以後綴形式存在的,也有不少可以組合使用,用來表達多重的意義。

image-20210810135355862.png

這些單詞很簡單,但可以讓你的類命名看起來更加清爽和專業。接下來,我將帶大家遊覽一遍。為了方便理解,每種類型,我都配備了相應的示例。

管理類命名#

寫代碼,少不了對統一資源的管理,清晰的啟動過程可以有效的組織代碼。為了讓程序運行起來,少不了各種資源的註冊、調度,少不了公共集合資源的管理。

Bootstrap,Starter#

一般作為程序啟動器使用,或者作為啟動器的基類。通俗來說,可以認為是 main 函數的入口。

AbstractBootstrap
ServerBootstrap
MacosXApplicationStarter
DNSTaskStarter

Processor#

某一類功能的處理器,用來表示某個處理過程,是一系列代碼片段的集合。如果你不知道一些順序類的代碼怎麼命名,就可以使用它,顯得高大上一些。

CompoundProcessor
BinaryComparisonProcessor
DefaultDefaultValueProcessor

Manager#

對有生命狀態的對象進行管理,通常作為某一類資源的管理入口。

AccountManager
DevicePolicyManager
TransactionManager

Holder#

表示持有某個或者某類對象的引用,並可以對其進行統一管理。多見於不好回收的內存統一處理,或者一些全局集合容器的緩存。

QueryHolder
InstructionHolder
ViewHolder

Factory#

毫無疑問,工廠模式的命名,耳熟能詳。尤其是 Spring 中,多不勝數。

SessionFactory
ScriptEngineFactory
LiveCaptureFactory

Provider#

Provider = Strategy + Factory Method。它更高級一些,把策略模式和方法工廠揉在了一塊,讓人用起來很順手。Provider 一般是接口或者抽象類,以便能夠完成子實現。

AccountFeatureProvider
ApplicationFeatureProviderImpl
CollatorProvider

Registrar#

註冊並管理一系列資源。

ImportServiceRegistrar
IKryoRegistrar
PipelineOptionsRegistrar

Engine#

一般是核心模塊,用來處理一類功能。引擎是個非常高級的名詞,一般的類是沒有資格用它的。

ScriptEngine
DataQLScriptEngine
C2DEngine

Service#

某個服務。太簡單,不忍舉例。範圍太廣,不要濫用哦。

IntegratorServiceImpl
ISelectionService
PersistenceService

Task#

某個任務。通常是個 runnable

WorkflowTask
FutureTask
ForkJoinTask

传播类命名#

为了完成一些统计类或者全局类的功能,有些参数需要一传到底。传播类的对象就可以通过统一封装的方式进行传递,并在合适的地方进行拷贝或者更新。

Context#

如果你的程序执行,有一些变量,需要从函数执行的入口开始,一直传到大量子函数执行完毕之后。这些变量或者集合,如果以参数的形式传递,将会让代码变得冗长无比。这个时候,你就可以把变量统一塞到 Context 里面,以单个对象的形式进行传递。

在 Java 中,由于 ThreadLocal 的存在,Context 甚至可以不用在参数之间进行传递。

AppContext
ServletContext
ApplicationContext

Propagator#

传播,繁殖。用来将 context 中传递的值进行复制,添加,清除,重置,检索,恢复等动作。通常,它会提供一个叫做 propagate 的方法,实现真正的变量管理。

TextMapPropagator
FilePropagator
TransactionPropagator

回调类命名#

使用多核可以增加程序运行的效率,不可避免的引入异步化。我们需要有一定的手段,获取异步任务执行的结果,对任务执行过程中的关键点进行检查。回调类 API 可以通过监听、通知等形式,获取这些事件。

Handler,Callback,Trigger,Listener#

callback 通常是一个接口,用于响应某类消息,进行后续处理;Handler 通常表示持有真正消息处理逻辑的对象,它是有状态的;tigger 触发器代表某类事件的处理,属于 Handler,通常不会出现在类的命名中;Listener 的应用更加局限,通常在观察者模式中用来表示特定的含义。

ChannelHandler
SuccessCallback
CronTrigger
EventListener

Aware#

Aware 就是感知的意思,一般以该单词结尾的类,都实现了 Aware 接口。拿 spring 来说,Aware 的目的是为了让 bean 获取 spring 容器的服务。具体回调方法由子类实现,比如 ApplicationContextAware。它有点回调的意思。

ApplicationContextAware
ApplicationStartupAware
ApplicationEventPublisherAware

监控类命名#

现在的程序都比较复杂,运行状态监控已经成为居家必备之良品。监控数据的收集往往需要侵入到程序的边边角角,如何有效的与正常业务进行区分,是非常有必要的。

Metric#

表示监控数据。不要用 Monitor 了,比较丑。

TimelineMetric
HistogramMetric
Metric

Estimator#

估计,统计。用于计算某一类统计数值的计算器。

ConditionalDensityEstimator
FixedFrameRateEstimator
NestableLoadProfileEstimator

Accumulator#

累加器的意思。用来缓存累加的中间计算结果,并提供读取通道。

AbstractAccumulator
StatsAccumulator
TopFrequencyAccumulator

Tracker#

一般用于记录日志或者监控值,通常用于 apm 中。

VelocityTracker
RocketTracker
MediaTracker

内存管理类命名#

如果你的应用用到了自定义的内存管理,那么下面这些名词是绕不开的。比如 Netty,就实现了自己的内存管理机制。

Allocator#

与存储相关,通常表示内存分配器或者管理器。如果你得程序需要申请有规律得大块内存,allocator 是你得不二选择。

AbstractByteBufAllocator
ArrayAllocator
RecyclingIntBlockAllocator

Chunk#

表示一块内存。如果你想要对一类存储资源进行抽象,并统一管理,可以采用它。

EncryptedChunk
ChunkFactory
MultiChunk

Arena#

英文是舞台、竞技场的意思。由于 Linux 把它用在内存管理上发扬光大,它普遍用于各种存储资源的申请、释放与管理。为不同规格的存储 chunk 提供舞台,好像也是非常形象的表示。

关键是,这个词很美,作为后缀让类名显得很漂亮。

BookingArena
StandaloneArena
PoolArena

Pool#

表示池子。内存池,线程池,连接池,池池可用。

ConnectionPool
ObjectPool
MemoryPool

过滤检测类命名#

程序收到的事件和信息是非常多的,有些是合法的,有些需要过滤扔掉。根据不同的使用范围和功能性差别,过滤操作也有多种形式。你会在框架类代码中发现大量这样的名词。

Pipeline,Chain#

一般用在责任链模式中。Netty,Spring MVC,Tomcat 等都有大量应用。通过将某个处理过程加入到责任链的某个位置中,就可以接收前面处理过程的结果,强制添加或者改变某些功能。就像 Linux 的管道操作一样,最终构造出想要的结果。

Pipeline
ChildPipeline
DefaultResourceTransformerChain
FilterChain

Filter#

过滤器,用来筛选某些满足条件的数据集,或者在满足某些条件的时候执行一部分逻辑。如果和责任链连接起来,则通常能够实现多级的过滤。

FilenameFilter
AfterFirstEventTimeFilter
ScanFilter

Interceptor#

拦截器,其实和 Filter 差不多。不过在 Tomcat 中,Interceptor 可以拿到 controller 对象,但 filter 不行。拦截器是被包裹在过滤器中。

HttpRequestInterceptor

Evaluator#

英文里是评估器的意思。可用于判断某些条件是否成立,一般内部方法 evaluate会返回 bool 类型。比如你传递进去一个非常复杂的对象,或者字符串,进行正确与否的判断。

ScriptEvaluator
SubtractionExpressionEvaluator
StreamEvaluator

Detector#

探测器。用来管理一系列探测性事件,并在发生的时候能够进行捕获和响应。比如 Android 的手势检测,温度检测等。

FileHandlerReloadingDetector
TransformGestureDetector 
ScaleGestureDetector

结构类命名#

除了基本的数据结构,如数组、链表、队列、栈等,其他更高一层的常见抽象类,能够大量减少大家的交流,并能封装常见的变化。

Cache#

这个没啥好说的,就是缓存。大块的缓存。常见的缓存算法有 LRU、LFU、FIFO 等。

LoadingCache
EhCacheCache

Buffer#

buffer 是缓冲,不同于缓存,它一般用在数据写入阶段。

ByteBuffer
RingBuffer
DirectByteBuffer

Composite#

将相似的组件进行组合,并以相同的接口或者功能进行暴露,使用者不知道这到底是一个组合体还是其他个体。

CompositeData
CompositeMap
ScrolledComposite

Wrapper#

用来包装某个对象,做一些额外的处理,以便增加或者去掉某些功能。

IsoBufferWrapper
ResponseWrapper
MavenWrapperDownloader 

Option, Param,Attribute#

用来表示配置信息。說實話,它和 Properties 的區別並不大,但由於 Option 通常是一個類,所以功能可以擴展的更強大一些。它通常比 Config 的級別更小,關注的也是單個屬性的值。Param 一般是作為參數存在,對象生成的速度要快一些。

SpecificationOption
SelectOption
AlarmParam
ModelParam

Tuple#

元組的概念。由於 Java 中缺乏元組結構,我們通常會自定義這樣的類。

Tuple2
Tuple3

Aggregator#

聚合器,可以做一些聚合計算。比如分庫分表中的 sum,max,min 等聚合函數的彙集。

BigDecimalMaxAggregator
PipelineAggregator
TotalAggregator

Iterator#

迭代器。可以實現 Java 的迭代器接口,也可以有自己的迭代方式。在數據集很大的時候,需要進行深度遍歷,迭代器可以說是必備的。使用迭代器還可以在迭代過程中安全的刪除某些元素。

BreakIterator
StringCharacterIterator

Batch#

某些可以批量執行的請求或者對象。

SavedObjectBatch
BatchRequest

Limiter#

限流器,使用漏桶算法或者令牌桶來完成平滑的限流。

DefaultTimepointLimiter
RateLimiter
TimeBasedLimiter

常見設計模式命名#

設計模式是名詞的重災區,這裡只列出最常使用的幾個。

Strategy#

將抽象部分與它的實現部分分離,使它們都可以獨立地變化。策略模式。相同接口,不同實現類,同一方法結果不同,實現策略不同。比如一個配置文件,是放在 xml 裡,還是放在 json 文件裡,都可以使用不同的 provider 去命名。

RemoteAddressStrategy
StrategyRegistration
AppStrategy

Adapter#

將一個類的接口轉換為客戶希望的另一個接口,Adapter 模式使得原本由於接口不兼容而不能一起工作的那些類一起工作。

不過,相對於傳統的適配器進行 api 轉接,如果你的某個 Handler 裡面方法特別的多,可以使用 Adapter 實現一些默認的方法進行 0 適配。那么其他類使用的時候,只需要繼承 Adapter,然後重寫他想要重寫的方法就可以了。這也是 Adapter 的常見用法。

ExtendedPropertiesAdapter
ArrayObjectAdapter
CardGridCursorAdapter

Action,Command#

將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化,對請求排隊或記錄請求日誌,以及支持可撤銷的操作。

用來表示一系列動作指令,用來實現命令模式,封裝一系列動作或者功能。Action 一般用在 UI 操作上,後端框架可以無差別的使用。

在 DDD 的概念中,CQRS 的 Command 的 C,既為 Command。

DeleteAction
BoardCommand

Event#

表示一系列事件。一般的,在語義上,Action,Command 等,來自於主動觸發;Event 來自於被動觸發。

ObservesProtectedEvent
KeyEvent

Delegate#

代理或者委託模式。委託模式是將一件屬於委託者做的事情,交給另外一個被委託者來處理。

LayoutlibDelegate
FragmentDelegate

Builder#

將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

構建者模式的標準命名。比如 StringBuilder。當然 StringBuffer 是個另类。這也說明了,規則是人定的,人也可以破壞。

JsonBuilder
RequestBuilder

Template#

模板方法類的命名。定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。

JDBCTemplate

Proxy#

代理模式。為其他對象提供一種代理以控制對這個對象的訪問。

ProxyFactory 
SlowQueryProxy

解析類命名#

寫代碼要涉及到大量的字符串解析、日期解析、對象轉換等。根據語義和使用場合的區別,它們也分為多種。

Converter,Resolver#

轉換和解析。一般用於不同對象之間的格式轉換,把一類對象轉換成另一類。注意它們語義上的區別,一般特別複雜的轉換或者有加載過程的需求,可以使用 Resolver。

DataSetToListConverter
LayoutCommandLineConverter
InitRefResolver
MustacheViewResolver

Parser#

用來表示非常複雜的解析器,比如解析 DSL。

SQLParser
JSONParser

Customizer#

用來表示對某個對象進行特別的配置。由於這些配置過程特別的複雜,值得單獨提取出來進行自定義設置。

ContextCustomizer
DeviceFieldCustomizer

Formatter#

格式化類。主要用於字符串、數字或者日期的格式化處理工作。

DateFormatter
StringFormatter

網絡類命名#

網絡編程的同學,永遠繞不過去的幾個名詞。

Packet#

通常用於網絡編程中的數據包。

DhcpPacket
PacketBuffer

Protocol#

同樣用於網絡編程中,用來表示某個協議。

RedisProtocol
HttpProtocol

Encoder、Decoder、Codec#

編碼解碼器

RedisEncoder
RedisDecoder
RedisCodec

Request,Response#

一般用於網絡請求的進和出。如果你用在非網絡請求的方法上,會顯得很怪異。

CRUD 命名#

這個就有意思多了,統一的 Controller,Service,Repository,沒什麼好說的。但你一旦用了 DDD,那就得按照 DDD 那一套的命名來。

由於 DDD 不屬於通用編程範疇,它的名詞就不多做介紹了。

其他#

Util,Helper#

都表示工具類,Util 一般是無狀態的,Helper 以便需要創建實例才能使用。但是一般沒有使用 Tool 作為後綴的。

HttpUtil
TestKeyFieldHelper
CreationHelper

Mode,Type#

看到 mode 這個後綴,就能猜到這個類大概率是枚舉。它通常把常見的可能性都列到枚舉類裡面,其他地方就可以引用這個 Mode。

OperationMode
BridgeMode
ActionType

Invoker,Invocation#

invoker 是一類接口,通常會以反射或者觸發的方式,執行一些具體的業務邏輯。通過抽象出 invoke 方法,可以在 invoke 執行之前對入參進行記錄或者處理;在 invoke 執行之後對結果和異常進行處理,是 AOP 中常見的操作方式。

MethodInvoker
Invoker
ConstructorInvocation

Initializer#

如果你的應用程序,需要經過大量的初始化操作才能啟動,那就需要把它獨立出來,專門處理初始化動作。

MultiBackgroundInitialize
ApplicationContextInitializer

Feture,Promise#

它們都是用在多線程之間的,進行數據傳遞。

Feture 相當於一個佔位符,代表一個操作將來的結果。一般通過 get 可以直接阻塞得到結果,或者讓它異步執行然後通過 callback 回調結果。

但如果回調中嵌入了回調呢?如果層次很深,就是回調地獄。Java 中的 CompletableFuture 其實就是 Promise,用來解決回調地獄問題。Promise 是為了讓代碼變得優美而存在的。

Selector#

根據一系列條件,獲得相應的同類資源。它比較像 Factory,但只處理單項資源。

X509CertSelector
NodeSelector

Reporter#

用來彙報某些執行結果。

ExtentHtmlReporter
MetricReporter

Constants#

一般用於常量列表。

Accessor#

封裝了一系列 get 和 set 方法的類。像 lombok 就有 Accessors 註解,生成這些方法。但 Accessor 類一般是要通過計算來完成 get 和 set,而不是直接操作變量。這適合比較複雜的對象存取服務。

ComponentAccessor
StompHeaderAccessor

Generator#

生成器,一般用於生成代碼,生成 id 等。

CodeGenerator
CipherKeyGenerator

End#

寫代碼,看源碼,怎麼少得了意會和神通?代碼要帶感,命名也風騷。命名起的好,代碼會看起來很爽,大家也都喜歡。

說不清楚的事情,給一段代碼,咱就能懂!就是這麼神奇!

其實,寫專業牛 b 的代碼,並不需要了解太多的英文單詞,大多數時候用不着英文 4 級這麼了不起的水平。只需要有限的單詞,就能玩出代碼界好萊塢的感覺。

看完本文之後,翻一翻開源軟體的代碼們,看看是不是這個理?

上面這些命名,高頻率存在於各種框架中。你要是搞懂了這些名詞,閱讀大部分源代碼可以說是一點障礙都沒有了。在同一個場景下,優先使用這些名詞,已經是大家心照不宣的規範。

有很多名詞來自於設計模式,但又在特定場合使用了比較特殊的單詞,比如 Provider,大家仔細感受下其中的區別就可以了。

命名是編碼中非常重要的一環,希望大家找到其中的規律,讓你的代碼功能上強大,顏值上好看;祝大家的薪資水漲船高,配得上你的這份專業和工匠精神。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。