一、什么是单一职责原则?

单一职责原则(Single Responsibility Principle,简称 SRP),是面向对象设计五大基本原则之一。它的定义如下:

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

通俗来说就是: 一个类,只负责一件事。

如果一个类承担了太多职责,就等于把这些功能耦合在了一起。当其中一个职责需求变更时,可能会影响到其他职责,导致代码变得脆弱、难以维护、难以扩展。

二、为什么要遵守单一职责原则

1. 代码更清晰,可读性更强

一个类只做一件事,结构简单、逻辑清晰,别人接手代码时,一眼就能看懂它的作用。

2. 降低耦合,减少 bug

修改某一个功能时,不会意外破坏其他功能,大幅降低 “改一处、崩一片” 的情况。

3. 易于维护和扩展

需求变化时,只需要修改对应的类,不需要改动无关代码,扩展新功能也更方便。

4. 便于单元测试

功能单一,测试用例更简单,覆盖率更高,更容易保证代码质量。

三、一个单一职责原则实例

某基于Java的C/S系统的“登录功能”通过如下登陆类(Login)实现:

问题分析:

这个类存在明显的职责过载问题(违反单一职责原则):

1.界面相关init()display() 负责 UI 展示

2.业务逻辑validate()findUser() 处理登录验证

3.数据访问getConnection() 管理数据库连接

4.入口启动main() 作为程序入口

这种设计会导致:

1.代码耦合度高,难以维护和测试

2.复用性差,无法单独抽取数据库连接或验证逻辑

3.扩展性弱,新增登录方式(如短信、第三方登录)困难

现使用单一职责原则对其进行重构:

我们将原始的 Login 类按照单一职责原则拆分为 4 个核心类,每个类只承担一类核心功能:

1.界面初始化 / 显示功能

 由 LoginView 类承担 它属于视图层(V),专门负责和用户交互:包括初始化登录界面组件、展示界面、接收用户输入的用户名和密码,不处理任何业务逻辑或数据库操作。

2.输入校验 / 用户查询功能 

LoginService 类承担 它属于业务层(C),是登录功能的核心逻辑处理层:负责校验用户名 / 密码的格式是否合法,以及调用数据层查询数据库中是否存在匹配的用户账号。

3.数据库连接功能

 由 DBUtil 类承担 它属于数据层(M),专门封装数据库连接的相关操作:包含数据库地址、用户名、密码等配置信息,对外提供获取数据库连接的方法,供业务层调用。

4.程序入口功能

LoginMain 类承担 它是整个登录模块的启动类,仅负责程序的入口逻辑:在 main 方法中初始化视图层对象,启动整个登录流程,不参与具体的业务或界面逻辑。

重构结果如图所示

四、如何判断是否违背单一职责?

一个简单好用的判断方法:

试着用一句话描述这个类是做什么的。 如果描述里出现了 “和”“以及”“同时” 这类词,基本就违背了单一职责。

例如:

“这个类负责用户管理和邮件发送” → 职责过多

“这个类负责用户数据持久化” → 职责清晰

五、总结

单一职责原则,本质上是追求高内聚、低耦合

它不追求代码最少,而是追求代码清晰、稳定、可维护。在实际开发中,不必过度拆分,但要尽量让每个类、每个方法 “专一”。

代码写出来是给人看的,顺便能在机器上运行。 遵守单一职责,就是对自己和同事的代码负责。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐