高内聚低耦合指类职责单一且内部协作紧密、类间依赖弱;Java中一眼可判:new具体实现类或import大量非本模块实现类即耦合高,应改用接口+构造器注入,并将行为封装进对应数据类。

什么是高内聚低耦合,Java里怎么一眼看出来
高内聚指一个类职责单一、内部方法紧密协作完成同一目标;低耦合指类之间依赖尽量弱,不直接持有对方实例,不硬编码调用细节。在Java中,最直观的判断方式是看 new 关键字和 import 语句:如果一个类频繁 new 其他具体类、或 import 大量非本模块的实现类(比如 import com.xxx.service.impl.UserServiceImpl),基本就是耦合过高。
用接口隔离 + 依赖注入代替 new 实例
避免在业务类中直接 new UserServiceImpl(),而是声明接口依赖,由外部传入或容器注入:
public class OrderProcessor {
private final UserService userService; // 依赖接口,不是实现类
public OrderProcessor(UserService userService) { // 构造器注入
this.userService = userService;
}
public void process(Order order) {
User user = userService.findById(order.getUserId());
// ...
}
}
- 接口
UserService定义契约,实现类可随时替换(如从 DB 切到缓存) - 测试时可传入
MockUserService,无需启动数据库 - 若用 Spring,用
@Autowired注入也行,但构造器注入更清晰、不可变、易测 - 切忌在类内部写
new UserServiceImpl()—— 这会锁死实现,破坏可替换性
把状态和行为封装进同一个类,别拆成“DTO + 工具类”组合
常见反模式:定义 UserDto 存字段,再写个 UserHelper 放所有操作逻辑。这导致数据和行为分离,内聚度归零。
- 把校验、格式化、状态转换等逻辑放进
User类本身(只要不违反单一职责) - 例如
user.isValidEmail()比UserHelper.isValidEmail(user.getEmail())更内聚 - 若逻辑跨多个领域对象(如订单+库存联动),应提取新领域类(
OrderFulfillmentService),而不是塞进任一现有类 - DTO 只用于层间传输(如 Controller → Service),不参与业务逻辑
警惕“上帝类”和过度抽象带来的假低耦合
为解耦而抽象出一堆空接口、模板类、回调函数,结果每个类都依赖 AbstractBaseProcessor 和 CallbackHandlerFactory,实际只是把耦合从具体类转移到抽象结构上。
立即学习“Java免费学习笔记(深入)”;
- 优先用组合而非继承:
PaymentService持有NotificationSender和LogRecorder,比继承BaseTransactionService更可控 - 接口粒度要合理:一个
UserService没问题,但拆成FindUserPort、CreateUserPort、UpdateUserPort就过头了 - 真正低耦合的表现是:改一个模块(如换支付渠道),只动
AlipayAdapter和配置,其他类完全不动、不重编译
内聚和耦合不是靠设计模式数量衡量的,而是看修改一处时,有多少其他地方被迫跟着改。每次加新功能前,先问一句:这个逻辑放在这里,是不是只有它自己需要?它是否必须知道别的类怎么实现?










