代码的坏味道
Long Method(过长函数)
//for if 多重嵌套
public class PriceCalculatorServiceV1 {
public int calculateTotalPrice(List<Product> products, List<Discount> discounts, Customer customer) {
//折扣计算
int total = 0;
for (Product product : products) {
if (customer.isEligibleForDiscount()) {
int discountedPrice = product.getPrice();
for (Discount discount : discounts) {
if (discount.isApplicable(product)) {
int amountOff = discount.getAmountOff();
discountedPrice -= amountOff;
}
}
total += discountedPrice;
} else {
total += product.getPrice();
}
}
return total;
}
}
// 拆解
public class Calculator {
public int calculateTotalPrice(List<Product> products, List<Discount> discounts, Customer customer) {
int total = 0;
for (Product product : products) {
if (customer.isEligibleForDiscount()) {
int discountedPrice = calculateDiscountedPrice(product, discounts);
total += discountedPrice;
} else {
total += product.getPrice();
}
}
return total;
}
private int calculateDiscountedPrice(Product product, List<Discount> discounts) {
int discountedPrice = product.getPrice();
for (Discount discount : discounts) {
if (discount.isApplicable(product)) {
int amountOff = discount.getAmountOff();
discountedPrice -= amountOff;
}
}
return discountedPrice;
}
}
Duplicated Code (重复代码)
// method1 method2重复代码 doSomething1,doSomething2
class Test {
public void method1() {
doSomeThing1;
doSomeThing2;
doSomeThing3;
}
public void method2() {
doSomeThing1;
doSomeThing2;
doSomeThing4;
}
}
// 正例 先提取为类内公共函数,再考虑能否成为全局公共函数
class Test {
public void method1() {
commonMethod();
doSomeThing3;
}
public void method2() {
commonMethod();
doSomeThing4;
}
public void commonMethod(){
doSomeThing1;
doSomeThing2;
}
}
神秘命名(Mysterious Name)
public class MysteriousNamingExample {
public static void main(String[] args) {
//神秘字段命名
int p1 = 1000;
int r1 = 20;
int q1 = 5;
//神秘方法命名
int t1 = calculate(p1, r1, q1);
System.out.println("The mysterious total price is: " + t1);
}
public static int calculate(int p, int r, int q) {
int o1 = p * r;
int z1 = o1 * q;
return z1;
}
}
// 变量命名表面变量意义,方法命名表面方法行为
public class ImprovedNamingExample {
public static void main(String[] args) {
//明确字段意义命名
int productPrice = 1000;
int discountRate = 20;
int quantity = 5;
//明确方法行为命名
int totalPrice = calculateTotalPrice(productPrice, discountRate, quantity);
System.out.println("The calculated total price is: " + totalPrice);
}
public static int calculateTotalPrice(int price, int discount, int quantity) {
int discountedPrice = price * discount / 100;
int total = discountedPrice * quantity;
return total;
}
}
Large Class(过大的类)
interface class OrderService {
createOrder();
queryOrder();
updateOrderStatus();
snapshotGoods();
snapshotAddress();
queryGoodsSnapshot();
queryAddressSnapshot();
createPay();
queryPay();
updatePayStatus();
}
// 多大的类按照单一职责拆分
interface class OrderService {
createOrder();
queryOrder();
updateOrderStatus();
}
interface class OrderSnapshotService {
snapshotGoods();
snapshotAddress();
queryGoodsSnapshot();
queryAddressSnapshot();
}
interface class PayService {
createPay();
queryPay();
updatePayStatus();
}
Long Paramenter List(过长参数列)
// 一般参数超过3个认为过长
interface class OrderService {
queryOrder(String orderId,String orderNo,Long spuId,Long skuId,Long addressId,Long startTime ,Long endTime);
}
interface class OrderService {
queryOrder(OrderSearchDto dto);
}
// 过长参数调用方必须按照参数顺序填入,容易填错,拓展性困难,参数过长可读性不好
class OrderSearchDto {
String orderId;
String orderNo;
Long spuId;
Long skuId;
Long addressId;
Long startTime;
Long endTime;
}
//如果拆分后单类设计数据维度过多 可以对类继续拆分
class BaseSearchDto {
Long startTime;
Long endTime;
}
class OrderSearchDto extends BaseSearchDto {
String orderId;
String orderNo;
}
class OrderGoodsSearchDto {
Long spuId;
Long skuId;
Long addressId;
}
interface class OrderService {
queryOrder(OrderSearchDto orderSearchDto,OrderGoodsSearchDto orderGoodsSearchDto);
}
Divergent Change(发散式变化)
// 下单、取消订单、追踪订单、生成发票和发送邮件通知(一条龙代码)
interface class OrderService {
void createOrder();
void cancelOrder();
void trackOrder();
void generateInvoice();
void sendEmailNotification();
}
//职责划分
public class OrderPlacer {
void createOrder();
}
public class OrderCanceler {
void cancelOrder();
}
public class OrderTracker {
void trackOrder();
}
public class InvoiceGenerator {
void generateInvoice();
}
public class EmailNotifier {
void sendEmailNotification();
}
Shotgun Surgery(霰弹式修改)
// 需要监听用户领域 订单领域数据变化的对象,使用依赖倒置原则拆分
class class User {
private String userId;
private String name;
private List<Order> orders;
// 构造函数和其他方法
public void confirm() {
// 需要添加的逻辑
// ...
}
}
public class Order {
private String orderId;
private Date orderDate;
private double totalAmount;
// 构造函数和其他方法
public void confirm() {
// 需要添加的逻辑
// ...
}
}
// 依赖倒置之观察者模式,移除confirm内的变更
public interface OrderConfirmationObserver {
void notifyOrderConfirmation(Order order);
}
public class User implements OrderConfirmationObserver {
// 其他属性和方法
public void confirm() {
// 执行用户确认逻辑
// ...
// 通知订单确认
for (Order order : orders) {
order.notifyOrderConfirmation();
}
}
@Override
public void notifyOrderConfirmation(Order order) {
// 执行订单确认逻辑
// ...
}
}
public class Order {
private String orderId;
private Date orderDate;
private double totalAmount;
private OrderConfirmationObserver confirmationObserver;
// 其他属性和方法
public void confirm() {
// 执行订单确认逻辑
// ...
// 通知订单确认观察者
confirmationObserver.notifyOrderConfirmation(this);
}
public void setConfirmationObserver();
}
Feature Envy(依恋情结)
某一段代码过于依赖于其他对象或模块,缺乏独立性和可复用性
public class UserController {
private UserRepository userRepository;
public void createUser(String name) {
// 依赖具体的UserRepository实现
User user = new User(name);
userRepository.save(user);
sendWelcomeEmail(user);
}
private void sendWelcomeEmail(User user) {
// 发送欢迎邮件的代码
// ...
}
}
// 重构后
//采用依赖注入的方式 emailService
public class UserController {
private UserRepository userRepository;
private EmailService emailService;
public void createUser(String name) {
User user = new User(name);
userRepository.save(user);
emailService.sendWelcomeEmail(user);
}
}
Data Clumps(数据泥团)
代码中存在大量的重复、冗余、难以维护的数据。这些数据可能散落在代码的各个部分,而不是集中存储在一个地方
public class OrderProcessor {
public void processOrder(Order order) {
// 从数据库中获取税率
double taxRate = DatabaseHelper.getTaxRate();
// 从配置文件中获取折扣率
double discountRate = ConfigHelper.getDiscountRate();
// 计算税额
double taxAmount = order.getTotalAmount() * taxRate;
// 计算折扣
double discount = order.getTotalAmount() * discountRate;
// 应用税额和折扣
order.setTotalAmount(order.getTotalAmount() + taxAmount - discount);
// 更新订单状态
order.setStatus("Processed");
// 保存订单到数据库
DatabaseHelper.saveOrder(order);
}
}
//重构后
//税率和折扣率被交给OrderProcessor处理
public class OrderProcessor {
private double taxRate;
private double discountRate;
public OrderProcessor(double taxRate, double discountRate) {
this.taxRate = taxRate;
this.discountRate = discountRate;
}
public void processOrder(Order order) {
double taxAmount = order.getTotalAmount() * taxRate;
double discount = order.getTotalAmount() * discountRate;
order.setTotalAmount(order.getTotalAmount() + taxAmount - discount);
order.setStatus("Processed");
DatabaseHelper.saveOrder(order);
}
}
Primitive Obsession(基本类型偏执)
代码中过度使用基本数据类型而不是使用对象或自定义类型
public class OrderProcessor {
public void processOrder(double totalPrice) {
// 对总价进行处理的代码
// ...
}
}
//重构之后
//使用Order类来封装订单信息
public class Order {
private double totalPrice;
public Order(double totalPrice) {
this.totalPrice = totalPrice;
}
// getter和setter方法
}
public class OrderProcessor {
public void processOrder(Order order) {
// 对订单进行处理的代码
// 使用order.getTotalPrice()获取总价
// ...
}
}
Switch Statements(Switch惊悚现身)
代码中过度使用switch语句,导致代码冗长、难以扩展和维护
如果需要添加新的支付方式,就需要修改switch语句的代码,违反了开闭原则
public class OrderProcessor {
public void processOrder(String paymentMethod) {
switch (paymentMethod) {
case "creditCard":
// 处理信用卡支付的逻辑
break;
case "paypal":
// 处理PayPal支付的逻辑
break;
case "bankTransfer":
// 处理银行转账支付的逻辑
break;
case "cash":
// 处理现金支付的逻辑
break;
default:
// 处理未知支付方式的逻辑或抛出异常
break;
}
}
}
//重构后
//使用多态和面向对象设计原则修改
public class PaymentProcessor {
public void processOrder(PaymentMethod paymentMethod) {
paymentMethod.processPayment();
}
}
public interface PaymentMethod {
void processPayment();
}
public class CreditCardPayment implements PaymentMethod {
public void processPayment() {
// 处理信用卡支付的逻辑
}
}
public class PaypalPayment implements PaymentMethod {
public void processPayment() {
// 处理PayPal支付的逻辑
}
}
public class BankTransferPayment implements PaymentMethod {
public void processPayment() {
// 处理银行转账支付的逻辑
}
}
public class CashPayment implements PaymentMethod {
public void processPayment() {
// 处理现金支付的逻辑
}
}
Parallel Inheritance Hierarchies(平行继承体系)
代码中存在多个平行的继承关系,导致代码的复杂性增加
public class Shape {
// Shape的属性和方法
}
public class Circle extends Shape {
// Circle的属性和方法
}
public class Rectangle extends Shape {
// Rectangle的属性和方法
}
public class RedCircle extends Circle {
// RedCircle特有的属性和方法
}
public class BlueCircle extends Circle {
// BlueCircle特有的属性和方法
}
public class RedRectangle extends Rectangle {
// RedRectangle特有的属性和方法
}
public class BlueRectangle extends Rectangle {
// BlueRectangle特有的属性和方法
}
//重构后
//使用对象组合、接口和设计模式等技术来重构代码 减少类的继承层次
public interface Shape {
void draw();
}
public class Circle implements Shape {
// Circle的属性和方法的实现
public void draw() {
// 绘制圆形的逻辑
}
}
public class Rectangle implements Shape {
// Rectangle的属性和方法的实现
public void draw() {
// 绘制矩形的逻辑
}
}
public class ColorShape implements Shape {
private Shape shape;
private String color;
public ColorShape(Shape shape, String color) {
this.shape = shape;
this.color = color;
}
public void draw() {
shape.draw();
System.out.println("Color: " + color);
}
}
Lazy Class(冗赘类)
代码中存在无效、冗余或不必要的类,这些类对代码的功能没有实际贡献,反而增加了代码的复杂性和维护成本
public class Calculator {
public int add(int a, int b) {
return a + b;
}
}
public class AdvancedCalculator extends Calculator {
public int subtract(int a, int b) {
return a - b;
}
}
public class ScientificCalculator extends AdvancedCalculator {
public double sin(double angle) {
return Math.sin(angle);
}
}
public class Main {
public static void main(String[] args) {
ScientificCalculator calculator = new ScientificCalculator();
int result1 = calculator.add(1, 2);
int result2 = calculator.subtract(5, 3);
double result3 = calculator.sin(Math.PI / 2);
System.out.println(result1);
System.out.println(result2);
System.out.println(result3);
}
}
//重构后
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
public double sin(double angle) {
return Math.sin(angle);
}
}
public class Main {
public static void main(String[] args) {
Calculator calculator = new Calculator();
int result1 = calculator.add(1, 2);
int result2 = calculator.subtract(5, 3);
double result3 = calculator.sin(Math.PI / 2);
System.out.println(result1);
System.out.println(result2);
System.out.println(result3);
}
}
Speculative Generality(夸夸其谈未来性)
代码中使用过于复杂、高度抽象或未来可能用到但目前并不实际需要的技术或设计
@Service
public class FutureEcommerceService {
private ProductService productService;
private OrderService orderService;
public CompletableFuture<Order> placeOrderAsync(String productId, int quantity) {
CompletableFuture<Product> productFuture = CompletableFuture.supplyAsync(() ->
productService.getProductById(productId)
);
CompletableFuture<Order> orderFuture = productFuture.thenCompose(product ->
CompletableFuture.supplyAsync(() ->
orderService.createOrder(product, quantity)
)
);
return orderFuture.thenCombine(productFuture, (order, product) -> {
orderService.sendOrderConfirmation(order);
productService.updateStock(product, quantity);
return order;
});
}
}
//重构后
//简化异步操作和合并结果的功能使其具有通用性
@Service
public class EcommerceService {
private final ProductService productService;
private final OrderService orderService;
public EcommerceService(ProductService productService, OrderService orderService) {
this.productService = productService;
this.orderService = orderService;
}
public Order placeOrder(String productId, int quantity) {
Product product = productService.getProductById(productId);
Order order = orderService.createOrder(product, quantity);
orderService.sendOrderConfirmation(order);
productService.updateStock(product, quantity);
return order;
}
}
Temporary Field(令人迷惑的暂时字段)
@Service
public class ConfusingEcommerceService {
@Autowired
private ProductService productService;
@Autowired
private OrderService orderService;
private String productId;
private int quantity;
public void setProductId(String productId) {
this.productId = productId;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public void placeOrder() {
Product product = productService.getProductById(productId);
Order order = orderService.createOrder(product, quantity);
orderService.sendOrderConfirmation(order);
productService.updateStock(product, quantity);
}
}
//重构后
//类内部字段变为方法入参
@Service
public class EcommerceService {
private ProductService productService;
private OrderService orderService;
public Order placeOrder(String productId, int quantity) {
Product product = productService.getProductById(productId);
Order order = orderService.createOrder(product, quantity);
orderService.sendOrderConfirmation(order);
productService.updateStock(product, quantity);
return order;
}
}
Message Chains(过度耦合的消息链)
代码中出现多层对象之间的调用链,使得对象之间过于紧密耦合
@Service
public class OverlyCoupledEcommerceService {
public void processOrder(String userId, String productId, int quantity) {
User user = userService.getUserById(userId);
Product product = productService.getProductById(productId);
Cart cart = user.getCart();
cart.addItem(product, quantity);
Order order = cart.checkout();
orderService.placeOrder(order);
}
}
//重构后
//处理订单方法按照步骤划分 1.准备数据,2创建订单,3提交订单
@Service
public class EcommerceService {
public void processOrder(String userId, String productId, int quantity) {
User user = userService.getUserById(userId);
Product product = productService.getProductById(productId);
Order order = createOrder(user, product, quantity);
placeOrder(order);
}
private Order createOrder(User user, Product product, int quantity) {
Cart cart = user.getCart();
cart.addItem(product, quantity);
return cart.checkout();
}
private void placeOrder(Order order) {
orderService.placeOrder(order);
}
}
Middle Man(中间人)
一种过度使用委托(某类中一半以上方法都委托给其他类)的代码
Inappropriate Intimacy(狎昵关系)
两个类之间的关系过于紧密,一个类依赖了另一个类的内部实现细节,导致高度耦合
public class Customer {
private List<Order> orders;
public void addOrder(Order order) {
// 依赖Order类的内部逻辑
if (order.getTotalAmount() > 1000) {
// 处理大额订单
}
orders.add(order);
}
}
public class Order {
private double totalAmount;
public double getTotalAmount() {
return totalAmount;
}
}
//重构后
//Customer类过于依赖Order类的内部实现细节,产生了狎昵关系
//应该减少Customer类对Order类的直接依赖,可以引入一个中间层
public class Customer {
private List<Order> orders;
private OrderProcessor orderProcessor;
public void addOrder(Order order) {
// 调用OrderProcessor进行订单处理
orderProcessor.processOrder(order);
orders.add(order);
}
}
public class Order {
private double totalAmount;
public double getTotalAmount() {
return totalAmount;
}
// other methods and properties
}
public class OrderProcessor {
public void processOrder(Order order) {
// 处理订单逻辑,不直接依赖Order的内部实现细节
if (order.getTotalAmount() > 1000) {
// 处理大额订单
}
// other processing logic
}
}
Alternative Classes with Different Interfaces(异曲同工的类)
指的是在一个系统中存在多个类,它们提供了相似或相同的功能,但具有不同的接口,导致代码混乱
使用抽象类承载共同方法,使用接口定义共同方法
Incomplete Library Class(不完美的库类)
指的是一个库或外部依赖中的类缺少某些功能,需要在应用程序中补充完成
比如StringUtil 缺少一个字符串转小写的方法,
重构: 添加这个方法
Refused Bequest(被拒绝的遗赠)
对于某个子类,它只想继承基类的部分函数和数据,不需要基类提供的全部内容
public class Product {
private String name;
private String description;
private double price;
public Product(String name, String description, double price) {
this.name = name;
this.description = description;
this.price = price;
}
public double calculateDiscountedPrice(double discountPercentage) {
return price * (1 - discountPercentage / 100);
}
// Getters and setters for name, description, and price
}
public class ElectronicProduct extends Product {
// ElectronicProduct-specific attributes
// Constructor
// Getters and setters for ElectronicProduct-specific attributes
}
//重构后
//使用组合代替继承
public class Product {
private String name;
private String description;
private double price;
public Product(String name, String description, double price) {
this.name = name;
this.description = description;
this.price = price;
}
public double calculateDiscountedPrice(double discountPercentage) {
return price * (1 - discountPercentage / 100);
}
// Getters and setters for name, description, and price
}
public class ElectronicProduct {
private Product product; // 使用组合代替继承
public ElectronicProduct(String name, String description, double price) {
this.product = new Product(name, description, price);
}
// ElectronicProduct-specific attributes and methods
public double calculateDiscountedPrice(double discountPercentage) {
// 在ElectronicProduct中实现自己的价格计算逻辑
return product.calculateDiscountedPrice(discountPercentage);
}
// Getters and setters for ElectronicProduct-specific attributes
}