单一职责原则
名词解释:
单一职责原则(SRP:Single responsibility principle)又称单一功能原则,面向对象六个基本原则之一。它规定一个类应该只有一个发生变化的原因。该原则由罗伯特·C·马丁(Robert C. Martin)于《敏捷软件开发:原则、模式和实践》一书中给出的。马丁表示此原则是基于汤姆·狄马克(Tom DeMarco)和Meilir Page-Jones的著作中的内聚性原则发展出的。
所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。
一句话总结:
一个类只负责一个任务,就像一个人在公司内只做一件事。
现实场景:
在一个餐厅中假如有厨师、收银员、后勤三种角色,每个角色都有不同的职责,厨师负责烧菜,收银员负责结帐,后勤负责清洗工作。那么他们的任务应该是分得很清楚的,只要是烧菜类的就交由厨师,收银类的就找收银员,后勤就只管洗碗。
代码实现
/**
*厨师类
*/
class CookPerson{
public void task(){
System.out.print("烧菜");
}
}
/**
*收银员类
*/
class CashierPerson{
public void task(){
System.out.print("结账");
}
}
/**
*后勤类
*/
class WashPerson{
public void task(){
System.out.print("洗碗");
}
}
总结:
单一职责原则很简单,但事务往往是两面性的,粗看简单确未必是简单,简单其实就是复杂。“简单就是终极的复杂”,那么复杂是终极的简单吗?一定不是!但也未必没有是的可能。在以上代码实现中实现了单一职责。假如有一个新任务需要洗菜,我们只需要更改后勤类增加洗菜的功能,对别的类没有影响。在设计软件时也会自觉的遵守这一重要原则,因为这是常识。在软件编程中,谁也不希望因为修改了一个功能导致其他的功能发生故障。而避免出现这一问题的方法便是遵循单一职责原则。虽然单一职责原则如此简单,并且被认为是常识,但是即便是经验丰富的程序员写出的程序,也会有违背这一原则的代码存在。为什么会出现这种现象呢?因为有职责扩散。所谓职责扩散,就是因为某种原因,职责被分化为粒度更细的职责task1和task2。 假如我们此时需增一个配菜的任务,这个任务是由哪个类来完成呢,是由后勤类呢还是厨师类呢。又或者需求变更了我们不烧菜了,改为做蛋糕了等等。类的功能性就会引起变更,此时我们是考虑重用原类呢还是重新构建或者是扩散呢,因为这些都有不确定性,此时的简单就不好把握了。所以说软件的重构真是无处不在无时不有,那只有到具体情况具体分析了。
遵循单一职责原的优点有:
1.可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
2.提高类的可读性,提高系统的可维护性;
3.变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。
名词解释:
单一职责原则(SRP:Single responsibility principle)又称单一功能原则,面向对象六个基本原则之一。它规定一个类应该只有一个发生变化的原因。该原则由罗伯特·C·马丁(Robert C. Martin)于《敏捷软件开发:原则、模式和实践》一书中给出的。马丁表示此原则是基于汤姆·狄马克(Tom DeMarco)和Meilir Page-Jones的著作中的内聚性原则发展出的。
所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。
一句话总结:
一个类只负责一个任务,就像一个人在公司内只做一件事。
现实场景:
在一个餐厅中假如有厨师、收银员、后勤三种角色,每个角色都有不同的职责,厨师负责烧菜,收银员负责结帐,后勤负责清洗工作。那么他们的任务应该是分得很清楚的,只要是烧菜类的就交由厨师,收银类的就找收银员,后勤就只管洗碗。
代码实现
/**
*厨师类
*/
class CookPerson{
public void task(){
System.out.print("烧菜");
}
}
/**
*收银员类
*/
class CashierPerson{
public void task(){
System.out.print("结账");
}
}
/**
*后勤类
*/
class WashPerson{
public void task(){
System.out.print("洗碗");
}
}
总结:
单一职责原则很简单,但事务往往是两面性的,粗看简单确未必是简单,简单其实就是复杂。“简单就是终极的复杂”,那么复杂是终极的简单吗?一定不是!但也未必没有是的可能。在以上代码实现中实现了单一职责。假如有一个新任务需要洗菜,我们只需要更改后勤类增加洗菜的功能,对别的类没有影响。在设计软件时也会自觉的遵守这一重要原则,因为这是常识。在软件编程中,谁也不希望因为修改了一个功能导致其他的功能发生故障。而避免出现这一问题的方法便是遵循单一职责原则。虽然单一职责原则如此简单,并且被认为是常识,但是即便是经验丰富的程序员写出的程序,也会有违背这一原则的代码存在。为什么会出现这种现象呢?因为有职责扩散。所谓职责扩散,就是因为某种原因,职责被分化为粒度更细的职责task1和task2。 假如我们此时需增一个配菜的任务,这个任务是由哪个类来完成呢,是由后勤类呢还是厨师类呢。又或者需求变更了我们不烧菜了,改为做蛋糕了等等。类的功能性就会引起变更,此时我们是考虑重用原类呢还是重新构建或者是扩散呢,因为这些都有不确定性,此时的简单就不好把握了。所以说软件的重构真是无处不在无时不有,那只有到具体情况具体分析了。
遵循单一职责原的优点有:
1.可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
2.提高类的可读性,提高系统的可维护性;
3.变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。
4.需要说明的一点是单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则。