banner
biuaxia

biuaxia

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

[Reprint] How are excellent open source software classes named?

title: [Reprint] How Are Classes of Excellent Open Source Software Named?
date: 2021-08-12 14:57:51
comment: false
toc: true
category:

  • Skills
    tags:
  • Reprint
  • Open Source
  • Software
  • Naming

This article is reprinted from: How Are Classes of Excellent Open Source Software Named?


In daily coding, naming code is a significant topic. Being able to quickly understand the structure and intent of open source software code is also an essential skill. So, what patterns do they follow?

The code structure of Java projects can reflect their design philosophy. Java adopts a long naming convention to standardize class naming, allowing it to express its main intent. Coupled with advanced IDEs, it can reduce the memory burden on coders, enabling them to find the resources they need through fuzzy matching.

To help everyone better understand the naming conventions, I have drawn from the most popular Java open source software (Spring series, Netty, libGDX, Guava, Logback, etc.) and summarized 10 common types of class naming. Most exist in suffix forms, and many can be combined to express multiple meanings.

image-20210810135355862.png

These words are simple but can make your class naming look cleaner and more professional. Next, I will take you on a tour. For ease of understanding, I have provided corresponding examples for each type.

Management Class Naming#

Writing code inevitably involves managing unified resources, and a clear startup process can effectively organize code. To get the program running, various resources need to be registered and scheduled, along with managing common collection resources.

Bootstrap, Starter#

Generally used as a program launcher or as a base class for launchers. Simply put, it can be considered the entry point of the main function.

AbstractBootstrap  
ServerBootstrap  
MacosXApplicationStarter  
DNSTaskStarter  

Processor#

A processor for a certain type of functionality, used to represent a processing procedure, which is a collection of a series of code snippets. If you don't know how to name some sequential code, you can use this to sound more sophisticated.

CompoundProcessor  
BinaryComparisonProcessor  
DefaultDefaultValueProcessor  

Manager#

Manages objects with a life state, usually serving as an entry point for managing a certain type of resource.

AccountManager  
DevicePolicyManager  
TransactionManager  

Holder#

Represents a reference to hold a certain or a class of objects and can manage them uniformly. Commonly seen in the unified handling of non-recyclable memory or caching of some global collection containers.

QueryHolder  
InstructionHolder  
ViewHolder  

Factory#

Undoubtedly, the naming of the factory pattern is well-known. Especially in Spring, there are countless examples.

SessionFactory  
ScriptEngineFactory  
LiveCaptureFactory  

Provider#

Provider = Strategy + Factory Method. It is a bit more advanced, combining the strategy pattern and method factory, making it very user-friendly. Providers are generally interfaces or abstract classes to allow for sub-implementations.

AccountFeatureProvider  
ApplicationFeatureProviderImpl  
CollatorProvider  

Registrar#

Registers and manages a series of resources.

ImportServiceRegistrar  
IKryoRegistrar  
PipelineOptionsRegistrar  

Engine#

Generally the core module used to handle a type of functionality. Engine is a very advanced term, and ordinary classes are not qualified to use it.

ScriptEngine  
DataQLScriptEngine  
C2DEngine  

Service#

A certain service. Too simple, I hesitate to give examples. The scope is too broad, so don't misuse it.

IntegratorServiceImpl  
ISelectionService  
PersistenceService  

Task#

A certain task. Usually a runnable.

WorkflowTask  
FutureTask  
ForkJoinTask  

Propagation Class Naming#

To complete some statistical or global functions, some parameters need to be passed all the way through. Objects of the propagation class can be passed through a unified encapsulation method and copied or updated at appropriate places.

Context#

If your program execution has some variables that need to be passed from the entry point of the function all the way to the completion of many sub-functions, passing these variables or collections as parameters would make the code excessively verbose. At this point, you can unify the variables into a Context and pass them as a single object.

In Java, due to the existence of ThreadLocal, Context can even be passed without being passed between parameters.

AppContext  
ServletContext  
ApplicationContext  

Propagator#

Propagation, reproduction. Used to copy, add, clear, reset, retrieve, and restore values passed in the context. Typically, it provides a method called propagate to achieve real variable management.

TextMapPropagator  
FilePropagator  
TransactionPropagator  

Callback Class Naming#

Using multicore can increase the efficiency of program execution, inevitably introducing asynchrony. We need certain means to obtain the results of asynchronous task execution and check key points during the task execution process. Callback class APIs can obtain these events through listening, notifications, etc.

Handler, Callback, Trigger, Listener#

Callback is usually an interface used to respond to a certain type of message for subsequent processing; Handler typically represents an object that holds the actual message processing logic and is stateful; Trigger represents the handling of a certain type of event, belonging to Handler, and usually does not appear in class naming; Listener's application is more limited, typically used in the observer pattern to represent specific meanings.

ChannelHandler  
SuccessCallback  
CronTrigger  
EventListener  

Aware#

Aware means perception. Classes ending with this word generally implement the Aware interface. In Spring, the purpose of Aware is to allow beans to obtain services from the Spring container. The specific callback methods are implemented by subclasses, such as ApplicationContextAware. It has a bit of a callback meaning.

ApplicationContextAware  
ApplicationStartupAware  
ApplicationEventPublisherAware  

Monitoring Class Naming#

Modern programs are quite complex, and monitoring the running state has become an essential item for home use. Collecting monitoring data often requires intruding into the corners of the program, and effectively distinguishing it from normal business is very necessary.

Metric#

Represents monitoring data. Don't use Monitor, it's quite ugly.

TimelineMetric  
HistogramMetric  
Metric  

Estimator#

Estimation, statistics. Used for calculating a certain type of statistical value.

ConditionalDensityEstimator  
FixedFrameRateEstimator  
NestableLoadProfileEstimator  

Accumulator#

Means accumulator. Used to cache intermediate calculation results and provide a reading channel.

AbstractAccumulator  
StatsAccumulator  
TopFrequencyAccumulator  

Tracker#

Generally used to record logs or monitoring values, often used in APM.

VelocityTracker  
RocketTracker  
MediaTracker  

Memory Management Class Naming#

If your application uses custom memory management, then the following terms are unavoidable. For example, Netty implements its own memory management mechanism.

Allocator#

Related to storage, usually represents a memory allocator or manager. If your program needs to request large blocks of memory in a regular pattern, allocator is your best choice.

AbstractByteBufAllocator  
ArrayAllocator  
RecyclingIntBlockAllocator  

Chunk#

Represents a block of memory. If you want to abstract a type of storage resource and manage it uniformly, you can use it.

EncryptedChunk  
ChunkFactory  
MultiChunk  

Arena#

The English meaning is stage or arena. Since Linux has popularized it in memory management, it is commonly used for the allocation, release, and management of various storage resources. Providing a stage for different specifications of storage chunks is also a very vivid representation.

The key is that this word is beautiful, making class names look elegant as a suffix.

BookingArena  
StandaloneArena  
PoolArena  

Pool#

Represents a pool. Memory pool, thread pool, connection pool, pools are available.

ConnectionPool  
ObjectPool  
MemoryPool  

Filtering and Detection Class Naming#

The events and information received by the program are numerous, some are legitimate, and some need to be filtered out. Depending on different usage scopes and functional differences, filtering operations can take various forms. You will find a large number of such terms in framework class code.

Pipeline, Chain#

Generally used in the chain of responsibility pattern. Netty, Spring MVC, Tomcat, etc., have a large number of applications. By adding a certain processing procedure to a position in the responsibility chain, you can receive the results of the previous processing procedure and forcibly add or change certain functionalities. Just like the pipeline operation in Linux, ultimately constructing the desired result.

Pipeline  
ChildPipeline  
DefaultResourceTransformerChain  
FilterChain  

Filter#

A filter used to screen certain datasets that meet conditions or execute a portion of logic when certain conditions are met. If connected with the chain of responsibility, it can usually achieve multi-level filtering.

FilenameFilter  
AfterFirstEventTimeFilter  
ScanFilter  

Interceptor#

An interceptor, which is actually similar to a Filter. However, in Tomcat, an Interceptor can access the controller object, while a filter cannot. The interceptor is wrapped in the filter.

HttpRequestInterceptor  

Evaluator#

In English, it means evaluator. Can be used to determine whether certain conditions are met, generally, the internal method evaluate will return a boolean type. For example, you pass in a very complex object or string to judge correctness.

ScriptEvaluator  
SubtractionExpressionEvaluator  
StreamEvaluator  

Detector#

A detector. Used to manage a series of detection events and can capture and respond when they occur. For example, gesture detection and temperature detection in Android.

FileHandlerReloadingDetector  
TransformGestureDetector  
ScaleGestureDetector  

Structural Class Naming#

In addition to basic data structures like arrays, linked lists, queues, stacks, etc., other more common abstract classes at a higher level can greatly reduce communication among everyone and encapsulate common changes.

Cache#

Nothing much to say, just cache. Large caches. Common caching algorithms include LRU, LFU, FIFO, etc.

LoadingCache  
EhCacheCache  

Buffer#

Buffer is a buffer, different from cache, it is generally used in the data writing phase.

ByteBuffer  
RingBuffer  
DirectByteBuffer  

Composite#

Combines similar components and exposes them through the same interface or functionality, so the user does not know whether this is a composite or other individual.

CompositeData  
CompositeMap  
ScrolledComposite  

Wrapper#

Used to wrap a certain object and perform some additional processing to add or remove certain functionalities.

IsoBufferWrapper  
ResponseWrapper  
MavenWrapperDownloader  

Option, Param, Attribute#

Used to represent configuration information. To be honest, the difference between it and Properties is not significant, but since Option is usually a class, its functionality can be extended more robustly. It is usually at a lower level than Config and focuses on the value of a single attribute. Param generally exists as a parameter and is generated faster.

SpecificationOption  
SelectOption  
AlarmParam  
ModelParam  

Tuple#

The concept of a tuple. Due to the lack of tuple structures in Java, we usually define such classes.

Tuple2  
Tuple3  

Aggregator#

An aggregator that can perform some aggregation calculations. For example, the aggregation of sum, max, min, etc., in sharding.

BigDecimalMaxAggregator  
PipelineAggregator  
TotalAggregator  

Iterator#

An iterator. Can implement Java's iterator interface or have its own iteration method. When the dataset is large, deep traversal is necessary, and an iterator is essential. Using an iterator also allows for safely deleting certain elements during iteration.

BreakIterator  
StringCharacterIterator  

Batch#

Certain requests or objects that can be executed in batches.

SavedObjectBatch  
BatchRequest  

Limiter#

A rate limiter, using a leaky bucket algorithm or token bucket to achieve smooth rate limiting.

DefaultTimepointLimiter  
RateLimiter  
TimeBasedLimiter  

Common Design Pattern Naming#

Design patterns are a hotspot for terminology; here are just a few of the most commonly used.

Strategy#

Separates the abstract part from its implementation part, allowing them to vary independently. Strategy pattern. Same interface, different implementation classes, same method results differ, implementing different strategies. For example, whether a configuration file is placed in XML or JSON can use different providers for naming.

RemoteAddressStrategy  
StrategyRegistration  
AppStrategy  

Adapter#

Converts the interface of a class into another interface that clients expect, allowing classes that cannot work together due to incompatible interfaces to work together.

However, compared to traditional adapters for API connections, if your Handler has many methods, you can use Adapter to implement some default methods for zero adaptation. Other classes can then simply inherit Adapter and override the methods they want to change. This is also a common use of Adapter.

ExtendedPropertiesAdapter  
ArrayObjectAdapter  
CardGridCursorAdapter  

Action, Command#

Encapsulates a request as an object, allowing you to parameterize clients with different requests, queue requests, or log request requests, and support undoable operations.

Used to represent a series of action commands to implement the command pattern, encapsulating a series of actions or functionalities. Action is generally used in UI operations, while backend frameworks can use it indiscriminately.

In the concept of DDD, the C in CQRS's Command stands for Command.

DeleteAction  
BoardCommand  

Event#

Represents a series of events. Generally, semantically, Action, Command, etc., come from active triggers; Event comes from passive triggers.

ObservesProtectedEvent  
KeyEvent  

Delegate#

Proxy or delegation pattern. The delegation pattern is to hand over a task that belongs to the delegator to another delegatee for processing.

LayoutlibDelegate  
FragmentDelegate  

Builder#

Separates the construction of a complex object from its representation, allowing the same construction process to create different representations.

Standard naming for the builder pattern. For example, StringBuilder. Of course, StringBuffer is an exception. This also illustrates that rules are made by people, and people can also break them.

JsonBuilder  
RequestBuilder  

Template#

Naming of template method classes. Defines the skeleton of an algorithm in an operation, deferring some steps to subclasses. The template method allows subclasses to redefine certain specific steps of an algorithm without changing the structure of that algorithm.

JDBCTemplate  

Proxy#

Proxy pattern. Provides a proxy for other objects to control access to that object.

ProxyFactory  
SlowQueryProxy  

Parsing Class Naming#

Writing code involves a lot of string parsing, date parsing, object conversion, etc. Depending on the semantics and usage scenarios, they can be divided into various types.

Converter, Resolver#

Conversion and parsing. Generally used for format conversion between different objects, converting one type of object into another. Note their semantic differences; particularly complex conversions or those requiring a loading process can use Resolver.

DataSetToListConverter  
LayoutCommandLineConverter  
InitRefResolver  
MustacheViewResolver  

Parser#

Used to represent very complex parsers, such as parsing DSL.

SQLParser  
JSONParser  

Customizer#

Used to represent special configurations for a certain object. Since these configuration processes are particularly complex, they are worth extracting for custom settings.

ContextCustomizer  
DeviceFieldCustomizer  

Formatter#

Formatting class. Mainly used for formatting strings, numbers, or dates.

DateFormatter  
StringFormatter  

Networking Class Naming#

Networking programming colleagues can never avoid a few terms.

Packet#

Usually used for data packets in network programming.

DhcpPacket  
PacketBuffer  

Protocol#

Also used in network programming to represent a certain protocol.

RedisProtocol  
HttpProtocol  

Encoder, Decoder, Codec#

Encoding and decoding.

RedisEncoder  
RedisDecoder  
RedisCodec  

Request, Response#

Generally used for incoming and outgoing network requests. If you use it in non-network request methods, it will seem quite odd.

CRUD Naming#

This is more interesting; unified Controller, Service, Repository, not much to say. But once you use DDD, you must follow the naming conventions of DDD.

Since DDD does not belong to the general programming category, its terminology will not be elaborated on.

Others#

Util, Helper#

Both represent utility classes; Util is generally stateless, while Helper requires an instance to be created for use. However, Tool is generally not used as a suffix.

HttpUtil  
TestKeyFieldHelper  
CreationHelper  

Mode, Type#

Seeing the suffix mode, you can guess that this class is likely an enumeration. It usually lists common possibilities in the enumeration class, which can be referenced elsewhere.

OperationMode  
BridgeMode  
ActionType  

Invoker, Invocation#

Invoker is a type of interface, usually executing specific business logic through reflection or triggering. By abstracting the invoke method, you can record or process input parameters before invoking; after invoking, you can handle results and exceptions, which is a common operation in AOP.

MethodInvoker  
Invoker  
ConstructorInvocation  

Initializer#

If your application requires a lot of initialization operations to start, you need to separate it out to handle initialization actions specifically.

MultiBackgroundInitialize  
ApplicationContextInitializer  

Feature, Promise#

Both are used for data transmission between threads.

Feature is equivalent to a placeholder representing the future result of an operation. Generally, you can directly block to get the result through get, or let it execute asynchronously and then callback the result.

But what if callbacks are nested within callbacks? If the hierarchy is deep, it becomes callback hell. CompletableFuture in Java is actually Promise, used to solve the callback hell problem. Promise exists to make the code more elegant.

Selector#

Obtains corresponding similar resources based on a series of conditions. It is somewhat like a Factory but only processes single resources.

X509CertSelector  
NodeSelector  

Reporter#

Used to report certain execution results.

ExtentHtmlReporter  
MetricReporter  

Constants#

Generally used for constant lists.

Accessor#

A class that encapsulates a series of get and set methods. For example, Lombok has an Accessors annotation to generate these methods. However, Accessor classes generally complete get and set through calculations rather than directly manipulating variables. This is suitable for more complex object access services.

ComponentAccessor  
StompHeaderAccessor  

Generator#

A generator, generally used for generating code, generating IDs, etc.

CodeGenerator  
CipherKeyGenerator  

End#

Writing code and reading source code inevitably involves understanding and skill. Code should be engaging, and naming should be stylish. Good naming makes code look great, and everyone appreciates it.

When something is unclear, just give a piece of code, and we can understand it! It's that magical!

In fact, writing professional and impressive code does not require knowing too many English words; most of the time, you don't need such a high level of English. With a limited vocabulary, you can create a Hollywood feel in the coding world.

After reading this article, take a look at the code of open source software and see if this is the case?

The above naming conventions frequently exist in various frameworks. If you understand these terms, reading most source code can be said to have no obstacles. In the same scenario, prioritizing the use of these terms has become an unspoken norm.

Many terms come from design patterns but use relatively unique words in specific contexts, such as Provider; just feel the differences among them.

Naming is a very important part of coding, and I hope everyone finds the patterns within it, making your code powerful in functionality and beautiful in appearance; may everyone's salary rise to match your professionalism and craftsmanship.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.