单一职责原则(Single Responsibility Principle)
定义:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。
问题由来:类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。
解决方案:遵循单一职责原则。分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发生故障风险;同理,当修改T2时,也不会使职责P1发生故障风险。
说到单一职责原则,很多人都会不屑一顾。因为它太简单了。稍有经验的程序员即使从来没有读过设计模式、从来没有听说过单一职责原则,在设计软件时也会自觉的遵守这一重要原则,因为这是常识。在软件编程中,谁也不希望因为修改了一个功能导致其他的功能发生故障。而避免出现这一问题的方法便是遵循单一职责原则。虽然单一职责原则如此简单,并且被认为是常识,但是即便是经验丰富的程序员写出的程序,也会有违背这一原则的代码存在。为什么会出现这种现象呢?因为有职责扩散。所谓职责扩散,就是因为某种原因,职责P被分化为粒度更细的职责P1和P2。
比如:类T只负责一个职责P,这样设计是符合单一职责原则的。后来由于某种原因,也许是需求变更了,也许是程序的设计者境界提高了,需要将职责P细分为粒度更细的职责P1,P2,这时如果要使程序遵循单一职责原则,需要将类T也分解为两个类T1和T2,分别负责P1、P2两个职责。但是在程序已经写好的情况下,这样做简直太费时间了。所以,简单的修改类T,用它来负责两个职责是一个比较不错的选择,虽然这样做有悖于单一职责原则。
举例说明,用一个类描述动物呼吸这个场景:
class Animal{
public void breathe(String animal){
System.out.println(animal+"呼吸空气");
}
}
public class Client{
public static void main(String[] args){
Animal animal = new Animal();
animal.breathe("牛");
animal.breathe("羊");
animal.breathe("猪");
}
}
运行结果:
牛呼吸空气
羊呼吸空气
猪呼吸空气
程序上线后,发现问题了,并不是所有的动物都呼吸空气的,比如鱼就是呼吸水的。修改时如果遵循单一职责原则,需要将Animal类细分为陆生动物类Terrestrial,水生动物Aquatic,代码如下:
class Terrestrial{
public void breathe(String animal){
System.out.println(animal+"呼吸空气");
}
}
class Aquatic{
public void breathe(String animal){
System.out.println(animal+"呼吸水");
}
}
public class Client{
public static void main(String[] args){
Terrestrial terrestrial = new Terrestrial();
terrestrial.breathe("牛");
terrestrial.breathe("羊");
terrestrial.breathe("猪");
Aquatic aquatic = new Aquatic();
aquatic.breathe("鱼");
}
}
运行结果:
牛呼吸空气
羊呼吸空气
猪呼吸空气
鱼呼吸水
我们会发现如果这样修改花销是很大的,除了将原来的类分解之外,还需要修改客户端。而直接修改类Animal来达成目的虽然违背了单一职责原则,但花销却小的多,代码如下:
class Animal{
public void breathe(String animal){
if("鱼".equals(animal)){
System.out.println(animal+"呼吸水");
}else{
System.out.println(animal+"呼吸空气");
}
}
}
public class Client{
public static void main(String[] args){
Animal animal = new Animal();
animal.breathe("牛");
animal.breathe("羊");
animal.breathe("猪");
animal.breathe("鱼");
}
}
可以看到,这种修改方式要简单的多。但是却存在着隐患:有一天需要将鱼分为呼吸淡水的鱼和呼吸海水的鱼,则又需要修改Animal类的breathe方法,而对原有代码的修改会对调用“猪”“牛”“羊”等相关功能带来风险,也许某一天你会发现程序运行的结果变为“牛呼吸水”了。这种修改方式直接在代码级别上违背了单一职责原则,虽然修改起来最简单,但隐患却是最大的。还有一种修改方式:
class Animal{
public void breathe(String animal){
System.out.println(animal+"呼吸空气");
}
public void breathe2(String animal){
System.out.println(animal+"呼吸水");
}
}
public class Client{
public static void main(String[] args){
Animal animal = new Animal();
animal.breathe("牛");
animal.breathe("羊");
animal.breathe("猪");
animal.breathe2("鱼");
}
}
可以看到,这种修改方式没有改动原来的方法,而是在类中新加了一个方法,这样虽然也违背了单一职责原则,但在方法级别上却是符合单一职责原则的,因为它并没有动原来方法的代码。这三种方式各有优缺点,那么在实际编程中,采用哪一中呢?其实这真的比较难说,需要根据实际情况来确定。我的原则是:只有逻辑足够简单,才可以在代码级别上违反单一职责原则;只有类中方法数量足够少,才可以在方法级别上违反单一职责原则;
例如本文所举的这个例子,它太简单了,它只有一个方法,所以,无论是在代码级别上违反单一职责原则,还是在方法级别上违反,都不会造成太大的影响。实际应用中的类都要复杂的多,一旦发生职责扩散而需要修改类时,除非这个类本身非常简单,否则还是遵循单一职责原则的好。
遵循单一职责原的优点有:
l 可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
l 提高类的可读性,提高系统的可维护性;
l 变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。
需要说明的一点是单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都需要遵循这一重要原则。
相关推荐
单一职责原则(SRP) 单一职责原则(SRP)是面向对象设计的五个基本原则之一。该原则规定,一个类应当只有一个引起它变化的原因。换言之,一个类应该只有一个职责,避免一个类承担多个职责,从而降低类的耦合度和...
1. 单一职责原则(Single Responsibility Principle, SRP) 1.1 原则定义 1.2 为什么需要单一职责原则? 1.3 违反单一职责原则的例子 1.4 应用单一职责原则的改进 1.5 现实应用场景 1.6 单一职责原则的注意事项 2. ...
本文将深入探讨这六大原则中的第一个——单一职责原则(Single Responsibility Principle, SRP),并结合AcountYear.java这个文件名来解析该原则的应用。 单一职责原则指出,一个类或者一个模块应该只有一个引起它...
单一职责原则(Single Responsibility Principle,简称SRP)是面向对象设计的基本原则之一,由罗伯特·C·马丁(Robert C. Martin)在其著作《Clean Architecture》中提出。这一原则主张一个类或模块应当有且仅有一...
在软件设计领域,单一职责原则(Single Responsibility Principle,简称SRP)是面向对象设计的六大原则之一,由罗伯特·C·马丁(Robert C. Martin)在其著作《Clean Code》中提出。这个原则强调一个类或者模块应当...
**单一职责原则(Single Responsibility Principle, SRP)**是面向对象设计中的一个重要原则,由罗伯特·C·马丁(Robert C. Martin)提出。这一原则指出,一个类或者模块应该有且只有一个职责,即它应该只负责一项...
【标题】"C#俄罗斯方块源码(单一职责原则)" 涉及到的核心知识点主要是C#编程语言以及软件设计原则中的“单一职责原则”(Single Responsibility Principle, SRP)。C#是一种广泛用于开发Windows应用程序、Web服务和...
单一职责原则(SRP)是面向对象设计中的一个基本原则,它要求一个类应该只有一个引起它变化的原因。在PHP等面向对象编程语言中,遵守这一原则可以帮助开发人员编写出结构更清晰、维护性更强的代码。接下来,我们将详细...
SOLID原则是由五个设计原则组成的,分别是:单一职责原则(Single Responsibility Principle, SRP)、开闭原则(Open-Closed Principle)、里式替换原则(Liskov Substitution Principle)、接口隔离原则(Interface...
其中,"单一职责原则"(Single Responsibility Principle,SRP)是面向对象设计的基本原则之一,也是Java设计模式中的重要组成部分。本篇文章将深入探讨单一职责原则的概念、意义、应用及其在Java编程中的实际运用。...
**单一职责原则(Single Responsibility Principle, SRP)**是面向对象设计的基本原则之一,由罗伯特·C·马丁(Robert C. Martin)提出,并在《敏捷软件开发:原则、模式和实践》中阐述。这一原则是SOLID原则的首...
其中,“单一职责原则”(Single Responsibility Principle,SRP)是面向对象设计的五个核心原则之一,由罗伯特·C·马丁(Robert C. Martin)在其著作《Clean Code》中提出。这个原则强调一个类或模块应该只有一个...
其中包括SRP(单一职责原则)、OCP(开闭原则)、LSP(里氏替换原则)、ISP(接口分离原则)、DIP(依赖倒置原则)、CRP(组合/聚合复用原则)和PLK(最小知识原则)。 一、SRP(Single Responsibility Principle)...
单一职责原则(Single Responsibility Principle, SRP)指出,一个类或模块应当只有一个改变的原因,即它应该只有一个明确的责任或功能。这样做的目的是为了提高代码的可读性、可维护性和可扩展性。 在上述描述中...
单一职责原则(Single Responsibility Principle,简称SRP)是面向对象设计(OOD)中的一个基本原则。它强调每个类应该只有一个改变的理由,意味着一个类应该只有一个职责,只有一个因素能引起这个类的变更。当类...
这五个原则包括单一职责原则(Single Responsibility Principle,SRP)、开闭原则(Open/Closed Principle,OCP)、里氏替换原则(Liskov Substitution Principle,LSP)、接口隔离原则(Interface Segregation ...
面向对象 设计原则 单一职责原则--SRP 开放封闭原则--OCP Liskov替换原则--LSP 依赖倒置原则--DIP 接口隔离原则--ISP
Java设计模式中的单一职责原则(Single Responsibility Principle,SRP)是面向对象设计的基本原则之一,它的核心思想是:一个类或者一个模块应该只有一个引起它变化的原因。这意味着一个类应该只负责一项职责,使得...
在软件设计领域,单一职责原则(Single Responsibility Principle, SRP)是面向对象设计的基本原则之一,由罗伯特·C·马丁(Robert C. Martin)在其著作《Clean Code》中提出。这一原则强调一个类或者模块应该有且...
1. **编程原则**:《编写整洁代码》强调了如SOLID(单一职责原则SRP、开闭原则OCP、里氏替换原则LSP、接口隔离原则ISP、依赖倒置原则DIP)等核心设计原则。这些原则指导开发者编写出结构良好、易于扩展和维护的代码...