当前位置:首页 > 文章列表 > 文章 > java教程 > Java如何实现OOP设计原则?

Java如何实现OOP设计原则?

2026-03-13 12:40:39 0浏览 收藏
本文深入浅出地揭示了Java中“真正遵循面向对象设计原则”的本质——不是简单地使用class关键字,而是通过接口依赖、依赖注入和里氏替换等实践,让代码具备可替换、可扩展、低耦合的韧性:支付方式增删不改订单逻辑,模块改动互不影响,单元测试轻松隔离,新功能只需新增类而非修改旧代码;它把抽象的SOLID原则转化为开发者日常写new、if和public void时的一句自问:“以后加另一种实现,要动我几行?会破谁的假设?”——让面向对象回归人本,既好懂,又安全。

在Java里如何遵循面向对象设计原则_JavaOOP设计思路说明

什么是“遵循面向对象设计原则”的实际表现

不是写个 class 就算面向对象,而是让类与类之间的关系可替换、可扩展、不耦合。比如你改一个支付模块,不该牵连订单、用户、日志模块;加一种新支付方式(如 Apple Pay),不该动已有代码,只新增类即可。这背后是 SOLID 原则的落地,但别被术语吓住——它本质是「写人能轻松看懂、机器能安全扩改」的代码习惯。

interface 而不是 class 做依赖声明

常见错误:把具体实现类(如 AlipayService)直接写进业务逻辑里,导致后续加 WechatPayService 时必须改方法签名、if-else 判断、甚至单元测试全崩。

正确做法是先定义契约:

public interface PaymentService {
    boolean pay(Order order, BigDecimal amount);
}

再让具体实现去实现它:

public class AlipayService implements PaymentService { ... }
public class WechatPayService implements PaymentService { ... }

业务类只依赖接口:

public class OrderService {
    private final PaymentService paymentService; // 不是 AlipayService!

    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    public void checkout(Order order) {
        paymentService.pay(order, order.getTotal());
    }
}
  • 测试时可用 Mockito.mock(PaymentService.class) 快速隔离
  • 切换支付渠道只需改构造注入的对象,不碰业务逻辑行
  • 违反这点,Open/Closed Principle(开闭原则)就塌了一半

避免在构造函数里做重操作或强依赖初始化

典型反例:new DatabaseConnection()loadConfigFromFile()initHttpClient() 直接塞进构造函数。结果一 new 对象就可能抛 IOException 或阻塞线程,且无法 mock、无法控制生命周期。

更稳妥的做法:

  • 构造函数只接收已创建好的依赖(即依赖注入),保持轻量、无副作用
  • 耗时/异常风险操作移到 init() 方法,由调用方显式触发(如 Spring 的 @PostConstruct
  • 若必须懒加载,用 SupplierOptional 包一层,推迟实例化时机

例如:

public class ReportGenerator {
    private final Supplier<PdfRenderer> rendererSupplier;

    public ReportGenerator(Supplier<PdfRenderer> rendererSupplier) {
        this.rendererSupplier = rendererSupplier; // 不立即 new
    }

    public byte[] generate() {
        PdfRenderer renderer = rendererSupplier.get(); // 真正需要时才创建
        return renderer.render(data);
    }
}

子类不应破坏父类的行为契约

这是 Liskov Substitution Principle(里氏替换原则)最常踩的坑。比如父类 CollectionUtils.isEmpty(List list) 规定:传 null 返回 true;结果子类重写后对 nullNullPointerException,上游所有调用立刻崩溃。

判断是否合规,看三点: