当前位置: 首页 > news >正文

202537 |《代码整洁之道》笔记

一 有意义的命名

🧠 名副其实

描述:名称应准确地表达变量、函数或类的用途或含义,避免含糊不清。

❌ 反例
int d; // 表示天数,但完全看不出来
✅ 正例
int daysSinceLastBackup;

👍 优点:名称传达了变量的确切含义,使代码更具可读性和可维护性。


🧠 避免误导

描述:名称不应暗示错误的行为或结构,避免让读者产生误解。

❌ 反例
List<User> userList = new HashSet<>();
✅ 正例
Set<User> userSet = new HashSet<>();

👍 优点:名称与类型保持一致,减少因误解导致的错误使用。


🧠 做有意义的区分

描述:命名的不同之处应具有实际意义,而不是依靠无意义的数字或冗余。

❌ 反例
int data;
int data1;
✅ 正例
int rawData;
int processedData;

👍 优点:明确表达变量间的区别,提高代码清晰度。


🧠 使用读得出来的名称

描述:名称应便于阅读和朗读,让代码更容易被讨论和理解。

❌ 反例
int genymdhms;
✅ 正例
int generationTimestamp;

👍 优点:可朗读的名称提升沟通效率和团队协作质量。


🧠 使用可搜索的名称

描述:变量和方法名应便于在代码中搜索和定位。

❌ 反例
int t; // 搜索t毫无意义
✅ 正例
int timeoutInSeconds;

👍 优点:便于搜索和重构,提高开发效率。


🧠 避免使用编码

描述:不要在名称中加入类型、作用域等冗余信息(如匈牙利命名法)。

❌ 反例
String strName;
✅ 正例
String name;

👍 优点:现代IDE已能提示类型,简化命名让代码更清爽。


🧠 避免思维映射

描述:变量名应直观表达意义,避免使用缩写或需要解释的名字。

❌ 反例
int r; // 是radius?rows?result?
✅ 正例
int rowCount;

👍 优点:减少大脑负担,无需额外推理变量含义。


🧠 类名

描述:类名应使用名词或名词短语,表示对象的“是什么”。

❌ 反例
class ManageUsers {}
✅ 正例
class UserManager {}

👍 优点:贴合职责,符合语法规范,有助于理解类功能。


🧠 方法名

描述:方法名应使用动词或动词短语,表示行为或动作。

❌ 反例
void data() {}
✅ 正例
void fetchUserData() {}

👍 优点:表达清晰,说明方法具体要做什么。


🧠 别扮可爱

描述:避免使用俏皮或晦涩的名称,让代码看起来不专业。

❌ 反例
int haha = 5;
✅ 正例
int retryLimit = 5;

👍 优点:增强代码专业性,提高可读性和维护性。


🧠 每个概念对应一个词

描述:同一概念在代码中应始终使用一致的词汇。

❌ 反例
fetch();
retrieve();
get();
✅ 正例
get();
get();
get();

👍 优点:统一命名风格,减少认知切换。


🧠 别用双关语

描述:避免一个词同时表示多个不同概念,防止歧义。

❌ 反例
class Controller {} // 是MVC控制器?还是设备控制器?
✅ 正例
class DeviceController {}

👍 优点:消除歧义,让代码语义更清晰。


🧠 使用解决方案领域名称

描述:使用开发者熟悉的术语可提高技术理解效率。

❌ 反例
class ThingSorter {}
✅ 正例
class QuickSort {}

👍 优点:利用已有知识缩短理解路径。


🧠 使用源自所涉问题领域的名称

描述:使用业务领域的术语提升代码的业务语义。

❌ 反例
double value;
✅ 正例
double taxRate;

👍 优点:代码语义贴近业务逻辑,便于沟通和维护。


🧠 添加有意义的语境

描述:通过命名添加必要的上下文信息以避免歧义。

❌ 反例
String name;
✅ 正例
String employeeName;

👍 优点:让变量在脱离上下文时依然清晰易懂。


🧠 不要添加没用的语境

描述:避免冗余前缀或类名重复,使代码冗长。

❌ 反例
class Account {String accountName;
}
✅ 正例
class Account {String name;
}

👍 优点:移除冗余信息,代码更简洁,聚焦核心含义。

二 函数

🧠 短小

描述:函数应该尽量简洁精炼,保持在几行代码以内,有利于理解和维护。

❌ 反例
void processOrder() {validateUser();checkInventory();applyDiscounts();calculateTaxes();updateOrder();sendConfirmation();
}
✅ 正例
void processOrder() {prepareOrder();finalizeOrder();
}

👍 优点:短函数更容易阅读、测试与复用,符合“阅读比写作更重要”的原则。


🧠 只做一件事

描述:一个函数只应完成一项清晰的工作,如果它做了多个事,就应该拆分。

❌ 反例
void saveUser(User user) {validateUser(user);database.save(user);emailService.sendWelcome(user);
}
✅ 正例
void saveUser(User user) {validateUser(user);persistUser(user);notifyUser(user);
}

👍 优点:便于复用和修改,单一职责原则使测试更简单,出错更少。


🧠 每个函数一个抽象层级

描述:函数内部的操作应该处在同一抽象层,不应掺杂具体实现与高层逻辑。

❌ 反例
void generateInvoice() {System.out.println("Connecting to database...");Connection conn = DriverManager.getConnection(...);Invoice invoice = new Invoice();// ...
}
✅ 正例
void generateInvoice() {connectToDatabase();Invoice invoice = createInvoice();deliverInvoice(invoice);
}

👍 优点:抽象层次统一,逻辑清晰,利于维护和理解。


🧠 switch语句

描述switch 语句违反开闭原则,推荐用多态代替。

❌ 反例
double calculatePay(Employee e) {switch (e.type) {case ENGINEER: return baseSalary;case MANAGER: return baseSalary + bonus;default: return 0;}
}
✅ 正例
abstract class Employee {abstract double calculatePay();
}class Engineer extends Employee {double calculatePay() { return baseSalary; }
}class Manager extends Employee {double calculatePay() { return baseSalary + bonus; }
}

👍 优点:遵循开闭原则,添加新类型时无需修改原有代码。


🧠 使用描述性的名称

描述:函数名称应能清晰地表达它的目的和行为,避免模糊或通用词。

❌ 反例
void handle() {}
✅ 正例
void handleLoginRequest() {}

👍 优点:无需查看函数体即可理解其用途,提高可读性。


🧠 函数参数

描述:参数越少越好,理想是0到2个,多个参数应考虑封装成对象。

❌ 反例
void createUser(String name, String email, int age, boolean isVerified) {}
✅ 正例
void createUser(User user) {}

👍 优点:简化调用,增强可读性与可维护性。


🧠 分隔指令与询问

描述:一个函数不应该既执行操作又返回判断,应拆分为“命令”和“查询”。

❌ 反例
boolean saveAndCheck(User user) {save(user);return user.isValid();
}
✅ 正例
void save(User user) {database.save(user);
}boolean isValid(User user) {return user.isValid();
}

👍 优点:逻辑清晰,符合命令-查询分离(CQS)原则,便于测试和重构。


🧠 使用异常替代返回错误码

描述:错误码难以统一处理和传递,应该使用异常来表明异常状态。

❌ 反例
int withdraw(double amount) {if (amount > balance) {return -1; // 错误码}balance -= amount;return 0;
}
✅ 正例
void withdraw(double amount) throws InsufficientFundsException {if (amount > balance) {throw new InsufficientFundsException();}balance -= amount;
}

👍 优点:异常处理更清晰,避免遗漏错误判断,提高代码健壮性。


🧠 别重复自己(DRY)

描述:重复的逻辑应提取为独立函数,减少维护成本。

❌ 反例
if (user.isActive() && user.hasPermission("READ")) {// do read
}if (user.isActive() && user.hasPermission("WRITE")) {// do write
}
✅ 正例
boolean canAccess(User user, String permission) {return user.isActive() && user.hasPermission(permission);
}

👍 优点:便于维护、测试和逻辑复用。


🧠 结构化编程

描述:应使用结构化控制流(如 if、while)避免 goto、break 等混乱跳转。

❌ 反例
void process() {while (true) {if (conditionMet()) break;// do work}
}
✅ 正例
void process() {while (!conditionMet()) {// do work}
}

👍 优点:流程清晰,逻辑更易理解和维护。

三 注释

概念:注释不能美化糟糕的代码

描述:注释不是用来掩盖混乱代码的,清晰的代码应首先通过重构来改善,而不是依赖注释。

❌ 反例(糟糕代码加注释):

// 判断用户是否激活
if (user.status == 1) {// ...
}

✅ 正例(清晰表达):

if (user.isActive()) {// ...
}

👍 正例优点:通过良好的命名和结构消除了对注释的依赖,提升可读性。


概念:用代码来阐述

描述:当注释只是为了解释复杂逻辑时,应该考虑重构代码,让代码本身表达意图。

❌ 反例:

// 如果用户不是 VIP 且余额小于 0,就不允许操作
if (!user.isVip() && balance < 0) {return false;
}

✅ 正例:

if (isOverdrawnAndNotVip(user, balance)) {return false;
}boolean isOverdrawnAndNotVip(User user, double balance) {return balance < 0 && !user.isVip();
}

👍 正例优点:封装逻辑并用语义化命名,避免误解,提高代码自解释性。


概念:好注释

描述:好的注释提供代码无法表达的背景信息,例如设计原因、历史决定、外部依赖或警告。

✅ 正例:

// 第三方 API 存在 Bug,暂时使用固定日期,待 v2 修复后删除
request.setDate("2020-01-01");

👍 正例优点:提供维护线索,帮助理解异常或非直观代码行为。


概念:坏注释

描述:冗余、误导性、与代码不符或解释显而易见内容的注释,反而会造成困扰。

❌ 反例:

// 设置用户名为 Alice
user.setName("Alice");// 调用处理逻辑
process();

👍 正例优点(不写注释):避免信息重复、误导或过时,代码保持清爽简洁。


四 格式

概念:格式的目的

描述:代码格式的目的是使代码更易于阅读和理解。良好的格式可以帮助开发者快速抓住代码的结构,提升团队协作和维护的效率。

👍 优点:提高代码可读性和一致性,减少理解时间,避免错误。


概念:垂直格式

描述:垂直格式关注代码在页面上的排列,涉及如何在文件中安排不同的代码块,使它们具有良好的层次性和可视性。

❌ 反例

public void processOrder(Order order) {validateOrder(order); checkInventory(order); applyDiscounts(order); sendConfirmation(order);}

✅ 正例

public void processOrder(Order order) {validateOrder(order);checkInventory(order);applyDiscounts(order);sendConfirmation(order);
}

👍 正例优点:清晰的空行分隔有助于理解代码逻辑,减少长行代码的压迫感。


概念:横向格式

描述:横向格式关注如何在每行代码中安排内容,确保每行代码不过长,变量、操作符等元素的合理分布。

❌ 反例

if (someLongConditionThatRequiresMultipleArguments && someOtherCondition && yetAnotherCondition) { doSomething(); }

✅ 正例

if (someLongConditionThatRequiresMultipleArguments && someOtherCondition && yetAnotherCondition) {doSomething();
}

👍 正例优点:提高每行代码的可读性,避免行过长导致的视觉疲劳和难以理解的表达。


是否继续整理第五章内容,或有其他需要修改的部分?

五 对象和数据结构

概念:数据抽象

描述:数据抽象是指将数据和操作数据的细节隐藏起来,暴露出更高层次的接口和行为。通过抽象,可以更清晰地定义数据的使用方式,而不被实现细节所干扰。

❌ 反例

class Employee {String name;int age;double salary;void setName(String name) {this.name = name;}void setAge(int age) {this.age = age;}void setSalary(double salary) {this.salary = salary;}
}

✅ 正例

class Employee {private String name;private int age;private double salary;void increaseSalary(double amount) {this.salary += amount;}void celebrateBirthday() {this.age++;}// 仅暴露必要的操作,隐藏数据细节
}

👍 正例优点:隐藏实现细节,暴露有意义的行为,让外部代码只关心操作而非数据结构。


概念:数据、对象的反对称性

描述:对象和数据结构之间存在反对称性:对象封装了数据和行为,数据结构只是数据的容器,缺乏行为。优先选择对象而非数据结构,能带来更高层次的封装和灵活性。

❌ 反例

class Order {String product;int quantity;double price;
}

✅ 正例

class Order {private String product;private int quantity;private double price;double calculateTotal() {return quantity * price;}void updateQuantity(int newQuantity) {this.quantity = newQuantity;}
}

👍 正例优点:对象将数据和行为结合,封装了复杂性,使得类更具备清晰的职责,便于扩展和维护。


概念:得墨忒定律

描述:得墨忒定律指出,软件系统中高层次的模块应该依赖于低层次模块,而不是反过来。高层模块依赖于低层模块的接口,而不直接依赖于实现细节。

❌ 反例

class CustomerService {void createCustomer() {DatabaseConnection db = new DatabaseConnection();db.saveCustomer();}
}

✅ 正例

class CustomerService {private DatabaseConnection db;CustomerService(DatabaseConnection db) {this.db = db;}void createCustomer() {db.saveCustomer();}
}

👍 正例优点:依赖注入使得高层模块不直接依赖于低层实现,增强了可扩展性和可测试性。


概念:数据传送对象(DTO)

描述:数据传送对象(DTO)是用于数据传输的简单对象,不包含业务逻辑,只承载数据。在服务层和表示层之间传递数据时,DTO 是常见的解决方案。

❌ 反例

class User {private String username;private String email;// 包含业务逻辑的 DTO 使得数据变得复杂void sendEmail(String message) {EmailService.send(this.email, message);}
}

✅ 正例

class UserDTO {private String username;private String email;// 不包含业务逻辑,仅提供数据承载
}

👍 正例优点:DTO 清晰地分离了数据与业务逻辑,简化了数据传输和存储结构,提高了系统的灵活性。

六 错误处理和异常码

概念:使用异常而非返回码

描述:应该使用异常来处理错误,而不是通过返回码来传递错误信息。异常能清晰地标识出错误发生的原因,且能简化错误处理逻辑。

❌ 反例

int processOrder(Order order) {if (order.isValid()) {// 处理订单return 0;  // 成功}return -1;  // 错误码
}

✅ 正例

void processOrder(Order order) throws InvalidOrderException {if (!order.isValid()) {throw new InvalidOrderException("Order is not valid");}// 处理订单
}

👍 正例优点:异常提供明确的错误信息,简化错误处理流程,使错误传递更加清晰。


概念:先写try-catch-finally语句

描述:编写 try-catch-finally 语句时,应该在捕获异常时尽量考虑异常处理的范围,并且确保 finally 中的清理工作得以执行。

❌ 反例

try {// 执行操作
} catch (Exception e) {// 错误处理
}
// 忘记写 finally,导致资源泄漏

✅ 正例

try {// 执行操作
} catch (Exception e) {// 错误处理
} finally {closeResources();
}

👍 正例优点:确保资源得以释放,错误处理更具备一致性,避免资源泄漏。


概念:使用不可控异常

描述:对于无法预见和无法控制的异常,应该使用异常来通知调用者。例如,I/O 错误、数据库连接问题等。

❌ 反例

boolean connectToDatabase() {if (/* some error */) {return false; // 通过返回码报告错误}return true;
}

✅ 正例

void connectToDatabase() throws DatabaseConnectionException {if (/* some error */) {throw new DatabaseConnectionException("Unable to connect to database");}
}

👍 正例优点:异常可以清晰地描述错误,保证异常被显式处理或传播。


概念:给出异常发生的环境说明

描述:异常应尽可能提供发生的上下文信息,帮助调用者更好地理解发生了什么错误。

❌ 反例

throw new SQLException();

✅ 正例

throw new SQLException("Database connection failed while trying to save order with ID: " + orderId);

👍 正例优点:提供详细的上下文信息,帮助排查和处理问题。


概念:依调用者需要定义异常类

描述:异常类应根据调用者的需求来定义,不应过度设计或者定义无关的异常类。每个异常类应聚焦于其特定场景。

❌ 反例

class InvalidInputException extends Exception {}
class NetworkException extends Exception {}
class GenericException extends Exception {}  // 不明确、不必要的异常类

✅ 正例

class OrderNotFoundException extends Exception {}
class PaymentFailedException extends Exception {}

👍 正例优点:通过精确的异常类可以明确标识错误的具体原因,便于异常的分类和捕获。


概念:定义常规流程

描述:在程序的常规流程中,尽量避免将控制流中断,异常应该用来处理异常情况,而不是正常的业务流程。

❌ 反例

void processOrder(Order order) {if (order.isValid()) {// 正常处理} else {throw new InvalidOrderException("Invalid order");}
}

✅ 正例

void processOrder(Order order) {if (!order.isValid()) {return;  // 正常流程中不抛出异常}// 正常处理
}

👍 正例优点:避免过度依赖异常来控制正常流程,提高代码的清晰度和执行效率。


概念:别返回null值

描述:函数应避免返回 null 值,这会导致调用者额外的 null 检查。通过返回一个空对象或者特定的错误信息,可以提高代码的健壮性。

❌ 反例

Order findOrderById(int orderId) {if (orderId == 0) {return null;  // 返回 null}// 查找订单
}

✅ 正例

Optional<Order> findOrderById(int orderId) {if (orderId == 0) {return Optional.empty();  // 返回 Optional 对象}// 查找订单
}

👍 正例优点:通过使用 Optional 等类型来处理空值,能减少空指针异常的发生,提升代码的健壮性。


概念:别传递null值

描述:函数的参数不应传递 null,这可能导致运行时错误。可以使用空对象模式或适当的检查来处理空值问题。

❌ 反例

processOrder(null);  // 传递 null 参数

✅ 正例

if (order != null) {processOrder(order);  // 空值检查
}

👍 正例优点:避免空指针异常,提高代码的稳定性和容错性。

七 味道与启发

1 注释

概念:不恰当的信息

描述:不恰当的注释是指提供无关或误导信息的注释。这样的注释不仅不能帮助开发者理解代码,反而可能引起混乱。

❌ 反例

// 这里设置用户年龄
user.setAge(30);

这里的注释没有提供任何有价值的信息,因为代码本身已经非常直观。

✅ 正例

// 设置用户年龄
user.setAge(user.getAge() + 1); // 将年龄加 1,表示用户过生日了

👍 正例优点:注释清晰地阐明了操作的目的,提升了代码的可理解性。


概念:废弃的注释

描述:废弃的注释是指已经不再有效或不再使用的注释。它们会让读者困惑,因为它们描述的是过时的信息或不再相关的逻辑。

❌ 反例

// 这个方法不再使用,已被 deleteUser() 替代
deleteOldUser();

✅ 正例

// 删除过时用户
deleteUser();

👍 正例优点:去掉废弃注释,让代码更简洁,确保注释与实际代码一致,避免混淆。


概念:冗余的注释

描述:冗余的注释指的是那些重复或显而易见的注释。这样的注释没有提供附加信息,反而增加了代码的复杂性。

❌ 反例

int count = 0; // 将 count 初始化为 0

✅ 正例

int count = 0; // 没有必要的注释,代码已足够清晰

👍 正例优点:避免无意义的注释,保持代码简洁和清晰。


概念:糟糕的注释

描述:糟糕的注释是指那些写得模糊不清、过于复杂或与代码不一致的注释。糟糕的注释不仅没用,还会增加理解难度。

❌ 反例

// 下面的代码是为了确保我们不会遇到潜在的问题,但也不清楚为什么要这么做
handleErrors();

✅ 正例

// 处理可能出现的网络错误并记录日志
handleErrors();

👍 正例优点:注释清晰、简洁且直接,明确描述了代码的意图,帮助开发者快速理解。


概念:注释掉的代码

描述:注释掉的代码是指被暂时禁用但未删除的代码。保留注释掉的代码会导致代码库冗余,增加维护成本,并使代码变得不清晰。

❌ 反例

// if (user.isLoggedIn()) {
//     sendWelcomeMessage();
// }

✅ 正例

// 删除过时代码,避免不必要的注释

👍 正例优点:删除不再需要的注释掉的代码,使代码库保持干净、整洁。

2 环境

概念:需要多步才能实现的构建

描述:构建过程如果需要多个步骤才能完成,意味着构建系统存在复杂性,增加了构建和部署的难度。尽可能减少构建步骤,确保构建流程简洁高效。

❌ 反例

# 多步手动构建过程
git pull
mvn clean install
cp target/*.jar /opt/app
service restart app

✅ 正例

# 简化的构建过程
./build.sh  # 一键构建脚本

👍 正例优点:通过自动化脚本减少人为操作的复杂性,确保构建过程一致且高效。


概念:需要多步才能做到的测试

描述:如果测试需要多步才能完成,可能会导致测试过程变得冗长且易错,影响开发效率。简化测试步骤并使其尽量自动化,可以提升开发和测试的效率。

❌ 反例

# 多步手动测试过程
git pull
mvn clean install
mvn test
cp target/test-results/*.xml /opt/test-reports

✅ 正例

# 简化的自动化测试过程
./run_tests.sh  # 一键测试脚本

👍 正例优点:自动化测试流程减少了出错的机会,保证了测试的覆盖性和效率,同时提高了开发周期中的反馈速度。

3 函数

概念:过多的参数

描述:函数参数过多会增加函数的复杂性,导致理解和维护变得更加困难。理想的函数应尽量减少参数的数量,必要时可以将相关参数打包成对象。

❌ 反例

void createUser(String name, String email, String phone, String address, String city, String state, String zip) {// 创建用户
}

✅ 正例

class User {String name;String email;String phone;String address;String city;String state;String zip;// 构造函数将所有参数封装成对象public User(String name, String email, String phone, Address address) {this.name = name;this.email = email;this.phone = phone;this.address = address;}
}

👍 正例优点:通过将相关参数封装成对象(如 Address),减少了函数参数的数量,使代码更简洁、易于理解和维护。


概念:输出参数

描述:输出参数是指函数通过参数返回值,这样的做法会增加函数的副作用和复杂度。尽量避免使用输出参数,而是通过返回值来传递结果。

❌ 反例

void calculateArea(int radius, int result) {result = (int) (Math.PI * radius * radius);
}

✅ 正例

int calculateArea(int radius) {return (int) (Math.PI * radius * radius);
}

👍 正例优点:返回值明确,不修改外部变量,函数副作用更少,调用者使用更简单。


概念:标识参数

描述:标识参数是用于区分不同操作或状态的参数,通常是一个常量或枚举值。这样的参数可以使函数的行为变得模糊不清,增加了函数的复杂性。应尽量避免使用标识参数,或者考虑使用更具描述性的方式来表达不同状态。

❌ 反例

void processOrder(int orderType) {if (orderType == 1) {// 处理普通订单} else if (orderType == 2) {// 处理加急订单}
}

✅ 正例

enum OrderType {NORMAL, URGENT;
}void processOrder(OrderType orderType) {switch (orderType) {case NORMAL:// 处理普通订单break;case URGENT:// 处理加急订单break;}
}

👍 正例优点:使用枚举类型 OrderType 清晰地表达了不同订单类型,避免了不明确的标识参数,提高了代码可读性和可扩展性。


概念:死函数

描述:死函数是指没有实际效果或没有被调用的函数。它们增加了代码的冗余,降低了代码的质量和可维护性。应定期删除不再使用的死函数。

❌ 反例

void doNothing() {// 空函数,完全没有作用
}

✅ 正例

// 删除无用的死函数

👍 正例优点:删除死函数清理了代码,减少了维护负担,提升了代码质量。

4 一般性问题

概念:一个源文件存在多种语言

描述:源文件中包含多种编程语言会增加代码的复杂性和维护成本。理想的做法是每个源文件专注于一种语言和功能。

❌ 反例

// Java 和 HTML 混合
public class MyPage {public String getContent() {return "<html><body>Hello</body></html>"; // HTML 代码与 Java 逻辑混在一起}
}

✅ 正例

// Java 只包含 Java 代码
public class MyPage {public String getContent() {return HtmlContent.getPage(); // 分离 HTML 逻辑}
}

👍 正例优点:将不同语言和逻辑分离,提高代码的清晰度和可维护性。


概念:明显的行为未被实现

描述:如果某个功能或行为的定义存在但未实现,代码将会变得不完整或误导。应该确保函数和方法在设计时是有意义且实现的。

❌ 反例

void processOrder() {// 处理订单,但没有实际实现
}

✅ 正例

void processOrder(Order order) {// 处理订单的实际逻辑
}

👍 正例优点:每个函数和方法都清晰地定义了行为,避免了未实现的逻辑,提升了代码的完整性。


概念:不正确的边界行为

描述:当代码无法正确处理边界情况(如空值、极限值等)时,会引发错误或不可预见的行为。应确保每个边界条件都得到了妥善处理。

❌ 反例

int calculatePrice(int quantity) {return quantity * 10;
}

✅ 正例

int calculatePrice(int quantity) {if (quantity <= 0) {throw new IllegalArgumentException("Quantity must be greater than zero");}return quantity * 10;
}

👍 正例优点:正确处理边界情况,避免程序异常或不符合预期的行为。


概念:忽视安全

描述:在编写代码时忽视安全性可能会导致漏洞和安全隐患。应始终考虑到可能的攻击方式,确保代码安全。

❌ 反例

// 不进行任何验证,直接接受用户输入
String username = request.getParameter("username");

✅ 正例

// 对用户输入进行验证和过滤
String username = sanitizeInput(request.getParameter("username"));

👍 正例优点:通过适当的验证和过滤,增强了代码的安全性,防止潜在的安全漏洞。


概念:重复

描述:重复代码违反了 DRY(Don’t Repeat Yourself)原则。重复的代码增加了维护成本并且容易导致错误。应将重复的逻辑提取到独立的函数或方法中。

❌ 反例

void processOrder(Order order) {// 处理订单的重复代码
}void processPayment(Payment payment) {// 重复的支付处理代码
}

✅ 正例

void processOrder(Order order) {handleTransaction(order);
}void processPayment(Payment payment) {handleTransaction(payment);
}void handleTransaction(Object transaction) {// 提取公共的处理逻辑
}

👍 正例优点:减少了代码重复,提高了代码的可重用性和可维护性。


概念:在错误的抽象层级上的代码

描述:代码应当在适当的抽象层级上进行组织。如果代码的复杂性和细节太多,可能会影响上层逻辑的可读性。应确保每层代码都专注于其应有的责任。

❌ 反例

class CustomerService {void createOrder(Order order) {// 在业务逻辑层写数据库访问代码,增加了不必要的细节db.insert(order);}
}

✅ 正例

class CustomerService {void createOrder(Order order) {orderRepository.save(order);}
}class OrderRepository {void save(Order order) {db.insert(order);  // 数据访问层只负责数据库操作}
}

👍 正例优点:通过合理划分职责和抽象层级,使代码更具可维护性和可扩展性。


概念:基类依赖于派生类

描述:基类不应依赖于派生类,这会导致依赖方向错误,增加耦合度,降低系统的灵活性和可扩展性。

❌ 反例

class Shape {void draw() {if (this instanceof Circle) {// 依赖于派生类drawCircle();}}
}

✅ 正例

abstract class Shape {abstract void draw();
}class Circle extends Shape {void draw() {// 实现具体的绘制逻辑}
}

👍 正例优点:基类提供通用接口,避免了依赖派生类,使得代码更符合面向对象设计原则。


概念:信息过多

描述:代码中信息过多会导致混乱和难以理解。应通过适当的封装和分解将复杂的信息隐藏起来,保持代码的简洁和易读性。

❌ 反例

public class Product {String name;String description;double price;int stock;String category;// 包含过多信息
}

✅ 正例

public class Product {String name;double price;Category category;  // 将信息封装在 Category 对象中
}

👍 正例优点:通过封装相关数据减少了类的复杂度,使代码更简洁且易于维护。


概念:死代码

描述:死代码是指那些永远不会执行的代码或已经不再使用的代码。它增加了代码的复杂性,并且应该被删除。

❌ 反例

if (false) {// 永远不会执行的代码System.out.println("This will never be executed");
}

✅ 正例

// 删除无用代码

👍 正例优点:删除死代码可以减少代码冗余,提高代码的可维护性。

概念:垂直分隔

描述:垂直分隔指的是将代码逻辑分隔到不同的区域或层次,使得代码更加有序且易于理解。适当的垂直分隔能够提高代码的可读性,避免让开发者需要在一个长的函数或类中不断跳转来理解不同的功能块。

❌ 反例

void processOrder() {// 一开始做输入验证if (order == null) {throw new IllegalArgumentException("Order is null");}// 然后是支付处理if (!paymentSuccessful) {throw new PaymentException("Payment failed");}// 最后处理配送initiateShipping(order);
}

✅ 正例

void processOrder() {validateOrder(order);processPayment(order);initiateShipping(order);
}void validateOrder(Order order) {if (order == null) {throw new IllegalArgumentException("Order is null");}
}void processPayment(Order order) {if (!paymentSuccessful) {throw new PaymentException("Payment failed");}
}void initiateShipping(Order order) {// 配送逻辑
}

👍 正例优点:通过将逻辑进行垂直分隔,每个方法处理单一任务,使得代码更清晰,便于维护和扩展。


概念:前后不一致

描述:前后不一致是指代码的行为在不同的上下文中不一致或违反了预期的设计原则。代码应该保持一致性,使开发者能够预测代码的行为。

❌ 反例

// 根据不同条件采用不同的变量命名风格,给开发者带来困惑
int userAge = 25;
String userName = "Alice";
double userSalary = 5000;

✅ 正例

// 保持一致的命名风格
int age = 25;
String name = "Alice";
double salary = 5000;

👍 正例优点:通过一致的命名规范,使得代码更容易理解,并减少了开发人员的认知负担。


概念:混淆视听

描述:混淆视听指的是代码中使用不清晰、不直观的命名、结构或实现方式,使得开发者难以理解代码的实际意图。避免使用难以理解的代码,可以通过清晰的命名和简洁的结构提高代码的可读性。

❌ 反例

int x = 5;
int y = 10;
int z = x * y + 50;

✅ 正例

int width = 5;
int height = 10;
int area = width * height + 50;

👍 正例优点:通过清晰、直观的命名和结构,开发者能够立即理解变量的含义和代码的目的。


概念:人为耦合

描述:人为耦合是指通过不必要的方式将两个模块或类紧密绑定,使得修改一个部分时需要同时修改其他部分。代码应尽量保持松耦合,以便各个部分能够独立发展和维护。

❌ 反例

class User {private Order order;public void processOrder() {// User 类依赖 Order 类的实现细节,造成耦合order.process();}
}

✅ 正例

class User {private OrderProcessor orderProcessor;public void processOrder() {// User 类依赖 OrderProcessor 接口,而不是 Order 类本身orderProcessor.process();}
}

👍 正例优点:通过依赖接口而非具体实现,减少了类之间的耦合,提高了代码的灵活性和可扩展性。


概念:特性依恋

描述:特性依恋是指代码中存在依赖于特定实现的行为,而不是依赖于通用的接口或抽象。这会限制代码的灵活性和可扩展性,应避免依赖于特定的实现细节。

❌ 反例

class PaymentProcessor {private CreditCardProcessor creditCardProcessor;public void processPayment(Payment payment) {// 依赖于 CreditCardProcessor 实现creditCardProcessor.process(payment);}
}

✅ 正例

interface PaymentGateway {void processPayment(Payment payment);
}class CreditCardProcessor implements PaymentGateway {public void processPayment(Payment payment) {// 处理信用卡支付}
}class PaymentProcessor {private PaymentGateway paymentGateway;public void processPayment(Payment payment) {paymentGateway.processPayment(payment);  // 依赖于接口}
}

👍 正例优点:通过依赖接口而非具体实现,代码的可扩展性和灵活性大大增强,可以方便地引入其他支付方式。


概念:选择算子参数

描述:选择算子(例如 if/elseswitch/case)中的参数不应直接传递过多的选项或复杂条件。使用多个参数可能会使条件判断变得复杂且难以维护,应考虑使用枚举、策略模式等方式来简化选择条件。

❌ 反例

void handleRequest(int type) {if (type == 1) {// 处理订单请求} else if (type == 2) {// 处理支付请求} else if (type == 3) {// 处理退款请求}
}

✅ 正例

enum RequestType {ORDER, PAYMENT, REFUND
}void handleRequest(RequestType type) {switch (type) {case ORDER:// 处理订单请求break;case PAYMENT:// 处理支付请求break;case REFUND:// 处理退款请求break;}
}

👍 正例优点:通过使用枚举 RequestType,代码变得更加清晰,容易扩展和维护,同时避免了重复的 if/else 判断。

概念:晦涩的意图

描述:晦涩的意图是指代码的设计或实现不清楚,无法明确表达其目的或意图。这种代码可能导致开发者误解其功能或造成不必要的复杂性。代码应始终清晰表达意图,便于开发者理解。

❌ 反例

int calculate(int a, int b) {return (a * b) / (a - b); // 代码意图不明确
}

✅ 正例

int calculateRectangleArea(int width, int height) {return width * height; // 明确表达计算矩形面积的意图
}

👍 正例优点:清晰的命名和功能,使代码的意图一目了然,易于理解和维护。


概念:位置错误的权责

描述:代码中每个模块或类的责任应当与其所处的层级和位置相匹配。避免将不相关的功能放置在不合适的地方。责任应在正确的层级上实现,确保代码职责明确。

❌ 反例

class UserService {public void saveOrder(Order order) {// 直接在业务层进行数据库操作db.insert(order);}
}

✅ 正例

class UserService {private OrderRepository orderRepository;public void saveOrder(Order order) {orderRepository.save(order);  // 让责任分明,数据访问层专注于数据操作}
}class OrderRepository {public void save(Order order) {db.insert(order); // 数据访问操作}
}

👍 正例优点:职责分离,业务逻辑层与数据访问层清晰划分,易于维护和扩展。


概念:不恰当的静态方法

描述:静态方法应仅用于那些与对象状态无关的功能。过度使用静态方法会导致代码难以扩展和测试,应避免将对象的状态逻辑和行为放入静态方法中。

❌ 反例

class User {static String getUserInfo(String userId) {// 使用静态方法访问和修改实例变量,破坏了对象的封装性return userId + " info";}
}

✅ 正例

class User {String userId;public String getUserInfo() {// 通过实例方法访问对象的状态return userId + " info";}
}

👍 正例优点:通过实例方法访问和修改对象状态,保持了对象封装性,增加了灵活性和可测试性。


概念:使用解释性变量

描述:解释性变量是指那些通过描述性的命名解释代码逻辑的变量。这种命名可以减少代码中注释的需要,让代码自解释,从而提高可读性。

❌ 反例

int a = 10;
int b = 20;
int c = a * b; // 变量命名没有表达清晰的含义

✅ 正例

int width = 10;
int height = 20;
int area = width * height;  // 变量命名清晰,表达了代码的意图

👍 正例优点:通过描述性的变量命名,代码变得更具自解释性,减少了对注释的依赖。


概念:函数名称应该表达其行为

描述:函数名称应该清楚地表达其行为和目的,而不仅仅是简单描述其操作。清晰的函数名可以帮助开发者更好地理解代码的功能,避免歧义。

❌ 反例

void doStuff() {// 函数名称没有明确表达其行为
}

✅ 正例

void calculateTotalPrice(Order order) {// 函数名称明确表达了其计算总价的行为
}

👍 正例优点:清晰的函数名称帮助开发者快速理解代码意图,减少了对文档和注释的依赖。


概念:理解算法

描述:编写代码时,应确保所使用的算法被完全理解。对算法的深入理解能帮助开发者写出高效、可维护的代码。避免使用不明白的算法或难以优化的复杂算法。

❌ 反例

void calculate(int[] arr) {// 只知道用排序来实现某个功能,但未深刻理解排序算法的效率Arrays.sort(arr);
}

✅ 正例

void calculate(int[] arr) {// 理解快速排序算法并实现quickSort(arr, 0, arr.length - 1);
}

👍 正例优点:通过深入理解和应用合适的算法,代码效率高,容易优化,且具备较好的可维护性。

概念:把逻辑依赖改为物理依赖

描述:逻辑依赖是指代码的行为依赖于某些特定的条件或顺序,而物理依赖则是指代码通过明确的对象或模块依赖来实现功能。为了提高代码的灵活性和可维护性,应尽量避免逻辑依赖,改为物理依赖。

❌ 反例

class OrderProcessor {private boolean isUserRegistered;private boolean isPaymentSuccessful;void processOrder(Order order) {if (isUserRegistered) {// 处理注册用户订单} else {// 处理未注册用户订单}if (isPaymentSuccessful) {// 处理支付成功的订单} else {// 处理支付失败的订单}}
}

✅ 正例

class OrderProcessor {private UserRegistrationService registrationService;private PaymentService paymentService;void processOrder(Order order) {if (registrationService.isUserRegistered(order)) {// 处理注册用户订单}if (paymentService.isPaymentSuccessful(order)) {// 处理支付成功的订单}}
}

👍 正例优点:通过物理依赖,代码更加模块化、清晰,且易于测试和扩展。


概念:用多态代替 if/else 或者 switch/case

描述:多态可以用来代替繁杂的 if/elseswitch/case 语句。通过继承和接口,使用多态可以使得代码更具扩展性和可维护性,避免使用大量的条件判断。

❌ 反例

class PaymentProcessor {void processPayment(Payment payment) {if (payment.getType() == PaymentType.CREDIT_CARD) {// 处理信用卡支付} else if (payment.getType() == PaymentType.PAYPAL) {// 处理 PayPal 支付} else if (payment.getType() == PaymentType.BANK_TRANSFER) {// 处理银行转账支付}}
}

✅ 正例

interface PaymentMethod {void processPayment(Payment payment);
}class CreditCardPayment implements PaymentMethod {void processPayment(Payment payment) {// 处理信用卡支付}
}class PaypalPayment implements PaymentMethod {void processPayment(Payment payment) {// 处理 PayPal 支付}
}class PaymentProcessor {void processPayment(PaymentMethod paymentMethod) {paymentMethod.processPayment(payment);}
}

👍 正例优点:通过多态替代条件判断,使得代码更加灵活,增加新支付方式时无需修改现有代码。


概念:遵循标准约定

描述:代码应遵循一定的标准和约定,这样可以提高团队协作效率,保证代码的一致性,并且便于新成员理解和维护代码。遵循标准约定可以避免编码风格上的不一致。

❌ 反例

public class user {public static void Main() {// 不遵循 Java 编码标准}
}

✅ 正例

public class User {public static void main(String[] args) {// 遵循 Java 编码标准}
}

👍 正例优点:代码遵循一致的标准和约定,使团队协作更高效,代码风格一致,便于后续维护。


概念:用命名常量代替魔术数

描述:魔术数是指代码中硬编码的常量值,这些数字没有明确的意义,容易造成混淆。为了提高代码的可读性和可维护性,应使用命名常量来替代魔术数。

❌ 反例

class DiscountCalculator {double calculateDiscount(double price) {return price * 0.1;  // 0.1 是魔术数,不清楚其含义}
}

✅ 正例

class DiscountCalculator {static final double DISCOUNT_RATE = 0.1;double calculateDiscount(double price) {return price * DISCOUNT_RATE;  // 使用命名常量代替魔术数}
}

👍 正例优点:通过使用命名常量,代码变得更加易读,常量的含义更加明确,便于修改和维护。


概念:准确

描述:代码应尽量保持准确性,避免不必要的模糊或错误的实现。准确的代码能够减少误解和潜在的bug,提高代码的可靠性。

❌ 反例

class TaxCalculator {double calculateTax(double price) {return price * 0.15;  // 税率硬编码,可能并不适用所有地区}
}

✅ 正例

class TaxCalculator {static final double TAX_RATE = 0.15;double calculateTax(double price) {return price * TAX_RATE;  // 通过使用常量,保证税率的准确性和可修改性}
}

👍 正例优点:通过准确的常量和实现,代码的行为更加可预测,并且可以减少潜在的错误。

概念:结构甚于约定

描述:结构化的代码应该优先于约定,代码中的结构应当清晰表达设计意图。依赖于复杂的约定会增加理解难度,而良好的结构能直观地表达设计,减少对解释和理解的依赖。

❌ 反例

class OrderProcessor {// 使用了约定方法名,但结构不清晰void processOrder(Order order) {if (order.isPaid()) {// 确保支付}}
}

✅ 正例

class OrderProcessor {void processPaidOrder(PaidOrder paidOrder) {// 清晰的结构,明确的功能}
}

👍 正例优点:代码结构清晰,易于理解和扩展,无需依赖复杂的命名或约定,减少了理解代码的难度。


概念:封装条件

描述:条件表达式应该被封装在方法或对象中,避免将复杂的条件逻辑暴露在业务逻辑中。通过封装条件,代码的意图更加明确,且易于修改和扩展。

❌ 反例

class DiscountCalculator {double calculateDiscount(Order order) {if (order.isVip() && order.getTotalAmount() > 1000) {return order.getTotalAmount() * 0.1;}return 0;}
}

✅ 正例

class DiscountCalculator {double calculateDiscount(Order order) {DiscountCondition discountCondition = new DiscountCondition(order);if (discountCondition.isVipAndEligibleForDiscount()) {return order.getTotalAmount() * 0.1;}return 0;}
}class DiscountCondition {private Order order;DiscountCondition(Order order) {this.order = order;}boolean isVipAndEligibleForDiscount() {return order.isVip() && order.getTotalAmount() > 1000;}
}

👍 正例优点:条件逻辑被封装在一个独立的类中,业务逻辑更加简洁清晰,便于修改和扩展。


概念:避免否定性条件

描述:否定性条件(如 if (!condition))会导致代码理解上的混乱,增加开发者的认知负担。应尽量使用肯定的条件来提高代码的可读性。

❌ 反例

if (!user.isActive()) {// 处理未激活用户
}

✅ 正例

if (user.isInactive()) {// 处理未激活用户
}

👍 正例优点:通过避免否定性条件,代码更具可读性,减少了对逻辑的理解难度。


概念:函数只做一件事

描述:函数应当只做一件事,并且做好这件事。如果一个函数承担了多重责任,代码的可读性和可维护性都会受到影响。

❌ 反例

void saveOrderAndSendEmail(Order order) {saveOrder(order); // 保存订单sendEmail(order); // 发送邮件
}

✅ 正例

void saveOrder(Order order) {// 保存订单
}void sendEmail(Order order) {// 发送邮件
}

👍 正例优点:每个函数只做一件事,职责单一,便于修改、扩展和单元测试。


概念:掩蔽时序耦合

描述:时序耦合指的是程序中某些操作的执行顺序强烈依赖于前一个操作的结果。通过掩蔽时序耦合,可以提高代码的灵活性,使得操作的顺序不那么依赖于特定的执行时机。

❌ 反例

class ReportGenerator {void generateReport() {loadData();processData();displayReport();}void loadData() {// 加载数据}void processData() {// 处理数据}void displayReport() {// 显示报告}
}

✅ 正例

class ReportGenerator {void generateReport() {loadData();processData();}void loadData() {// 加载数据}void processData() {// 处理数据}void saveReport() {// 保存报告}void displayReport() {// 显示报告}
}

👍 正例优点:通过掩蔽时序耦合,操作顺序更加灵活,模块化程度提高,代码更易维护。


概念:别随意

描述:编写代码时要避免随意性,应当遵循一定的规则和原则。随意的代码设计和实现会导致代码难以理解和维护。

❌ 反例

class User {String name;int age;// 随意添加了字段,不符合业务需求
}

✅ 正例

class User {String name;int age;// 只添加与用户相关的字段
}

👍 正例优点:避免随意性,代码结构清晰,便于后期维护和扩展。


概念:封装边界条件

描述:边界条件(如 null 值或极限值)应该被封装起来,而不是直接暴露给代码的其余部分。这样可以减少代码中的条件判断,提高代码的稳定性。

❌ 反例

void processOrder(Order order) {if (order == null) {// 处理 null 值}if (order.getItems() == null) {// 处理空项}
}

✅ 正例

void processOrder(Order order) {if (order != null && order.hasItems()) {// 处理有效订单}
}class Order {List<Item> items;boolean hasItems() {return items != null && !items.isEmpty();}
}

👍 正例优点:通过封装边界条件,业务逻辑代码变得更加简洁和健壮,减少了空值和边界判断的复杂度。


概念:函数应该只在一个抽象层级上

描述:函数应专注于处理一个抽象层级的问题,不应跨越多个抽象层级。将复杂的函数分解为多个小函数,每个函数处理一个清晰的责任。

❌ 反例

void processPayment(Order order) {if (order.isValid()) {processPaymentGateway(order);updateOrderStatus(order);}
}

✅ 正例

void processPayment(Order order) {if (order.isValid()) {processPaymentGateway(order);}
}void updateOrderStatus(Order order) {order.setStatus("Paid");
}

👍 正例优点:每个函数只处理一个抽象层级,代码更清晰,易于理解和维护。


概念:在较高层级放置可配置数据

描述:可配置的数据(如应用程序设置或常量值)应当放置在较高层级,以便于统一管理和修改。避免将可配置的数据硬编码在底层逻辑中。

❌ 反例

class PaymentProcessor {void processPayment(Order order) {if (order.getAmount() > 1000) {// 使用硬编码的值applyDiscount(order);}}
}

✅ 正例

class PaymentProcessor {static final double DISCOUNT_THRESHOLD = 1000;void processPayment(Order order) {if (order.getAmount() > DISCOUNT_THRESHOLD) {applyDiscount(order);}}
}

👍 正例优点:通过集中管理可配置的数据,代码更加灵活,便于修改和扩展。


概念:避免传递浏览

描述:浏览是一种获取对象属性或状态的方式,通过传递浏览方式的对象,代码可能变得难以理解和不清晰。应避免传递对象的浏览方法,改为传递必要的参数。

❌ 反例

class User {String name;String email;
}class EmailSender {void sendEmail(User user) {// 通过浏览 User 对象来获取属性String userEmail = user.email;send(userEmail);}
}

✅ 正例

class EmailSender {void sendEmail(String email) {send(email); // 只传递必要的信息}
}

👍 正例优点:避免了不必要的对象依赖,使得代码更加简洁且易于理解。

5 Java

概念:通过使用通配符避免过长的导入清单

描述:在导入包时,使用通配符(*)可以减少导入语句的数量,尤其当你需要从同一包中导入多个类时,通配符可以使代码看起来更简洁。但这种做法可能会引入一些问题,尤其是会使得代码的依赖关系不明确。

❌ 反例

import java.util.*; // 导入整个包,可能导致命名冲突

✅ 正例

import java.util.List; // 仅导入需要的类,避免命名冲突
import java.util.ArrayList;

👍 正例优点:明确显示需要使用的类,避免不必要的类导入,提升代码可读性,避免命名冲突。


概念:不要继承常量

描述:常量应当作为独立的值来使用,而不是作为继承的成员。这是因为常量的意义通常是固定的,继承常量会让其失去原本的含义和清晰性,增加代码的耦合性。

❌ 反例

class SuperClass {public static final String ERROR_MESSAGE = "Error!";
}class SubClass extends SuperClass {// 继承了父类的常量,造成代码耦合
}

✅ 正例

class ErrorMessages {public static final String ERROR_MESSAGE = "Error!";
}

👍 正例优点:常量独立于类的继承层次,更加清晰和易于维护,减少了代码的耦合。


概念:常量 VS 枚举

描述:常量和枚举都可以用来表示固定的值集合,但它们的使用场景不同。常量适用于有限的固定值,而枚举类型适用于一组相关的常量值,它具有更多的功能性,例如方法、字段等。使用枚举可以提高代码的可读性和类型安全性。

❌ 反例(使用常量):

public class Status {public static final int PENDING = 1;public static final int APPROVED = 2;public static final int REJECTED = 3;
}

✅ 正例(使用枚举):

public enum Status {PENDING,APPROVED,REJECTED;
}

👍 正例优点:枚举类型提供更好的类型安全性和代码可读性,能够扩展更多功能(如方法和字段),并且避免了使用常量时的错误传递和管理问题。

6 名称

概念:采用描述性名称

描述:变量、函数、类等的名称应当能清晰地反映其作用和意图,避免使用模糊的或难以理解的名称。通过采用描述性名称,代码的可读性和可维护性得以提高。

❌ 反例

int x; // 不清晰的变量名

✅ 正例

int totalAmount; // 描述性名称,明确表示该变量的作用

👍 正例优点:描述性名称让代码的含义更加直观,其他开发者能够快速理解其功能和用途,减少理解代码时的认知负担。


概念:名称应与抽象层级相符合

描述:名称应与其所处的抽象层级相匹配。例如,高层次的类或方法应该有较为抽象的名称,而低层次的实现方法或变量则应有更具体的名称。

❌ 反例

class FileHandler {void saveToFile(String content) {// 实现细节混杂在高层次的名称中}
}

✅ 正例

class FileSaver {void save(String content) {// 更符合其职责和抽象层级}
}

👍 正例优点:通过匹配抽象层级,代码层次更加清晰,职责划分明确,代码更具可维护性。


概念:尽可能使用标准命名法

描述:遵循行业或语言约定的标准命名法可以提高代码的可理解性,使得其他开发者能够更容易地理解你的代码并且快速上手。标准命名法能够减少混乱,增强团队协作。

❌ 反例

int MyNumber; // 不符合命名标准

✅ 正例

int myNumber; // 遵循标准的命名法,符合Java的命名惯例

👍 正例优点:遵循标准命名法使代码风格统一,便于团队合作,减少了因命名不规范造成的混乱和错误。


概念:无歧义名称

描述:变量、函数、类等的名称应避免含有歧义。歧义的名称可能导致误解和错误,尤其在多人协作开发时,歧义性会带来更大的风险。

❌ 反例

int status; // 状态不明确,可能指代多种不同的状态

✅ 正例

int orderStatus; // 明确表示订单的状态

👍 正例优点:无歧义名称使代码的意图更加明确,降低理解错误的风险,提高代码的清晰度和可维护性。


概念:为较大作用范围选用较长名称

描述:当一个变量或函数的作用范围较大时,名称应更加具体和详细,以反映其较大的影响范围。相对地,较小作用范围的变量或函数名称可以更简短。

❌ 反例

int count; // 在类中作为全局变量使用,名称过于简短

✅ 正例

int totalItemCount; // 表明是全局变量,并描述了其作用范围

👍 正例优点:较长的名称可以清楚地表明变量或函数的作用范围和意义,减少混淆,增强代码的可读性。


概念:避免编码

描述:编码(如 x, y, temp 等)作为变量名应当尽量避免使用。编码并不具备描述性,无法表达变量的真实意义,可能会造成代码理解上的困难。

❌ 反例

int a; // 没有任何描述意义的变量名

✅ 正例

int itemCount; // 明确描述该变量的作用

👍 正例优点:避免编码使变量名称具有实际意义,能更容易让开发者理解其作用,提升代码的可读性。


概念:名称应说明其副作用

描述:当一个函数或方法具有副作用时,其名称应明确表达这一点。副作用是指除了返回值外,还会修改状态或产生其他影响。通过名称提示副作用,能够帮助开发者在使用时更好地理解该方法的行为。

❌ 反例

void update(User user) {// 可能会修改多个不相关的状态,名称不明确
}

✅ 正例

void updateUserStatus(User user) {// 明确指出方法的副作用:更新用户状态
}

👍 正例优点:通过明确命名,能够提高代码的透明度,减少副作用带来的误用和意外结果。

相关文章:

  • C# 创建线程的方式
  • 基于LLM合成高质量情感数据,提升情感分类能力!!
  • 程序人生-Hello’s P2P
  • C语言| 指针变量的定义
  • c++ 运算符重载
  • 【LINUX操作系统】生产者消费者模型(下):封装、信号量与环形队列
  • 【Spring】Spring的请求处理
  • SVGPlay:一次 CodeBuddy 主动构建的动画工具之旅
  • 融智学视域下的系统性认知增强框架——基于文理工三类AI助理赋能HI四阶跃迁路径
  • Linux调试生成核心存储文件
  • python线程相关讲解
  • 从0到1:Python项目部署与运维全攻略(10/10)
  • Flowbite 和 daisyUI 那个好用?
  • 数字化转型- 数字化转型路线和推进
  • 【四川省专升本计算机基础】第二章 计算机软硬件基础(2)
  • USRP 射频信号 采集 回放 系统
  • Python基础学习-Day27
  • 【Changer解码头详解及融入neck层数据的实验设计】
  • C#与KepOPC通讯
  • 手动实现 Transformer 模型
  • 三方合作会否受政局变化影响?“中日韩+”智库合作论坛在沪举行
  • 第十一届世界雷达展开幕,尖端装备、“大国重器”集中亮相
  • 美国贸易政策|特朗普模式:你想做交易吗?
  • 上海博物馆展览进校园,“小先生”传递文物知识
  • “养胃骗局”大公开,真正有用的方法究竟是?
  • “女硕士失踪13年生两孩”案进入审查起诉阶段,哥哥:妹妹精神状态好转