单一职责原则(SRP:single responsibility principle)
定义:一个类或者模块应该有且只有一个改变的原因,通俗的讲就是一个类只能拥有一个职责。
实例:比如一个类同时拥有A和B两个职责,当需要对A职责进行修改时,可能由于莫须有的原因导致B功能出现问题。所以这里就需要将类分解为A和B两个类。
我们程序开发中的登陆类,用户类都是一个大的单一职责。程序员都明白要写出一个高内聚低耦合的程序,但是由于我们的开发水平或者业务需求的变更,B职责又细分出B1、B2职责,这就是所谓的职责扩散。
虽然会违背单一职责,但是我们遇到这种问题通常是在B类中就地分解B1、B2的职责。这样做无可厚非,但是需要考虑是否会出现B3、B4... 到那时再去分解职责,代价昂贵。
下面将通过程序深入理解 职责扩散 后的处理方式:
这是一个鸟的类,和鸟飞行的实现。
class bird {
public function fly($birdName) {
echo $birdName . " can fly!";
}
}
定义鹰的类,并调用fly方法
class client {
$birdObj = new bird();
$birdObj->fly('鹰');
$birdObj->fly('麻雀');
$birdObj->fly('企鹅');
}
企鹅也属于鸟类,当我们调用方法时,发现企鹅是不能飞的。这时候我们可以在代码级别和方法级别做弥补。
//代码级别的弥补
class bird {
public function fly($birdName) {
if($birdName == '企鹅'){
echo $birdName . "can't fly!";
} else {
echo $birdName . " can fly!";
}
}
}
//方法级别的弥补(企鹅调用notFly方法)
class bird {
//会飞的鸟类
public function fly($birdName) {
echo $birdName . " can fly!";
}
//不会飞的鸟类
public function notFly($birdName) {
echo $birdName . " can't fly!";
}
}
代码级开小灶式的修复方法,相信大家就算想不到也能闻到其中的坏味道,当企鹅再细分为帝企鹅、王企鹅,这里只能妥协是的继续修改,而且说不定还改出鹰不能飞的结果。
而方法级的修改,可以避免此问题,只有类中方法少的时候是比较适用的,类足够大时,这就是方法级别的开小灶了。
单一职责原则的优点:
可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
提高类的可读性,提高系统的可维护性;
变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。
上面的问题用代码级的解决方式,是可以接收的,但是如果能够预测到以后每个动物都需要复杂的表现时,可以考虑将bird 作为基类,提供所有鸟类共同的方法,飞行的行为作为interface接口实现。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。