introduction
In projects I have seen, most teams tend to "functional stacking" development: when the demand comes, logic or function is added, but few people are willing to spend time on design, especially inObject namingSpend time. This seems like a "quick implementation of requirements" approach, which usually has a bad impact on the readability of the code, and thus affects maintainability.
A good object namingIt is not just about making the code look neat on the surface; it is related to the way humans and AI understand the system, and it will also shape the behavior of programmers and AI tools in subsequent maintenance and iterations. In other words, appropriate naming not only determines the elegance of the current code, but also subtly affects the thinking path and decision-making process when modifying, expanding and refactoring the code in the future.
Below, we will explore how to use reasonable naming to truly reflect the business meaning and autonomous decision-making ability, rather than simply playing a "passive executor".
1. Avoid naming objects ending with er or or
Imagine you walking into a restaurant. How would you order food? Should I ask for a portion of Kung Pao Chicken Dice, or tell the chef: "You add oil first, then stir-fry over high heat, and then add seasonings"? If you choose the latter, then the corresponding programming method is probably the following:
class FoodMaker {
public Dish Cook(List<Step> cookingSteps) {
foreach(var step in cookingSteps) {
ExecuteStep(step);
}
return new Dish();
}
}
// Client code
var maker = new FoodMaker();
var steps = new List<Step> {
new Step("Drain oil"),
new Step("hot and stir-fry"),
new Step("add seasoning")
};
var dish = (steps);
FoodMaker, it is just a "cooking person" or "actuator" and lacks more "subjective initiative". This not only increases the burden on users at the thinking level, but also seems to be inconsiderable to the experience and skills of professional chefs.
In contrast, a more realistic way is to directly tell the other party "I need a portion of Kung Pao Chicken", and the chef will complete the dish based on his own experience and understanding of the ingredients. For example:
Chef {
public Dish PrepareKungPaoChicken() {
// The chef knows how to prepare this dish
return new KungPaoChicken();
}
}
// Client code
var chef = new Chef();
var dish = ();
so,ChefIt fully reflects professionalism and autonomy:
-
The character name directly reminds people of a self-decision-making person with professional skills, rather than a simple “cooker.”
-
The client simply needs to express "what dish you want" without having to elaborate on all the steps.
-
Chefs can adjust cooking details according to specific ingredients and scenarios, bringing more flexibility to the business.
It is worth noting that many“-er”or“-or”The ending object (such asManager、Processor、Controller、Validator) There are often similar tendencies of "processing":They reflect more of process collections than business entities. When we change the naming to a noun that better conveys professional identity or business roles, we often see the object's "self-awareness" and "subjective initiative" improve, thus making the entire system's abstraction level higher and maintainable better.
2. Suffixes such as "Service", "Helper", "Utility", etc. are more likely to appear "God"
With the popularity of AI-assisted programming tools, the clarity of naming is particularly important in large-scale projects. A vague or overly abstract name will not only increase the team members, but also put your own cognitive burden after 3 months, but will also make it difficult for AI to understand the object's true intentions in a large number of contexts, and even cause misleading completion. Let's first look at an inappropriate example:
Error Example: RestaurantService collects all trivial matters
public class RestaurantService {
// The name seems to manage everything in the restaurant, but it mixes completely different functions such as cooking, delivering and finance
// Cook a dish
public void cookDish(String dishName) {
}
// Send the dishes to the designated address
public void deliverFood(String address) {
}
// Arrange work shifts for chefs, waiters and other employees
public void scheduleStaff(String staffName, String shift) {
}
// Handle daily or monthly financial settlements at the restaurant
public void handleBilling() {
}
}
question:
-
Too broad and abstract class names: RestaurantService seems to be responsible for all restaurant-related functions, from cooking to delivery to financial settlement, which is far beyond the scope of a single responsibility.
-
Misleading to AI: When AI tools are searched or completed in large-scale code bases, when you see "RestaurantService", you may think that you can find any logic related to restaurant operations, and when completing, you may also add more irrelevant functions (such as " Purchase ingredients, "marketing activities", etc.) can easily lead to God-like things.
-
Difficult to maintain and expand: If you want to change the delivery method or financial accounting logic in the future, you will find that all functions are coupled in the same category, and one change is very likely to affect the entire system.
More reasonable design: split according to professional division of labor
To make the code easier to read, maintainable, and make AI analysis more accurate, we can split the "restaurant operation" into multiple special objects according to the real scenario, so that each class name can "prove its duties" more easily :
// Focus on cooking logic
public class Kitchen {
public void cookDish(String dishName) {
// Professionally handle cooking process
}
}
// Focus on takeaway delivery
public class Delivery {
public void deliverFood(String address) {
// Professionally handle the food delivery process
}
}
// Focus on staff scheduling
public class StaffScheduling {
public void schedule(String staffName, String shift) {
// Professionally handle employee shift scheduling
}
}
// Focus on financial settlement
public class Billing {
public void settlementAccounts() {
// Specializes in accounting settlement
}
}
benefit:
-
Clear responsibilities: Kitchen only does cooking, Delivery only does take-out, StaffScheduling only takes care of shifts, and Billing is used for settlement finance. Each object has a clear field of expertise.
-
Easy to understand: Whether it is a human or an AI, you can quickly infer its functions by seeing the class name to reduce misunderstandings.
-
Easy to expand: In the future, you need to add automatic scheduling to "delivery" or add menu recommendation logic to "cooking". You can also iterate separately in the corresponding class without affecting other modules.
-
Match the real scene: In reality, the restaurant's back kitchen, delivery staff, personnel, finance, etc. perform their duties, and similar principles should be followed in software design.
3. Object naming and object "intelligent" attributes: can still adapt to the environment when the environment changes.
In real life, if the essential ingredients for Kung Pao chicken (such as peanuts) are suddenly out of stock, a real professional chef will take the initiative to find alternative ingredients without asking customers to "issuing orders" or "changing ordering methods". Similarly, in software, an object designed to be "smart" enough should be able to adjust the internal logic by itself when external conditions or business needs change without affecting the caller's usage.
Example: Cooking of facial process
public class CookingProcess {
public Dish cook(String dishName) {
// Perform fixed steps regardless of whether the ingredients are out of stock
// ...
return new Dish(dishName); // Return to the prepared dish
}
}
Limited:
-
Once the ingredients are out of stock, the caller needs to determine whether the dish can be made or modify the cooking process.
-
Every time the requirements change, the cook method or the code must be changed, and true "adaptation" cannot be achieved.
Improvement example: Chefs are professionals who can adapt to environmental changes
Chef below decides internally whether peanuts are available, and if they are out of stock, use other ingredients instead. In this way, even if there are more similar changes in the future (change of new seasonings, temporary suppliers, etc.), they can be concentrated on the internal adjustment of Chef without changing the client call code.
public class Chef {
// Simulate peanut inventory status, can be from a database or configuration file
private boolean peanutsInStock = false;
public Dish prepareDish(String dishName) {
if ("Kang Bao Chicken Dice".equals(dishName)) {
// If peanuts are out of stock, use other dried fruits instead
if (!peanutsInStock) {
// ...Use cashew nuts or other alternative ingredients internally
}
// ...Otherwise, peanuts will be used normally
}
// The rest of the cooking logic
return new Dish(dishName);
}
}
benefit:
-
Strong cohesion: All judgments and alternative logic are placed inside Chef, and the outside world does not need to care about specific practices.
-
Client calls remain unchanged: No matter how the peanut inventory status changes, the caller still only needs to order food with "one command" to get the result.
-
Scalable: If you encounter more similar scenarios in the future (for example, a seasoning is temporarily sold out), you only need to modify Chef, which will not affect the existing calling code.
-
Client call example: Environment/demand changes, does not affect client call
public class Main {
public static void main(String[] args) {
Chef chef = new Chef();
// The client only needs to tell the chef to make "Kang Bao Chicken"
Dish dish = ("Kang Bao Chicken Ding");
// Even if the peanuts are out of stock, Chef will automatically use other ingredients without the caller's change
}
}
Regardless of the peanut stock,Client calls are always consistent: An intelligent Chef can complete the corresponding "adaptive" processing internally.
Summary: Naming means design, treating objects as living entities and being able to make independent decisions
Many people often regard the naming of objects as "good-looking" or "easy" issues, but ignore the depth of business understanding and systematic thinking it implies. When we deliberately avoid it“-er”When ending or vague labels such as "Service" and "utility" suffixes, and let the object name truly reflect its professional role and business responsibilities, the following benefits can be achieved:
-
Reduce misunderstandings
New members or AI tools can quickly understand the intent of the class and prevent them from going astray when completing or analyzing. -
Improve internal gathering
The logical boundaries of each object are clearer, so changing a function does not require changing the global situation. -
Easy to expand
Each object is like a flexible module that can be maintained, replaced or upgraded independently without affecting the overall architecture. -
Close to business
Consistent with the product or business team at the concept level, improve communication efficiency, and reduce the gap between architecture design and business needs.
In software engineering, the importance of naming is often overlooked, but naming itself subtly affects our thinking when coding. Only when we truly regard the object as entities with "dignity" and "autonomous decision-making capabilities" can we more easily build a system that is highly cohesive, easy to expand, and in line with the nature of the business.