1. 为什么需要深入理解面向对象进阶特性?
我至今记得第一次用Java写电商系统时的窘境——当产品经理要求给所有商品类型添加折扣功能时,我在每个商品类里重复编写了几乎相同的calculateDiscount()方法。直到同事提醒我可以用继承和多态重构,才意识到面向对象(OOP)的进阶特性不是学院派的理论,而是解决实际工程问题的利器。
Java作为一门纯面向对象语言,其封装、继承、多态三大特性构成了代码组织的基石。但很多开发者停留在基础用法阶段,比如:
- 把封装简单理解为private字段加getter/setter
- 继承只用于代码复用而忽视里氏替换原则
- 多态仅停留在方法重写的表面认知
这种认知局限会导致:
- 系统扩展时出现大量重复代码
- 父类修改引发子类雪崩式报错
- 类型转换和条件判断充斥代码
来看个真实案例:某金融系统最初用if-else处理不同支付方式,随着支付渠道增加到20+种,维护成本呈指数增长。通过应用策略模式(基于多态)重构后,新增支付方式只需添加新类,核心逻辑保持稳定。
关键认知:OOP进阶不是语法糖,而是应对复杂业务变化的工程方法论
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 封装的深层实践:不仅仅是数据隐藏
2.1 访问控制的工程意义
教科书常把封装等同于private字段,但实际项目中,合理的访问控制层级能显著降低模块耦合度。Java提供的4种访问修饰符对应不同的使用场景:
| 修饰符 | 类内 | 同包 | 子类 | 任意位置 | 典型用途 |
|---|---|---|---|---|---|
| private | √ | × | × | × | 内部实现细节 |
| default | √ | √ | × | × | 包内协作组件 |
| protected | √ | √ | √ | × | 框架扩展点 |
| public | √ | √ | √ | √ | 对外API |
我在物流系统中曾犯过一个典型错误:将运输工具的currentSpeed字段设为public以便外部直接修改,结果导致:
- 无法校验速度合法性(出现负值)
- 难以添加速度变化日志
- 速度单位混乱(mph/kmh)
重构为private并通过方法控制后,增加了单位转换和越界校验,系统健壮性大幅提升。
2.2 不变性与防御式拷贝
封装的核心是保持对象状态一致。对于敏感数据,仅用private不够,还需要:
java复制// 不安全的做法
public class BankAccount {
private Date openDate;
public Date getOpenDate() {
return openDate; // 外部可修改Date对象
}
}
// 防御式拷贝
public Date getOpenDate() {
return new Date(openDate.getTime());
}
在金融项目中,我们要求所有金额字段返回BigDecimal时都必须使用new BigDecimal(String)构造器,避免浮点数精度问题被外部引用修改。
2.3 封装的最佳实践
- 最小化可见性:从private开始,仅按需放宽
- 不可变优先:final字段+深度拷贝
- 方法而非字段:即使简单getter也保留未来扩展可能
- 包私有化:模块内部协作使用default修饰符
- 文档契约:用JavaDoc明确方法的前置/后置条件
3. 继承的陷阱与正确打开方式
3.1 何时使用继承——is-a关系的严格检验
继承滥用是系统腐化的常见根源。必须通过"里氏替换原则"测试:
子类对象应该能够替换父类对象出现在任何地方,而不破坏程序正确性
我曾见过这样的继承体系:
java复制class Rectangle {
void setWidth(int w) {...}
void setHeight(int h) {...}
}
class Square extends Rectangle {
@Override
void setWidth(int w) {
super.setWidth(w);
super.setHeight(w); // 破坏矩形不变性
}
}
这违反了数学上的is-a关系,正确做法应该是:
java复制interface Shape {
double area();
}
class Rectangle implements Shape {...}
class Square implements Shape {...}
3.2 组合优于继承
在电商平台开发中,我们最初用继承实现不同促销策略:
java复制abstract class DiscountPolicy {
abstract double apply(Order order);
}
class SeasonDiscount extends DiscountPolicy {...}
class MemberDiscount extends DiscountPolicy {...}
当需要叠加多种折扣时,继承体系崩溃。改用组合模式:
java复制class CompositeDiscount {
List<DiscountStrategy> strategies;
double apply(Order order) {
return strategies.stream()
.mapToDouble(s -> s.apply(order))
.sum();
}
}
3.3 模板方法模式的正向案例
继承的正确使用场景——定义算法骨架,允许子类重写特定步骤:
java复制abstract class DataExporter {
// 模板方法
public final void export() {
prepareData();
validate();
doExport(); // 子类实现
cleanup();
}
protected abstract void doExport();
}
class CSVExporter extends DataExporter {
protected void doExport() {
// 生成CSV文件
}
}
4. 多态的动态威力
4.1 方法分发的底层机制
理解多态需要了解JVM的方法调用指令:
- invokestatic:静态方法
- invokespecial:构造器/private/父类方法
- invokevirtual:实例方法(多态基础)
- invokeinterface:接口方法
通过javap反编译可见多态调用:
java复制interface Greeter { void greet(); }
class EnglishGreeter implements Greeter {
public void greet() { System.out.println("Hello"); }
}
// 编译后指令:
// invokeinterface #2, 1 // Interface Greeter.greet
4.2 策略模式的典型实现
在游戏开发中,角色攻击行为可以动态切换:
java复制interface AttackStrategy {
void execute();
}
class SwordAttack implements AttackStrategy {
public void execute() { /* 挥剑动画 */ }
}
class MagicAttack implements AttackStrategy {
public void execute() { /* 施法特效 */ }
}
class Character {
private AttackStrategy strategy;
void setStrategy(AttackStrategy s) {
this.strategy = s;
}
void attack() {
strategy.execute();
}
}
4.3 避免instanceof的替代方案
多态的反模式——类型判断式代码:
java复制// 坏味道
if (animal instanceof Dog) {
((Dog)animal).bark();
} else if (animal instanceof Cat) {
((Cat)animal).meow();
}
改进方案:
java复制interface Animal {
void speak();
}
class Dog implements Animal {
public void speak() { bark(); }
private void bark() {...}
}
5. 类型系统进阶技巧
5.1 协变返回类型
JDK5开始支持返回类型窄化:
java复制class Fruit {}
class Apple extends Fruit {}
class Farm {
Fruit harvest() { return new Fruit(); }
}
class AppleFarm extends Farm {
@Override
Apple harvest() { // 合法协变
return new Apple();
}
}
5.2 桥方法揭秘
泛型擦除会导致编译器生成桥方法:
java复制class Node<T> {
public T data;
public void setData(T data) {
this.data = data;
}
}
class MyNode extends Node<Integer> {
public void setData(Integer data) {
super.setData(data);
}
}
// 编译器会生成:
// public void setData(Object data) {
// setData((Integer)data);
// }
5.3 用sealed类控制继承
Java17引入的sealed类提供了精细的继承控制:
java复制public sealed class Shape
permits Circle, Square, Rectangle {
// 仅允许这三个子类
}
这在设计支付网关时特别有用,可以严格限定支付方式类型。
6. 设计模式中的OOP实践
6.1 工厂方法模式
创建对象时不暴露实例化逻辑:
java复制interface Logger {
void log(String message);
}
class FileLogger implements Logger {...}
class DatabaseLogger implements Logger {...}
abstract class LoggerFactory {
abstract Logger createLogger();
void writeLog(String msg) {
Logger logger = createLogger();
logger.log(msg);
}
}
class FileLoggerFactory extends LoggerFactory {
Logger createLogger() {
return new FileLogger("/app.log");
}
}
6.2 观察者模式
Java标准库中的实现:
java复制class Order implements Observable {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer o) {
observers.add(o);
}
public void complete() {
observers.forEach(o -> o.update(this));
}
}
6.3 装饰器模式
Java I/O流的经典应用:
java复制InputStream in = new BufferedInputStream(
new GZIPInputStream(
new FileInputStream("data.gz")));
7. 性能考量与JVM优化
7.1 虚方法表(vtable)
每个类维护一个方法表,包含:
- 非private实例方法
- 非final方法
- 父类方法
调用流程:
- 获取对象实际类型
- 查找vtable
- 根据偏移量定位方法
7.2 内联优化
对于final/private/static方法,JIT会直接内联:
java复制final class MathUtils {
static double circleArea(double r) {
return 3.14 * r * r;
}
}
// 调用处可能被优化为:
double area = 3.14 * radius * radius;
7.3 对象内存布局
普通对象头包含:
- Mark Word(哈希码/GC信息)
- 类指针
- 数组长度(如果是数组)
继承体系下的字段排列遵循声明顺序,父类字段在前。
8. 常见误区与最佳实践
8.1 继承滥用检测清单
当出现以下情况时,应该考虑用组合替代继承:
- 子类需要覆盖大量父类方法
- 父类修改会导致子类连锁反应
- 需要同时继承多个类的特性
- is-a关系不明确
8.2 多态性能优化
高频调用场景的优化技巧:
- 对关键方法使用final修饰
- 小对象考虑值类型(Java16+的value types)
- 避免深度继承(3层以上)
- 接口方法保持精简
8.3 现代Java特性
- Records(Java16+):
java复制record Point(int x, int y) {}
// 自动生成:final类、私有final字段、构造器、equals/hashCode/toString
- Pattern Matching(Java17+):
java复制if (obj instanceof String s) {
System.out.println(s.length());
}
- Sealed Interfaces(Java17+):
java复制sealed interface Expr
permits ConstantExpr, PlusExpr, MinusExpr {}
9. 实战:设计一个可扩展的通知系统
需求背景:需要支持多种通知方式(邮件、短信、站内信),且未来可能新增方式。
9.1 基础实现
java复制interface Notifier {
void send(String recipient, String message);
}
class EmailNotifier implements Notifier {
public void send(String email, String msg) {
// 调用邮件服务API
}
}
class NotificationService {
private final Map<String, Notifier> notifiers;
public void notify(String type, String recipient, String msg) {
Notifier notifier = notifiers.get(type);
if (notifier != null) {
notifier.send(recipient, msg);
}
}
}
9.2 支持优先级和重试
java复制abstract class AbstractNotifier implements Notifier {
protected int maxRetries = 3;
public final void send(String recipient, String message) {
int attempts = 0;
while (attempts < maxRetries) {
try {
doSend(recipient, message);
return;
} catch (NotificationException e) {
attempts++;
if (attempts == maxRetries) {
logError(e);
}
}
}
}
protected abstract void doSend(String recipient, String message);
}
9.3 动态配置
通过Spring配置示例:
java复制@Configuration
class NotifierConfig {
@Bean
public NotificationService notificationService(
List<Notifier> notifiers) {
Map<String, Notifier> map = notifiers.stream()
.collect(Collectors.toMap(
n -> n.getClass().getSimpleName()
.replace("Notifier", "").toLowerCase(),
Function.identity()));
return new NotificationService(map);
}
}
10. 单元测试策略
10.1 测试多态行为
使用Mockito测试策略模式:
java复制@Test
void testPaymentStrategy() {
PaymentStrategy mockStrategy = mock(PaymentStrategy.class);
PaymentProcessor processor = new PaymentProcessor(mockStrategy);
processor.process(100.0);
verify(mockStrategy).execute(100.0);
}
10.2 继承测试技巧
父类测试用例复用:
java复制public abstract class AbstractListTest {
protected abstract List<String> createList();
@Test
void testAdd() {
List<String> list = createList();
list.add("test");
assertEquals(1, list.size());
}
}
class ArrayListTest extends AbstractListTest {
protected List<String> createList() {
return new ArrayList<>();
}
}
10.3 测试密封类
利用permits子类进行测试:
java复制sealed class Shape permits TestCircle {
abstract double area();
}
final class TestCircle extends Shape {
double area() { return Math.PI * radius * radius; }
}
class ShapeTest {
@Test
void testArea() {
Shape circle = new TestCircle(5.0);
assertEquals(78.5, circle.area(), 0.1);
}
}
11. 架构层面的OOP应用
11.1 模块化设计
Java9+的模块系统与OOP结合:
java复制module order.service {
exports com.example.order.model;
exports com.example.order.service;
requires payment.api;
}
// 内部实现包不导出
package com.example.order.internal; // 对其它模块不可见
11.2 领域驱动设计
聚合根封装业务规则:
java复制class Order {
private List<LineItem> items;
private Customer customer;
public void addItem(Product p, int qty) {
if (qty <= 0) throw new IllegalArgumentException();
if (items.stream().anyMatch(i -> i.productId().equals(p.id()))) {
// 合并相同商品
} else {
items.add(new LineItem(p, qty));
}
}
}
11.3 六边形架构
端口与适配器:
java复制// 核心业务
interface OrderRepository {
Order findById(OrderId id);
void save(Order order);
}
// 基础设施实现
@Repository
class JpaOrderRepository implements OrderRepository {
// 使用Spring Data JPA实现
}
12. 前沿趋势与持续学习
12.1 值类型发展
Project Valhalla的目标:
java复制// 未来可能语法
value class Point {
int x;
int y;
}
12.2 模式匹配演进
Java21中的模式匹配增强:
java复制switch (obj) {
case String s -> System.out.println(s.length());
case Integer i -> System.out.println(i * 2);
default -> throw new IllegalArgumentException();
}
12.3 响应式编程中的OOP
Reactor中的封装:
java复制public interface UserService {
Mono<User> findById(String id);
default Mono<User> findByIdWithCache(String id) {
return checkCache(id)
.switchIfEmpty(findById(id).flatMap(this::cacheUser));
}
}
13. 工具链支持
13.1 字节码查看
使用javap分析多态:
bash复制javap -c -p MyClass.class
13.2 JOL分析对象布局
java复制System.out.println(ClassLayout.parseInstance(obj).toPrintable());
13.3 架构可视化
使用PlantUML生成类图:
plantuml复制@startuml
interface Listener {
void onEvent(Event e)
}
class EmailListener implements Listener
class SMSListener implements Listener
@enduml
14. 性能调优实战
14.1 虚方法调用优化
对比测试:
java复制// 测试继承深度对性能的影响
class A { void doWork() {} }
class B extends A { void doWork() {} }
// ...直到class E
// 测试final方法
class FastA { final void doWork() {} }
14.2 内存占用分析
使用JProfiler查看:
- 对象头开销
- 继承导致的字段对齐
- 接口方法表占用
14.3 内联策略调整
JVM参数:
bash复制-XX:MaxInlineSize=35 -XX:FreqInlineSize=325
15. 代码质量保障
15.1 静态分析工具
使用Checkstyle检查:
- 封装违规(public字段)
- 继承深度限制
- 方法重写检查
15.2 架构守护
ArchUnit测试示例:
java复制@ArchTest
static final ArchRule no_cycles =
slices().matching("com.example.(*)..")
.should().beFreeOfCycles();
15.3 代码评审要点
OOP专项检查清单:
- 所有字段是否默认private
- 子类是否真正is-a父类
- 是否存在instanceof类型判断
- 接口是否定义最小必要方法
- 继承层次是否超过3层
16. 复杂系统设计案例
16.1 电商促销引擎
策略模式+工厂方法:
java复制interface DiscountStrategy {
BigDecimal apply(Order order);
}
class DiscountEngine {
private Map<String, DiscountStrategy> strategies;
BigDecimal calculate(Order order) {
return strategies.values().stream()
.map(s -> s.apply(order))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
}
16.2 游戏技能系统
组合+装饰器:
java复制interface SkillEffect {
void apply(Character target);
}
class CompositeEffect implements SkillEffect {
private List<SkillEffect> effects;
void apply(Character target) {
effects.forEach(e -> e.apply(target));
}
}
class FireDamageEffect implements SkillEffect {
private int baseDamage;
void apply(Character target) {
target.takeDamage(baseDamage * getFireResistFactor(target));
}
}
16.3 物联网设备管理
状态模式:
java复制interface DeviceState {
void handleCommand(Device device, Command cmd);
}
class OnlineState implements DeviceState {
public void handleCommand(Device device, Command cmd) {
if (cmd instanceof UpdateCommand) {
device.sendToPhysicalDevice(cmd);
}
}
}
class OfflineState implements DeviceState {
public void handleCommand(Device device, Command cmd) {
if (cmd instanceof UpdateCommand) {
device.queueCommand(cmd);
}
}
}
17. 反模式与重构方案
17.1 上帝对象
症状:
- 一个类承担太多职责
- 频繁修改且影响范围大
重构:
- 识别内聚功能块
- 提取为独立类
- 使用组合关系
17.2 菱形继承
问题场景:
java复制class A { void foo() {} }
class B extends A { void foo() {} }
class C extends A { void foo() {} }
class D extends B, C {} // Java不支持
解决方案:
- 改为接口继承
- 使用委托
17.3 过度多态
典型问题:
- 接口方法过多
- 实现类需要空实现不相关方法
改进:
- 接口隔离原则
- 拆分为更小接口
18. 团队协作规范
18.1 继承使用准则
- 禁止超过3层的继承链
- 父类必须为abstract或final
- 所有重写方法必须加@Override
- 子类不得缩小访问权限
18.2 接口设计原则
- 单一职责
- 默认方法仅用于向后兼容
- 避免接口继承接口
- 方法数控制在5个以内
18.3 代码评审checklist
- [ ] 所有字段private
- [ ] final不可变对象
- [ ] 无重复条件判断
- [ ] 子类可替换父类
- [ ] 接口而非实现编程
19. 性能与安全的平衡
19.1 防御性拷贝的代价
性能敏感场景的优化:
java复制// 原始安全版本
public Date getDate() {
return new Date(innerDate.getTime());
}
// 信任内部调用版本
@InternalUseOnly
public Date getDateUnsafe() {
return innerDate;
}
19.2 反射与封装
性能测试显示:
- 直接调用:1x
- 反射调用:5-10x
- setAccessible(true):2-3x
19.3 多线程环境
安全发布模式:
java复制class SafePublisher {
private final Map<String, String> data;
public SafePublisher(Map<String, String> input) {
this.data = Collections.unmodifiableMap(
new HashMap<>(input));
}
}
20. 现代化改造路径
20.1 从Java8到Java17
逐步升级策略:
- 先迁移到Java11 LTS
- 使用jdeprscan检查过时API
- 逐步引入:
- var局部变量
- 文本块
- 模式匹配
- 最终迁移到Java17
20.2 模块化改造
步骤示例:
- 识别现有包依赖
- 定义初始module-info.java
- 使用jdeps分析
- 逐步拆分模块
20.3 记录类型迁移
将传统POJO转为record:
java复制// 改造前
class Person {
private final String name;
private final int age;
// 构造器+getter+equals+hashCode+toString
}
// 改造后
record Person(String name, int age) {}
21. 跨语言对比
21.1 Kotlin的实现
密封类语法对比:
kotlin复制sealed class Result<out T> {
data class Success<T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
}
21.2 C#特性比较
属性语法差异:
csharp复制// C#属性
public string Name {
get => _name;
set => _name = value ?? throw new ArgumentNullException();
}
21.3 TypeScript的OOP
接口扩展能力:
typescript复制interface Named {
name: string;
}
interface Greetable extends Named {
greet(): void;
}
22. 调试技巧精要
22.1 多态调用追踪
使用条件断点:
- 在接口方法入口设置断点
- 条件:instanceof ConcreteImpl
22.2 继承链分析
JDK工具:
bash复制jhsdb jstack --pid <PID> | grep -A10 "Thread name"
22.3 内存泄漏定位
继承相关的常见泄漏:
- 静态集合持有子类实例
- 父类未正确实现close()
- 监听器未注销
23. 设计原则进阶
23.1 开闭原则实践
扩展点设计模式:
java复制public interface ExtensionPoint<T> {
void process(T context);
}
public class Processor {
private List<ExtensionPoint<Context>> extensions;
public void register(ExtensionPoint<Context> ep) {
extensions.add(ep);
}
}
23.2 依赖倒置实现
Spring中的典型应用:
java复制@Repository
interface UserRepository extends JpaRepository<User, Long> {}
@Service
class UserService {
private final UserRepository repo; // 依赖接口
@Autowired
public UserService(UserRepository repo) {
this.repo = repo;
}
}
23.3 接口隔离案例
拆分胖接口:
java复制// 改造前
interface Worker {
void code();
void test();
void deploy();
void monitor();
}
// 改造后
interface Developer {
void code();
void test();
}
interface DevOps {
void deploy();
void monitor();
}
24. 微服务中的OOP
24.1 DTO设计模式
使用record简化:
java复制public record UserDTO(
Long id,
String username,
Instant createdAt
) {}
24.2 服务契约设计
接口版本控制策略:
- 兼容性变更:添加方法
- 非兼容变更:新接口
- @Deprecated过渡期
24.3 聚合根设计
领域模型示例:
java复制public class Order {
private OrderId id;
private List<OrderItem> items;
public void addItem(ProductId productId, int quantity) {
// 业务规则校验
items.add(new OrderItem(productId, quantity));
}
}
25. 并发编程模型
25.1 不可变对象优势
线程安全保证:
java复制@Immutable
public final class Transaction {
private final BigDecimal amount;
private final Currency currency;
// 仅需final字段+深度拷贝
}
25.2 策略模式+并发
无状态策略:
java复制interface PricingStrategy {
BigDecimal calculate(Order order); // 无实例字段
}
class ConcurrentPricingService {
private final Map<String, PricingStrategy> strategies;
// 线程安全:所有策略无状态
}
25.3 继承与锁
父类synchronized方法的影响:
java复制class Base {
public synchronized void doWork() {...}
}
class Sub extends Base {
@Override
public void doWork() {
super.doWork(); // 持有Base.class锁
// 新增逻辑
}
}
26. 领域特定设计
26.1 金融领域模型
精确计算模式:
java复制public class Money {
private final BigDecimal amount;
private final Currency currency;
public Money add(Money other) {
checkCurrencyMatch(other);
return new Money(amount.add(other.amount), currency);
}
}
26.2 游戏领域应用
组件模式:
java复制class GameObject {
private Map<Class<?>, Component> components;
public <T extends Component> T getComponent(Class<T> type) {
return type.cast(components.get(type));
}
}
interface Component {}
class PhysicsComponent implements Component {...}
26.3 物联网领域
状态管理:
java复制public abstract class DeviceState {
public void handleMessage(Device device, Message msg) {
throw new UnsupportedOperationException();
}
}
public class ConnectedState extends DeviceState {
@Override
public void handleMessage(Device device, Message msg) {
// 处理在线消息
}
}
27. 工具类设计艺术
27.1 私有构造器防御
防止实例化:
java复制public final class StringUtils {
private StringUtils() {
throw new AssertionError();
}
public static boolean isEmpty(String s) {...}
}
27.2 方法链优化
流畅接口设计:
java复制public class QueryBuilder {
private QueryBuilder() {}
public static Select select(String... fields) {
return new Select(fields);
}
public static class Select {
public From from(String table) {...}
}
}
27.3 静态工厂方法
替代构造器:
java复制public class Complex {
private final double real;
private final double imag;
private Complex(double r, double i) {
this.real = r;
this.imag = i;
}
public static Complex fromCartesian(double r, double i) {
return new Complex(r, i);
}
public static Complex fromPolar(double modulus, double angle) {
return new Complex(
modulus * Math.cos(angle),
modulus * Math.sin(angle));
}
}
28. 异常处理策略
28.1 检查异常封装
避免污染接口:
java复制interface DataLoader {
// 不声明throws SQLException
List<String> loadNames() throws DataAccessException;
}
class JdbcLoader implements DataLoader {
public List<String> loadNames() throws DataAccessException {
try {
// JDBC操作
} catch (SQLException e) {
throw new DataAccessException(e);
}
}
}
28.2 继承体系设计
异常分类:
java复制abstract class BusinessException extends RuntimeException {
private final ErrorCode code;
protected BusinessException(ErrorCode code, String message) {
super(message);
this.code = code;
}
}
class ValidationException extends BusinessException {...}
class PaymentException extends BusinessException {...}
28.3 防御性编程
参数校验:
java复制public class Range {
private final int start;
private final int end;
public Range(int start, int end) {
if (start > end) {
throw new IllegalArgumentException(
"Start must be <= end");
}
this.start = start;
this.end = end;
}
}
29. 测试驱动开发
29.1 接口契约测试
验证LSP:
java复制@Test
void testSubstitutability() {
List<Integer> list = new ArrayList<>(); // 可替换为LinkedList
testListContract(list);
}
void testListContract(List<Integer> list) {
list.add(1);
assertEquals(1, list.get(0));
}
29.2 Mock对象策略
多态测试:
java复制@Test
void testPaymentProcessor() {
PaymentStrategy mock = mock(PaymentStrategy.class);
PaymentProcessor processor = new PaymentProcessor(mock);
processor.process(100);
verify(mock).execute(100);
}
29.3 继承测试框架
抽象测试类:
java复制public abstract class AbstractDaoTest<T> {
protected abstract Dao<T> createDao();
@Test
void testSaveAndFind() {
Dao<T> dao = createDao();
T entity = createTestEntity();
dao.save(entity);
assertNotNull(dao.find(entity.getId()));
}
}
30. 持续演进建议
30.1 技术雷达扫描
定期评估:
- 新语言特性(如record、sealed类)
- 框架更新(Spring对JDK新特性的支持)
- 工具链增强(JUnit5参数化测试)
30.2 重构路线图
渐进式改进:
- 识别上帝对象
- 替换条件逻辑为多态
- 引入策略模式
- 应用设计原则检查
30.3 学习资源推荐
深度阅读:
- 《Effective Java》第3版
- 《Java并发编程实战》
- 《领域驱动设计》
- Java Language Specification
在真实项目中,我发现很多团队在OOP进阶实践上存在认知断层——要么过度设计导致系统复杂,要么缺乏设计导致代码僵化。掌握这些原则的关键在于理解其本质目的:管理复杂度,而非机械套用模式。建议从小的重构开始,逐步培养对优秀设计的直觉判断力。
