God对象是拥有过多职责的类,导致代码强耦合、难以测试与维护。
// ❌ 反模式代码:God对象
public class OrderService {
// 职责1:订单创建
public void createOrder() { /* 复杂业务逻辑 */ }
// 职责2:支付处理
public void processPayment() { /* 调用第三方API */ }
// 职责3:库存扣减
private void deductStock() { /* 直接操作数据库 */ }
// 职责4:日志记录
public void logActivity() { /* 混合业务逻辑与日志 */ }
// ... 其他20+方法
}
// ✅ 改良方案:模块化设计
// 1. 订单创建服务
public class OrderCreator {
private final StockService stockService;
public OrderCreator(StockService stockService) {
this.stockService = stockService; // 依赖注入
}
public void createOrder() {
stockService.deductStock(); // 专注核心职责
}
}
// 2. 支付服务(遵循开闭原则)
@RequiredArgsConstructor
public class PaymentProcessor {
private final PaymentGateway gateway;
public void processPayment() {
gateway.charge(); // 封装第三方逻辑
}
}
// 3. 日志服务(独立模块)
public class ActivityLogger {
public void logActivity(String message) {
// 专注日志记录,无业务逻辑
}
}
// 4. 顶层协调器(符合迪米特法则)
@Component
public class OrderCoordinator {
private final OrderCreator creator;
private final PaymentProcessor processor;
private final ActivityLogger logger;
@Autowired
public OrderCoordinator(
OrderCreator creator,
PaymentProcessor processor,
ActivityLogger logger
) {
this.creator = creator;
this.processor = processor;
this.logger = logger;
}
public void handleOrder() {
try {
creator.createOrder();
processor.processPayment();
logger.logActivity("Order processed");
} catch (Exception e) {
logger.logActivity("Error: " + e.getMessage());
}
}
}
@Autowired
实现松耦合。N+1查询导致数据库负载激增,典型场景是分页查询时逐条加载关联数据。
// ❌ 反模式代码:N+1查询
public class OrderRepository {
@PersistenceContext
private EntityManager em;
// 一级查询:获取订单列表
public List<Order> findOrders() {
return em.createQuery("SELECT o FROM Order o", Order.class).getResultList();
}
// 二级查询:逐条加载用户信息
public User findUserByOrder(Order order) {
return em.find(User.class, order.getUserId()); // 每个订单触发一次查询
}
}
// 调用方
List<Order> orders = orderRepo.findOrders();
for (Order o : orders) {
User user = orderRepo.findUserByOrder(o); // N次查询
System.out.println(user.getName());
}
// ✅ 改良方案:使用JPA的JOIN优化
public class OrderRepository {
// 1. 使用JOIN一次性加载关联数据
@Query("SELECT o FROM Order o JOIN FETCH o.user")
public List<Order> findOrdersWithUser();
// 2. 启用二级缓存(需配置Ehcache)
@Cacheable("orders")
public Order findOrderById(Long id) {
return em.find(Order.class, id);
}
}
// 调用方
List<Order> orders = orderRepo.findOrdersWithUser();
for (Order o : orders) {
System.out.println(o.getUser().getName()); // 无额外查询
}
// 配置ehcache.xml(关键参数)
<cache name="orders"
maxEntriesLocalHeap="1000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"/>
复制粘贴导致代码重复率高,修改时需逐处调整,引发维护雪崩。
// ❌ 反模式代码:重复计算逻辑
public class ShoppingCart {
public double calculateTotal() {
double total = 0;
for (Item item : items) {
total += item.getPrice() * item.getQuantity();
// 硬编码折扣规则
if (item.getCategory().equals("Electronics")) {
total *= 0.9; // 10%折扣
}
}
return total;
}
}
public class Invoice {
public double calculateTotal() {
double total = 0;
for (Item item : items) {
total += item.getPrice() * item.getQuantity();
// 相同的折扣规则
if (item.getCategory().equals("Electronics")) {
total *= 0.9; // 代码重复!
}
}
return total;
}
}
// ✅ 改良方案:策略模式解耦
// 1. 折扣策略接口
public interface DiscountStrategy {
double applyDiscount(double amount);
}
// 2. 具体策略实现
public class ElectronicsDiscount implements DiscountStrategy {
@Override
public double applyDiscount(double amount) {
return amount * 0.9; // 集中维护折扣规则
}
}
// 3. 上下文类
public class DiscountContext {
private final DiscountStrategy strategy;
public DiscountContext(DiscountStrategy strategy) {
this.strategy = strategy;
}
public double calculateDiscount(double amount) {
return strategy.applyDiscount(amount);
}
}
// 4. 调用方(ShoppingCart)
public class ShoppingCart {
private final DiscountContext context;
public ShoppingCart() {
this.context = new DiscountContext(new ElectronicsDiscount());
}
public double calculateTotal() {
double total = ...; // 基础计算
return context.calculateDiscount(total); // 统一调用策略
}
}
// 5. 其他场景复用
public class Invoice {
private final DiscountContext context;
// ...
public double calculateTotal() {
return context.calculateDiscount(total); // 无需重复代码
}
}
硬编码配置导致环境迁移困难,修改需重新编译代码。
// ❌ 反模式代码:硬编码数据库URL
public class DatabaseConfig {
private static final String URL = "jdbc:mysql://localhost:3306/mydb";
private static final String USER = "root";
private static final String PASSWORD = "secret";
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(URL); // 硬编码URL
dataSource.setUsername(USER);
dataSource.setPassword(PASSWORD);
return dataSource;
}
}
// ✅ 改良方案:使用Spring配置文件
@Configuration
@PropertySource("classpath:application.properties")
public class DatabaseConfig {
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Bean
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(url); // 从配置文件读取
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
// application.properties(配置文件)
spring.datasource.url=jdbc:mysql://${DB_HOST}:${DB_PORT}/mydb
spring.datasource.username=${DB_USER}
spring.datasource.password=${DB_PASSWORD}
// 部署时通过环境变量传递参数
export DB_HOST=localhost
export DB_PORT=3306
export DB_USER=root
export DB_PASSWORD=secret
application.properties
解耦代码与配置。${}
占位符实现动态替换。大泥球架构表现为无明确分层、类间强耦合,导致代码难以理解与维护。
// ❌ 反模式代码:无分层设计
public class UserController {
@Autowired
private UserRepository repo; // 直接操作数据库
@GetMapping("/users")
public List<User> listUsers() {
List<User> users = repo.findAll();
// 业务逻辑与控制逻辑混合
if (users.size() > 10) {
users.sort(Comparator.comparing(User::getName)); // 业务逻辑
}
return users;
}
@PostMapping("/users")
public void createUser(@RequestBody User user) {
// 业务规则内联
if (user.getAge() < 18) {
throw new IllegalArgumentException("年龄必须≥18"); // 无服务层
}
repo.save(user); // 直接调用持久层
}
}
// ✅ 改良方案:MVC分层与服务层
// 1. 控制器(Controller)
@RestController
public class UserController {
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/users")
public List<User> listUsers() {
return userService.getUsers(); // 调用服务层
}
@PostMapping("/users")
public void createUser(@RequestBody User user) {
userService.createUser(user); // 隔离业务逻辑
}
}
// 2. 服务层(Service)
@Service
public class UserService {
private final UserRepository repo;
@Autowired
public UserService(UserRepository repo) {
this.repo = repo;
}
public List<User> getUsers() {
List<User> users = repo.findAll();
if (users.size() > 10) {
users.sort(Comparator.comparing(User::getName)); // 业务逻辑集中
}
return users;
}
public void createUser(User user) {
validateUser(user); // 调用验证方法
repo.save(user);
}
private void validateUser(User user) {
if (user.getAge() < 18) {
throw new IllegalArgumentException("年龄必须≥18");
}
}
}
// 3. 持久层(Repository)
public interface UserRepository extends JpaRepository<User, Long> {
// 专注于数据访问
}
// ❌ 反模式代码:单体应用中的订单服务
public class OrderService {
private final InventoryService inventory;
private final PaymentService payment;
private final NotificationService notification;
@Autowired
public OrderService(InventoryService inventory, PaymentService payment, NotificationService notification) {
this.inventory = inventory;
this.payment = payment;
this.notification = notification;
}
public void placeOrder(Order order) {
// 强耦合的业务流程
inventory.deductStock(order);
payment.charge(order);
notification.sendEmail(order);
}
}
// ✅ 改良方案:事件驱动解耦
// 1. 订单服务(发布事件)
@Service
public class OrderService {
private final ApplicationEventPublisher eventPublisher;
@Autowired
public OrderService(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void placeOrder(Order order) {
// 仅负责核心订单逻辑
saveOrder(order);
eventPublisher.publishEvent(new OrderPlacedEvent(order)); // 发布事件
}
}
// 2. 库存服务(订阅事件)
@Component
public class InventoryListener {
private final InventoryService inventory;
@Autowired
public InventoryListener(InventoryService inventory) {
this.inventory = inventory;
}
@EventListener
public void handleOrderPlacedEvent(OrderPlacedEvent event) {
inventory.deductStock(event.getOrder()); // 异步处理
}
}
// 3. 支付服务(订阅事件)
@Component
public class PaymentListener {
private final PaymentService payment;
@Autowired
public PaymentListener(PaymentService payment) {
this.payment = payment;
}
@EventListener
public void handleOrderPlacedEvent(OrderPlacedEvent event) {
payment.charge(event.getOrder()); // 异步处理
}
}
# 安装SonarQube并配置规则
docker run -d --name sonarqube -p 9000:9000 sonarqube:lts
# 分析项目
mvn sonar:sonar -Dsonar.projectKey=my-project
// ✅ 使用Lombok减少重复代码
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Long id;
private String name;
private int age;
}
// 无需手动编写getter/setter/toString
application.properties
管理配置。