当前位置: 首页 > news >正文

软件架构设计7大原则

设计原则

    • 1. 开闭原则(OCP - Open-Closed Principle)
    • 2. 单一职责原则(SRP - Single Responsibility Principle)
    • 3. 里氏替换原则(LSP - Liskov Substitution Principle)
    • 4. 依赖倒置原则(DIP - Dependency Inversion Principle)
    • 5. 接口隔离原则(ISP - Interface Segregation Principle)
    • 6. 迪米特法则(LoD - Law of Demeter)
    • 7. 组合优于继承(Composition Over Inheritance)
    • 总结

在Java软件开发中,有7大重要的设计原则,它们帮助开发者编写高内聚、低耦合可维护、可扩展的代码。这些原则也被称为SOLID原则 + 其他关键设计原则,它们是面向对象编程(OOP)和软件架构的核心。

  • 高内聚
  • 低耦合
  • 可维护
  • 可扩展

1. 开闭原则(OCP - Open-Closed Principle)

定义:

对扩展开放,对修改关闭。

含义:

  • 软件应该可以扩展新功能,而不应该修改已有代码。
  • 使用接口抽象类策略模式等方式来实现扩展。

示例:

// 定义抽象接口,避免修改原有代码
interface Shape {
    double calculateArea();
}

class Circle implements Shape {
    private double radius;
    public Circle(double radius) { this.radius = radius; }
    @Override
    public double calculateArea() { return Math.PI * radius * radius; }
}

class Rectangle implements Shape {
    private double width, height;
    public Rectangle(double width, double height) { this.width = width; this.height = height; }
    @Override
    public double calculateArea() { return width * height; }
}

✅ 好处: 新增 Triangle(三角形)时,只需实现 Shape 接口,不用修改原代码,符合开闭原则。


2. 单一职责原则(SRP - Single Responsibility Principle)

定义:

一个类应该只有一个引起它变化的原因。

含义:

  • 每个类 只负责 一个功能,避免过多职责耦合。
  • 增强代码的可读性可维护性

示例(违反单一职责):

class ReportManager {
    void generateReport() { /* 生成报表的逻辑 */ }
    void saveToDatabase() { /* 数据库存储逻辑 */ }
    void sendEmail() { /* 发送邮件逻辑 */ }
}

✅ 遵循单一职责原则(拆分成多个类):

class ReportGenerator {
    void generateReport() { /* 生成报表 */ }
}

class DatabaseSaver {
    void saveToDatabase() { /* 存储数据 */ }
}

class EmailSender {
    void sendEmail() { /* 发送邮件 */ }
}

好处: 各个类职责单一,避免代码臃肿、难维护


3. 里氏替换原则(LSP - Liskov Substitution Principle)

定义:

子类可以替换父类,并且不会影响父类的功能。

含义:

  • 子类应该能够扩展父类的功能,而不会改变父类的行为
  • 不能让子类破坏父类的逻辑,否则多态会失效。

示例(违反LSP):

class Bird {
    void fly() { System.out.println("Bird is flying"); }
}

class Penguin extends Bird { // 企鹅不会飞
    @Override
    void fly() { throw new UnsupportedOperationException("Penguin cannot fly!"); }
}

遵循LSP(重构):

interface Bird { }
interface FlyableBird extends Bird {
    void fly();
}

class Sparrow implements FlyableBird {
    @Override
    public void fly() { System.out.println("Sparrow is flying"); }
}

class Penguin implements Bird { /* 企鹅不会飞 */ }

好处: 避免子类破坏父类逻辑,保证多态的正确性。


4. 依赖倒置原则(DIP - Dependency Inversion Principle)

定义:

高层模块不应该依赖于低层模块,而应该依赖于抽象。

含义:

  • 上层代码 不依赖于 具体实现(类),而是依赖 接口或抽象类
  • 低层代码 也依赖 接口,而不是直接实现。

示例(违反DIP):

class MySQLDatabase {
    void connect() { System.out.println("Connecting to MySQL"); }
}

class Application {
    private MySQLDatabase database = new MySQLDatabase();
    void start() { database.connect(); }
}

遵循DIP(使用接口):

interface Database {
    void connect();
}

class MySQLDatabase implements Database {
    @Override
    public void connect() { System.out.println("Connecting to MySQL"); }
}

class Application {
    private Database database;
    public Application(Database database) { this.database = database; }
    void start() { database.connect(); }
}

好处:

  • 未来如果更换 PostgreSQLDatabase无需修改 Application 代码,增强灵活性。

5. 接口隔离原则(ISP - Interface Segregation Principle)

定义:

接口应该尽可能小,每个接口只定义特定功能,而不是一个大而全的接口。

含义:

  • 避免“胖接口”,不让类实现它们不需要的方法。
  • 通过多个小接口,提供更清晰的抽象。

示例(违反ISP):

interface Animal {
    void eat();
    void fly();
    void swim();
}

class Dog implements Animal {
    public void eat() { /* 正常实现 */ }
    public void fly() { throw new UnsupportedOperationException(); }  // 不需要
    public void swim() { /* 正常实现 */ }
}

遵循ISP(拆分接口):

interface Eater { void eat(); }
interface Flyer { void fly(); }
interface Swimmer { void swim(); }

class Dog implements Eater, Swimmer {
    public void eat() { /* 正常实现 */ }
    public void swim() { /* 正常实现 */ }
}

好处: 避免不必要的方法实现,提高代码灵活性


6. 迪米特法则(LoD - Law of Demeter)

定义:

一个类应该尽可能少地与其他类发生直接交互。

含义:

  • 最小知识原则(Least Knowledge Principle, LKP)一个对象应尽量减少对其他对象的依赖
  • 降低耦合度,减少不必要的依赖。

示例(违反LoD):

class Engine {
    void start() { System.out.println("Engine starting..."); }
}

class Car {
    Engine engine = new Engine();
    void start() { engine.start(); } // 直接访问Engine
}

遵循LoD(使用封装):

class Engine {
    void start() { System.out.println("Engine starting..."); }
}

class Car {
    private Engine engine = new Engine();
    void startCar() { engine.start(); } // 间接访问
}

好处: 避免暴露不必要的内部实现,降低代码耦合度。


7. 组合优于继承(Composition Over Inheritance)

定义:

优先使用“组合”来实现代码复用,而不是继承。

含义:

  • 继承耦合度高,父类变化会影响子类。
  • 使用组合(has-a关系)更灵活,可以在运行时动态替换组件。

示例(组合替代继承):

class Engine {
    void start() { System.out.println("Engine starting..."); }
}

class Car {
    private Engine engine;
    Car(Engine engine) { this.engine = engine; }
    void startCar() { engine.start(); }
}

好处: 增强灵活性,避免继承带来的复杂依赖。


总结

原则核心思想
OCP开闭原则:对扩展开放,对修改关闭
SRP单一职责:一个类只做一件事
LSP里氏替换:子类可以替换父类
DIP依赖倒置:依赖抽象而非具体实现
ISP接口隔离:接口要小而精,不要臃肿
LoD迪米特法则:减少耦合,少与其他类交互
组合优于继承使用组合代替继承,增强灵活性

熟练掌握这些原则,可以帮助你写出更灵活、可维护、可扩展的Java代码! 🚀

相关文章:

  • 面试八股文--数据库基础知识总结(3)MySQL优化
  • 使用Windbg分析dump文件定位软件异常的方法与操作步骤
  • pandas如何在指定位置添加一个dataframe
  • 力扣hot100刷题——栈
  • 【大模型系列篇】国产开源大模型DeepSeek-V3技术报告解析
  • quillEditor 禁用复制粘贴图片,以及class转style等问题
  • 【C++ 函数重载】—— 现代编译技术下的多态表达与性能优化
  • 【leetcode hot 100 56】合并区间
  • 【计算机网络】Socket
  • CSDN markdown 操作指令等
  • 动漫短剧开发公司,短剧小程序搭建快速上线
  • Springboot整合WebSocket+Redis以及微信小程序如何调用
  • 2000-2020年各省地方财政一般预算收入数据
  • 【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-附录B-严格模式
  • FastGPT 源码:基于 LLM 实现 Rerank (含Prompt)
  • 深度学习-142-Text2SQL之基于langchain的少量样本提示词模板FewShotPromptTemplate的应用基础(一)
  • maven推送jar包到nexus
  • 前端大文件上传
  • 鬼泣:项目前置设置杂项
  • 【每日学点HarmonyOS Next知识】Web Header更新、状态变量嵌套问题、自定义弹窗、stack圆角、Flex换行问题
  • 保定市网站制作公司/新闻软文广告
  • 郑州专业的网站建设公司哪家好/宁波seo网络推广定制多少钱
  • 大朗做网站公司/三个关键词介绍自己
  • 最新手机网站推荐/网络推广方法怎么做
  • 苏州企业建设网站价格/免费的云服务器有哪些
  • 西安网站 技术支持牛商网/足球直播在线直播观看免费cctv5