在这篇文章中,我们探讨了15个代码重构的小技巧,从简单的提取方法到高级的设计模式应用。这些技巧可以帮助我们写出更加简洁、可读、可维护的代码。代码重构是一个持续的过程,我们应该在日常开发中不断地应用这些技巧,逐步改进我们的代码质量。
前言
相信很多小伙伴在日常工作中都会遇到这样的情况:接手了一个历史项目,代码像一团乱麻。
或者自己写的代码随着业务的不断迭代,变得越来越臃肿难以维护。
这时候,代码重构就显得尤为重要了。
那么,如何进行高效的代码重构呢?
这篇文章我跟大家大家一起聊聊15个实用的代码重构技巧,希望对你会有所帮助。
1. 提取方法
有些小伙伴在工作中可能会写出这样的代码:一个方法几百行,里面包含了各种业务逻辑。
这样的代码不仅难以阅读,也难以维护和测试。
重构前:
复制
public void processOrder(Order order) {
// 验证订单
if (order == null) {
throw new IllegalArgumentException("订单不能为空");
}
if (order.getItems() == null || order.getItems().isEmpty()) {
throw new IllegalArgumentException("订单项不能为空");
}
if (order.getCustomer() == null) {
throw new IllegalArgumentException("客户信息不能为空");
}
// 计算订单总价
double total = 0;
for (OrderItem item : order.getItems()) {
double price = item.getPrice();
int quantity = item.getQuantity();
total += price * quantity;
}
// 应用折扣
if (order.getCustomer().isVip()) {
total = total * 0.9;
}
// 保存订单
order.setTotal(total);
orderRepository.save(order);
// 发送通知
String message = "订单" + order.getId() + "已处理,总价:" +
total;
emailService.sendEmail(order.getCustomer().getEmail(), "订单处理
通知", message);
smsService.sendSms(order.getCustomer().getPhone(), message);
}
重构后:
public void processOrder(Order order) {
validateOrder(order);
double total = calculateOrderTotal(order);
total = applyDiscount(order, total);
saveOrder(order, total);
sendNotifications(order, total);
}
private void validateOrder(Order order) {
if (order == null) {
thrownew IllegalArgumentException("订单不能为空");
}
if (order.getItems() == null || order.getItems().isEmpty()) {
thrownew IllegalArgumentException("订单项不能为空");
}
if (order.getCustomer() == null) {
thrownew IllegalArgumentException("客户信息不能为空");
}
}
private double calculateOrderTotal(Order order) {
double total = 0;
for (OrderItem item : order.getItems()) {
double price = item.getPrice();
int quantity = item.getQuantity();
total += price * quantity;
}
return total;
}
private double applyDiscount(Order order, double total) {
if (order.getCustomer().isVip()) {
return total * 0.9;
}
return total;
}
private void saveOrder(Order order, double total) {
order.setTotal(total);
orderRepository.save(order);
}
private void sendNotifications(Order order, double total) {
String message = "订单" + order.getId() + "已处理,总价:" +
total;
emailService.sendEmail(order.getCustomer().getEmail(), "订单处理
通知", message);
smsService.sendSms(order.getCustomer().getPhone(), message);
}
通过提取方法,我们将一个大方法拆分成了多个小方法,每个方法只负责一个功能。
这样不仅提高了代码的可读性,也使得每个方法更容易测试和维护。
2. 引入解释性变量
有时候,一个复杂的表达式可能难以理解。
这时,我们可以引入一个解释性变量来提高代码的可读性。
重构前:
public boolean isEligibleForDiscount(Customer customer, Order
order) {
return (customer.getAge() >= 60 || (customer.getMembershipYears
() > 5 && order.getTotal() > 1000)) && !customer.
hasOutstandingPayments();
}
重构后:
public boolean isEligibleForDiscount(Customer customer, Order
order) {
boolean isSenior = customer.getAge() >= 60;
boolean isLoyalCustomerWithLargeOrder = customer.
getMembershipYears() > 5 && order.getTotal() > 1000;
boolean hasNoOutstandingPayments = !customer.
hasOutstandingPayments();
return (isSenior || isLoyalCustomerWithLargeOrder) &&
hasNoOutstandingPayments;
}
通过引入解释性变量,我们使得复杂的条件表达式更加清晰易懂。每个变量都有一个描述性的名称,使得代码的意图更加明确。
3. 替换条件表达式
有些小伙伴在处理不同类型的对象时,可能会使用大量的条件语句(if-else或switch)。
这样的代码不仅冗长,而且每次添加新类型都需要修改这些条件语句,违反了开闭原则。
重构前:
public class PaymentProcessor {
public void processPayment(Payment payment) {
if (payment.getType().equals("CREDIT_CARD")) {
// 处理信用卡支付
validateCreditCard(payment);
chargeCreditCard(payment);
} else if (payment.getType().equals("PAYPAL")) {
// 处理PayPal支付
validatePayPalAccount(payment);
chargePayPalAccount(payment);
} else if (payment.getType().equals("BANK_TRANSFER")) {
// 处理银行转账
validateBankAccount(payment);
initiateTransfer(payment);
} else {
throw new IllegalArgumentException("不支持的支付类型:" +
payment.getType());
}
}
// 其他方法...
}
重构后:
public interface PaymentProcessor {
void processPayment(Payment payment);
}
public class CreditCardProcessor implements PaymentProcessor {
@Override
public void processPayment(Payment payment) {
validateCreditCard(payment);
chargeCreditCard(payment);
}
// 其他方法...
}
public class PayPalProcessor implements PaymentProcessor {
@Override
public void processPayment(Payment payment) {
validatePayPalAccount(payment);
chargePayPalAccount(payment);
}
// 其他方法...
}
public class BankTransferProcessor implements PaymentProcessor {
@Override
public void processPayment(Payment payment) {
validateBankAccount(payment);
initiateTransfer(payment);
}
// 其他方法...
}
public class PaymentFactory {
public static PaymentProcessor getProcessor(String paymentType)
{
if (paymentType.equals("CREDIT_CARD")) {
return new CreditCardProcessor();
} elseif (paymentType.equals("PAYPAL")) {
return new PayPalProcessor();
} elseif (paymentType.equals("BANK_TRANSFER")) {
return new BankTransferProcessor();
} else {
throw new IllegalArgumentException("不支持的支付类型:" +
paymentType);
}
}
}
// 使用
PaymentProcessor processor = PaymentFactory.getProcessor(payment.
getType());
processor.processPayment(payment);
通过使用多态,我们将不同类型的支付处理逻辑分散到各自的类中,使得代码更加模块化,也更容易扩展。
当需要添加新的支付类型时,只需创建一个新的处理器类,而不需要修改现有的代码。
4. 移除重复代码
代码重复是软件开发中的一大问题。
重复的代码不仅增加了代码量,也增加了维护的难度。当需要修改一个功能时,可能需要在多个地方进行相同的修改,这增加了出错的可能性。
重构前:
public class UserService {
public User findUserById(Long id) {
// 记录日志
Logger logger = LoggerFactory.getLogger(UserService.class);
logger.info("查询用户,ID:" + id);
// 查询用户
User user = userRepository.findById(id);
if (user == null) {
logger.error("用户不存在,ID:" + id);
thrownew UserNotFoundException("用户不存在,ID:" + id);
}
return user;
}
public User findUserByEmail(String email) {
// 记录日志
Logger logger = LoggerFactory.getLogger(UserService.class);
logger.info("查询用户,Email:" + email);
// 查询用户
User user = userRepository.findByEmail(email);
if (user == null) {
logger.error("用户不存在,Email:" + email);
thrownew UserNotFoundException("用户不存在,Email:" +
email);
}
return user;
}
}
重构后:
public class UserService {
private static final Logger logger = LoggerFactory.getLogger
(UserService.class);
public User findUserById(Long id) {
logger.info("查询用户,ID:" + id);
return findUserOrThrow(() -> userRepository.findById(id), "
用户不存在,ID:" + id);
}
public User findUserByEmail(String email) {
logger.info("查询用户,Email:" + email);
return findUserOrThrow(() -> userRepository.findByEmail
(email), "用户不存在,Email:" + email);
}
private User findUserOrThrow(Supplier<User> finder, String
errorMessage) {
User user = finder.get();
if (user == null) {
logger.error(errorMessage);
throw new UserNotFoundException(errorMessage);
}
return user;
}
}
通过提取公共方法,我们消除了重复代码,使得代码更加简洁。
当需要修改查询用户的逻辑时,只需要修改一个地方,而不是多个地方。
5. 引入参数对象
当一个方法有多个参数时,特别是当这些参数经常一起出现时,可以考虑将它们封装成一个对象。
重构前:
public class ReportGenerator {
public Report generateReport(String startDate, String endDate,
String department, String format, boolean includeCharts) {
// 生成报告的逻辑
// ...
}
public void emailReport(String startDate, String endDate,
String department, String format, boolean includeCharts, String
email) {
Report report = generateReport(startDate, endDate,
department, format, includeCharts);
// 发送报告的逻辑
// ...
}
public void saveReport(String startDate, String endDate, String
department, String format, boolean includeCharts, String
filePath) {
Report report = generateReport(startDate, endDate,
department, format, includeCharts);
// 保存报告的逻辑
// ...
}
}
重构后:
public class ReportCriteria {
private String startDate;
private String endDate;
private String department;
private String format;
private boolean includeCharts;
// 构造函数、getter和setter
// ...
}
public class ReportGenerator {
public Report generateReport(ReportCriteria criteria) {
// 生成报告的逻辑
// ...
}
public void emailReport(ReportCriteria criteria, String email) {
Report report = generateReport(criteria);
// 发送报告的逻辑
// ...
}
public void saveReport(ReportCriteria criteria, String
filePath) {
Report report = generateReport(criteria);
// 保存报告的逻辑
// ...
}
}
通过引入参数对象,我们减少了方法的参数数量,使得方法调用更加简洁。同时,参数对象也可以包含与这些参数相关的行为,进一步提高代码的内聚性。
6. 使用策略模式
有些小伙伴在处理不同的算法或策略时,可能会使用大量的条件语句。
这样的代码不仅难以维护,也难以扩展。
重构前:
public class ShippingCalculator {
public double calculateShippingCost(Order order, String
shippingMethod) {
if (shippingMethod.equals("STANDARD")) {
// 标准运费计算逻辑
return order.getWeight() * 0.5;
} else if (shippingMethod.equals("EXPRESS")) {
// 快递运费计算逻辑
return order.getWeight() * 1.0 + 10;
} else if (shippingMethod.equals("OVERNIGHT")) {
// 隔夜运费计算逻辑
return order.getWeight() * 1.5 + 20;
} else {
throw new IllegalArgumentException("不支持的运输方式:" +
shippingMethod);
}
}
}
重构后:
public interface ShippingStrategy {
double calculateShippingCost(Order order);
}
public class StandardShipping implements ShippingStrategy {
@Override
public double calculateShippingCost(Order order) {
return order.getWeight() * 0.5;
}
}
public class ExpressShipping implements ShippingStrategy {
@Override
public double calculateShippingCost(Order order) {
return order.getWeight() * 1.0 + 10;
}
}
public class OvernightShipping implements ShippingStrategy {
@Override
public double calculateShippingCost(Order order) {
return order.getWeight() * 1.5 + 20;
}
}
public class ShippingCalculator {
private Map<String, ShippingStrategy> strategies = new HashMap<>
();
public ShippingCalculator() {
strategies.put("STANDARD", new StandardShipping());
strategies.put("EXPRESS", new ExpressShipping());
strategies.put("OVERNIGHT", new OvernightShipping());
}
public double calculateShippingCost(Order order, String
shippingMethod) {
ShippingStrategy strategy = strategies.get(shippingMethod);
if (strategy == null) {
thrownew IllegalArgumentException("不支持的运输方式:" +
shippingMethod);
}
return strategy.calculateShippingCost(order);
}
}
通过使用策略模式,我们将不同的运费计算逻辑分散到各自的类中,使得代码更加模块化,也更容易扩展。
当需要添加新的运输方式时,只需创建一个新的策略类,并将其添加到策略映射中,而不需要修改现有的代码。
7. 使用构建者模式
当一个类有多个构造参数时,特别是当有些参数是可选的时,可以考虑使用构建者模式。
重构前:
复制
public class User {
private String username;
private String email;
private String firstName;
private String lastName;
private String phone;
private String address;
private String city;
private String country;
private String postalCode;
// 构造函数
public User(String username, String email) {
this.username = username;
this.email = email;
}
public User(String username, String email, String firstName,
String lastName) {
this.username = username;
this.email = email;
this.firstName = firstName;
this.lastName = lastName;
}
public User(String username, String email, String firstName,
String lastName, String phone) {
this.username = username;
this.email = email;
this.firstName = firstName;
this.lastName = lastName;
this.phone = phone;
}
// 更多构造函数...
// getter和setter
// ...
}
重构后:
public class User {
private String username;
private String email;
private String firstName;
private String lastName;
private String phone;
private String address;
private String city;
private String country;
private String postalCode;
private User(Builder builder) {
this.username = builder.username;
this.email = builder.email;
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.phone = builder.phone;
this.address = builder.address;
this.city = builder.city;
this.country = builder.country;
this.postalCode = builder.postalCode;
}
// getter(没有setter,使对象不可变)
// ...
public static class Builder {
// 必需参数
private final String username;
private final String email;
// 可选参数
private String firstName;
private String lastName;
private String phone;
private String address;
private String city;
private String country;
private String postalCode;
public Builder(String username, String email) {
this.username = username;
this.email = email;
}
public Builder firstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder lastName(String lastName) {
this.lastName = lastName;
return this;
}
public Builder phone(String phone) {
this.phone = phone;
return this;
}
public Builder address(String address) {
this.address = address;
return this;
}
public Builder city(String city) {
this.city = city;
returnthis;
}
public Builder country(String country) {
this.c ountry = country;
return this;
}
public Builder postalCode(String postalCode) {
this.postalCode = postalCode;
return this;
}
public User build() {
return new User(this);
}
}
}
// 使用
User user = new User.Builder("johndoe", "john.doe@example.com")
.firstName("John")
.lastName("Doe")
.phone("1234567890")
.build();
通过使用构建者模式,我们解决了构造函数参数过多的问题,使得对象创建更加灵活和可读。
同时,构建者模式也可以确保对象在创建后是不可变的,提高了代码的安全性。
8. 使用工厂方法
当对象的创建逻辑比较复杂时,可以考虑使用工厂方法。
重构前:
public class ProductService {
public Product createProduct(String type, String name, double
price) {
Product product;
if (type.equals("PHYSICAL")) {
product = new PhysicalProduct(name, price);
// 设置物理产品的属性
// ...
} else if (type.equals("DIGITAL")) {
product = new DigitalProduct(name, price);
// 设置数字产品的属性
// ...
} else if (type.equals("SUBSCRIPTION")) {
product = new SubscriptionProduct(name, price);
// 设置订阅产品的属性
// ...
} else {
throw new IllegalArgumentException("不支持的产品类型:" +
type);
}
return product;
}
}
重构后:
public abstract class ProductFactory {
public static Product createProduct(String type, String name,
double price) {
if (type.equals("PHYSICAL")) {
return createPhysicalProduct(name, price);
} else if (type.equals("DIGITAL")) {
return createDigitalProduct(name, price);
} else if (type.equals("SUBSCRIPTION")) {
return createSubscriptionProduct(name, price);
} else {
thrownew IllegalArgumentException("不支持的产品类型:" +
type);
}
}
private static Product createPhysicalProduct(String name,
double price) {
PhysicalProduct product = new PhysicalProduct(name, price);
// 设置物理产品的属性
// ...
return product;
}
private static Product createDigitalProduct(String name, double
price) {
DigitalProduct product = new DigitalProduct(name, price);
// 设置数字产品的属性
// ...
return product;
}
private static Product createSubscriptionProduct(String name,
double price) {
SubscriptionProduct product = new SubscriptionProduct(name,
price);
// 设置订阅产品的属性
// ...
return product;
}
}
// 使用
Product product = ProductFactory.createProduct("PHYSICAL", "书籍",
29.99);
通过使用工厂方法,我们将对象的创建逻辑从客户端代码中分离出来,使得代码更加模块化,也更容易维护。
当需要添加新的产品类型时,只需在工厂类中添加相应的创建方法,而不需要修改客户端代码。
9. 使用Optional避免空指针异常
空指针异常(NullPointerException)是Java中最常见的异常之一。
为了避免这种异常,我们可以使用Java 8引入的Optional类。
重构前:
public class UserService {
public User findUserById(Long id) {
// 查询用户
return userRepository.findById(id);
}
public String getUserEmail(Long id) {
User user = findUserById(id);
if (user != null) {
String email = user.getEmail();
if (email != null) {
return email;
}
}
return"未知";
}
}
public class UserService {
public Optional<User> findUserById(Long id) {
// 查询用户
User user = userRepository.findById(id);
return Optional.ofNullable(user);
}
public String getUserEmail(Long id) {
return findUserById(id)
.map(User::getEmail)
.orElse("未知");
}
}
通过使用Optional,我们明确表示方法可能返回空值,使得代码更加清晰。
同时,Optional提供了丰富的API,如map、filter、orElse等,使得处理可能为空的值更加方便。
10. 使用Stream API简化集合操作
Java 8引入的Stream API提供了一种函数式编程的方式来处理集合,使得代码更加简洁和可读。
重构前:
public class OrderService {
public List<Order> findLargeOrders(List<Order> orders) {
List<Order> largeOrders = new ArrayList<>();
for (Order order : orders) {
if (order.getTotal() > 1000) {
largeOrders.add(order);
}
}
return largeOrders;
}
public double calculateTotalRevenue(List<Order> orders) {
double total = 0;
for (Order order : orders) {
total += order.getTotal();
}
return total;
}
public List<String> getCustomerNames(List<Order> orders) {
List<String> names = new ArrayList<>();
for (Order order : orders) {
String name = order.getCustomer().getName();
if (!names.contains(name)) {
names.add(name);
}
}
return names;
}
}
重构后:
public class OrderService {
public List<Order> findLargeOrders(List<Order> orders) {
return orders.stream()
.filter(order -> order.getTotal() > 1000)
.collect(Collectors.toList());
}
public double calculateTotalRevenue(List<Order> orders) {
return orders.stream()
.mapToDouble(Order::getTotal)
.sum();
}
public List<String> getCustomerNames(List<Order> orders) {
return orders.stream()
.map(order -> order.getCustomer().getName())
.distinct()
.collect(Collectors.toList());
}
}
通过使用Stream API,我们将命令式的代码转换为声明式的代码,使得代码更加简洁和可读。
Stream API提供了丰富的操作,如filter、map、reduce等,使得处理集合更加方便。
11. 使用Lambda表达式简化匿名内部类
Java 8引入的Lambda表达式提供了一种更简洁的方式来创建匿名函数,特别适合用于替代匿名内部类。
重构前:
public class ButtonHandler {
public void setupButton(Button button) {
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// 处理点击事件
System.out.println("按钮被点击");
}
});
}
public void sortUsers(List<User> users) {
Collections.sort(users, new Comparator<User>() {
@Override
public int compare(User u1, User u2) {
return u1.getName().compareTo(u2.getName());
}
});
}
}
重构后:
public class ButtonHandler {
public void setupButton(Button button) {
button.setOnClickListener(view -> {
// 处理点击事件
System.out.println("按钮被点击");
});
}
public void sortUsers(List<User> users) {
Collections.sort(users, (u1, u2) -> u1.getName().compareTo
(u2.getName()));
// 或者更简洁地
users.sort(Comparator.comparing(User::getName));
}
}
通过使用Lambda表达式,我们将冗长的匿名内部类替换为简洁的函数式表达式,使得代码更加简洁和可读。
12. 使用方法引用简化Lambda表达式
Java 8引入的方法引用提供了一种更简洁的方式来引用已有的方法,特别适合用于替代简单的Lambda表达式。
重构前:
public class UserProcessor {
public List<String> getUserNames(List<User> users) {
return users.stream()
.map(user -> user.getName())
.collect(Collectors.toList());
}
public void printUsers(List<User> users) {
users.forEach(user -> System.out.println(user));
}
public List<User> createUsers(List<String> names) {
return names.stream()
.map(name -> new User(name))
.collect(Collectors.toList());
}
}
重构后:
public class UserProcessor {
public List<String> getUserNames(List<User> users) {
return users.stream()
.map(User::getName)
.collect(Collectors.toList());
}
public void printUsers(List<User> users) {
users.forEach(System.out::println);
}
public List<User> createUsers(List<String> names) {
return names.stream()
.map(User::new)
.collect(Collectors.toList());
}
}
通过使用方法引用,我们将简单的Lambda表达式替换为更简洁的方法引用,使得代码更加简洁和可读。
13. 使用CompletableFuture简化异步编程
Java 8引入的CompletableFuture提供了一种更简洁的方式来处理异步操作,特别适合用于替代传统的回调方式。
重构前:
public class UserService {
public void processUser(Long userId, Callback<User> callback) {
// 异步查询用户
userRepository.findByIdAsync(userId, new Callback<User>() {
@Override
public void onSuccess(User user) {
// 异步查询用户的订单
orderRepository.findByUserIdAsync(userId, new
Callback<List<Order>>() {
@Override
public void onSuccess(List<Order> orders) {
// 处理用户和订单
user.setOrders(orders);
callback.onSuccess(user);
}
@Override
public void onError(Exception e) {
callback.onError(e);
}
});
}
@Override
public void onError(Exception e) {
callback.onError(e);
}
});
}
}
重构后:
public class UserService {
public CompletableFuture<User> processUser(Long userId) {
return userRepository.findByIdAsync(userId)
.thenCompose(user -> orderRepository.findByUserIdAsync
(userId)
.thenApply(orders -> {
user.setOrders(orders);
return user;
}));
}
}
// 使用
userService.processUser(123L)
.thenAccept(user -> {
// 处理用户
System.out.println("用户:" + user.getName());
System.out.println("订单数:" + user.getOrders().size());
})
.exceptionally(e -> {
// 处理异常
System.err.println("处理用户时出错:" + e.getMessage());
returnnull;
});
通过使用CompletableFuture,我们将嵌套的回调转换为链式的调用,使得代码更加简洁和可读。
CompletableFuture提供了丰富的API,如thenApply、thenCompose、thenAccept等,使得处理异步操作更加方便。
14. 使用接口默认方法简化接口实现
Java 8引入的接口默认方法允许在接口中提供方法的默认实现,使得接口的演化更加灵活。
重构前:
public interface PaymentProcessor {
void processPayment(Payment payment);
void refundPayment(Payment payment);
void cancelPayment(Payment payment);
}
public class CreditCardProcessor implements PaymentProcessor {
@Override
public void processPayment(Payment payment) {
// 处理信用卡支付
}
@Override
public void refundPayment(Payment payment) {
// 处理信用卡退款
}
@Override
public void cancelPayment(Payment payment) {
// 取消支付并退款
refundPayment(payment);
}
}
public class PayPalProcessor implements PaymentProcessor {
@Override
public void processPayment(Payment payment) {
// 处理PayPal支付
}
@Override
public void refundPayment(Payment payment) {
// 处理PayPal退款
}
@Override
public void cancelPayment(Payment payment) {
// 取消支付并退款
refundPayment(payment);
}
}
重构后:
public interface PaymentProcessor {
void processPayment(Payment payment);
void refundPayment(Payment payment);
default void cancelPayment(Payment payment) {
// 默认实现:取消支付并退款
refundPayment(payment);
}
}
public class CreditCardProcessor implements PaymentProcessor {
@Override
public void processPayment(Payment payment) {
// 处理信用卡支付
}
@Override
public void refundPayment(Payment payment) {
// 处理信用卡退款
}
}
public class PayPalProcessor implements PaymentProcessor {
@Override
public void processPayment(Payment payment) {
// 处理PayPal支付
}
@Override
public void refundPayment(Payment payment) {
// 处理PayPal退款
}
}
通过使用接口默认方法,我们将公共的实现从具体的类中提取到接口中,减少了重复代码。
当需要修改公共实现时,只需修改接口中的默认方法,而不需要修改所有实现类。
15. 使用枚举替代常量
使用枚举可以提供类型安全的常量,避免使用魔法数字或字符串常量。
重构前:
public class OrderStatus {
public static final String PENDING = "PENDING";
public static final String PROCESSING = "PROCESSING";
public static final String SHIPPED = "SHIPPED";
public static final String DELIVERED = "DELIVERED";
public static final String CANCELLED = "CANCELLED";
}
public class Order {
private String status;
public void setStatus(String status) {
this.status = status;
}
public String getStatus() {
return status;
}
public boolean isCancellable() {
return status.equals(OrderStatus.PENDING) || status.equals
(OrderStatus.PROCESSING);
}
}
// 使用
Order order = new Order();
order.setStatus(OrderStatus.PENDING);
// 可能的错误:使用了未定义的常量
order.setStatus("REFUNDED");
重构后:
public enum OrderStatus {
PENDING,
PROCESSING,
SHIPPED,
DELIVERED,
CANCELLED;
public boolean isCancellable() {
return this == PENDING || this == PROCESSING;
}
}
public class Order {
private OrderStatus status;
public void setStatus(OrderStatus status) {
this.status = status;
}
public OrderStatus getStatus() {
return status;
}
public boolean isCancellable() {
return status.isCancellable();
}
}
// 使用
Order order = new Order();
order.setStatus(OrderStatus.PENDING);
// 编译错误:无法使用未定义的枚举常量
// order.setStatus("REFUNDED");
通过使用枚举,我们提供了类型安全的常量,避免了使用魔法数字或字符串常量可能导致的错误。
同时,枚举也可以包含方法,使得与常量相关的行为更加内聚。
总结
在这篇文章中,我们探讨了15个代码重构的小技巧,从简单的提取方法到高级的设计模式应用。
这些技巧可以帮助我们写出更加简洁、可读、可维护的代码。
代码重构是一个持续的过程,我们应该在日常开发中不断地应用这些技巧,逐步改进我们的代码质量。
AI大模型学习福利
作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
一、全套AGI大模型学习路线
AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取
二、640套AI大模型报告合集
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
三、AI大模型经典PDF籍
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
四、AI大模型商业化落地方案

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量
4069

被折叠的 条评论
为什么被折叠?



