高内聚、低耦合不保证线程安全;高内聚指职责单一、响应同一变化原因,非代码行数少;低耦合要求依赖通过构造注入、抽象接口隔离实现;线程安全需无状态设计、合理使用原子类或redis,而非盲目加synchronized。

高内聚、低耦合本身不保证线程安全;强行把三者混为一谈,反而会掩盖真正的问题根源。
高内聚 ≠ 把所有逻辑塞进一个类里
常见错误是把“职责单一”误解为“代码行数少”,结果写个 UserServiceImpl 里堆了密码加密、发邮件、写日志、调第三方接口……表面看没跨类调用,实则内聚度极低——它响应的是至少 4 种不同变化原因(安全策略变、邮件服务商换、日志格式改、API 升级)。
- 每个方法只做一件事:比如
encryptPassword()不该同时负责校验强度或生成 salt - 状态相关逻辑收拢:像订单状态流转,用状态机封装在
OrderStatusTransition类里,而不是散落在十几个 if-else 中 - 避免“上帝参数”:传入
Map<string object></string>或Object作为方法参数,本质是把职责推给调用方,破坏内聚
低耦合的关键是控制依赖的“源头”和“方式”
不是“少 import 就低耦合”,而是看依赖是否绑定到具体实现。比如在 Service 层直接 new RedisTemplate 或 RestTemplate,哪怕只用了一次,也属于强耦合——它锁死了技术选型,且无法在测试中替换。
- 依赖必须通过构造函数注入,禁用
@Autowired字段注入(后者让类无法脱离 Spring 容器单元测试) - 第三方客户端应抽象为接口,如
PaymentClient,而非直接依赖OkHttpClient - 避免在 DTO 或 Entity 中放业务逻辑方法(如
User#isValid()),这会让数据对象承担校验职责,导致与校验规则强耦合
线程安全不是加个 synchronized 就完事
很多开发者看到并发问题第一反应是给方法加 synchronized,结果吞掉性能还未必解决问题。比如在 Spring 的 @Service 类上加 synchronized,实际锁的是当前 Bean 实例,而 Spring 默认单例,等于全局串行,吞掉整个服务吞吐量。
- 优先用无状态设计:Service 类不持有可变成员变量,天然线程安全
- 共享状态必须明确归属:缓存计数器归 Redis 管,本地计数器用
AtomicInteger或LongAdder,别用普通int - 慎用
ThreadLocal:它不解决共享资源竞争,只解决“每个线程一份副本”,但容易引发内存泄漏(尤其在线程池场景下未 remove)
Spring 环境下最容易被忽略的耦合点
Spring 的便利性会悄悄引入隐式耦合。比如在任意地方调用 ApplicationContext.getBean(),等于把整个容器变成全局变量;又或者在工具类里硬编码 new RestTemplate(),绕过 Spring 管理,导致连接池、拦截器、超时配置全部失效。
- 禁止在非 Spring 管理类(如
Utils、Converter)中直接使用@Value或@Autowired - 配置类要用
@ConfigurationProperties绑定,别在代码里写"redis.host=localhost" - 事务失效高频场景:同一个类内非 public 方法调用
@Transactional方法、捕获异常后没抛出、自调用未走代理
真正难的不是写出符合规范的代码,而是在需求压过来时,能一眼识别出“这个修改会牵动几个变化原因”“这个新功能该往哪个抽象层里塞”。高内聚、低耦合、线程安全,三者各自有判断依据,混在一起只会让人失去焦点。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











