单一设计原则
单一职责原则
一、概念
概念:单一职责原则中指出:一个类应该只有一个发生变化的原因。
背景:如果开发的一个功能需求不是一次性的,而是随着业务发展的变化而变化的,那么当一个class类负责超过两个及以上的职责的时候,就在需求的不断迭代中、实现类持续扩张的情况下,就会出现难以维护、不好扩展、测试难度大和上线风险高的问题等等。
模拟场景:
视频网站分类:各类视频网站看电影、电视剧的时候,网站针对不同的用户类型,会在用户观看时给出不同的用户反馈,如一下三种:
- 访问用户:一般可以看480P视频,并提醒用户注册会员才能看高清视频
- 普通会员:可以看720P的超清视频,但是不能够屏蔽掉视频中出现的广告
- VIP会员:既可以看1080P蓝光视频,又可以屏蔽或者关闭掉广告
二、错误设计方式
典型设计方式:
public class VideoUserService {
public void serveGrade(String userType){
if ("VIP".equals(userType)){
System.out.println("vip会员,可以观看1080P电影,也可以选择跳过广告");
}else if ("普通会员".equals(userType)){
System.out.println("普通会员,可以看720P电影,但是不能够跳过广告");
}else if ("访客用户".equals(userType)){
System.out.println("访客用户,可以看780视频");
}
}
}
因为业务逻辑比较简单,所以这样子来写不会有什么问题,但是如果一个类中包含着不同的行为,也就是多种用户职责。那么如果再次需要来做括号中那或者是添加逻辑,那么就会显得非常臃肿。
下面利用单元测试来进行测试:
public class Test {
public static void main(String[] args) {
VideoUserService videoUserService= new VideoUserService();
videoUserService.serveGrade("普通会员");
videoUserService.serveGrade("VIP");
videoUserService.serveGrade("访客用户");
}
}
上面的实现方式市一个类中使用If....else的方式来进行判断操作的,所以调用方法时候是所有的职责用户都使用一个方法来进行实现,作为程序调用入口。对于简单的或者说是不需要来使用迭代的功能,这种实现未尝不可,但是如果面对的是频繁迭代的业务需求,这样的代码结构就很难支持起来 系统迭代,每一次的需求的实现都需要影响到其他逻辑,给整个接口服务带来不可控的风险。
那么根据业务逻辑+单一职责原则来改善上面代码。
上面的核心功能是视频播放,当核心功能开发完整之后,就需要不断的来完善用户的权限,这样子才能更好的运营一家视频网站。
在模拟用户场景汇总,针对不同的用户类型来踢欧冠功能差异化服务,既能够满足客户需求,又可以让部分用户选择付费。
为了满足这样子不断迭代的需求,就不能够使用一个类来将所有职责行为混为一谈,而是需要提供一个上层接口类,对不同的差异化用户给出单独的实现类,拆分各自的职责边界。
三、使用单一原则优化
开始来进行拆分:
public interface IVideoUserService {
/**
* 定义视频类型:480/720/1080P
*/
void definition();
/**
* 这里为什么不给用户添加上?我觉得因为用户权益是可变的!而广告的播放方式相对来说,是固定的,对于不同的用户来说,来对其进行实现
* 广告的播放方式:有广告、无广告
*/
void advertisement();
}
开始来分别建立起来对应的实现类:
public class GuestVideoUserService implements IVideoUserService {
@Override
public void definition() {
System.out.println("访客用户,只能够看480P的视频");
}
@Override
public void advertisement() {
System.out.println("访问用户,必须得看广告");
}
}
public class OrdinaryVideoUserService implements IVideoUserService {
@Override
public void definition() {
System.out.println("普通会员,可以看720P超清视频");
}
@Override
public void advertisement() {
System.out.println("普通会员,需要看广告");
}
}
public class VipVideoUserService implements IVideoUserService {
@Override
public void definition() {
System.out.println("vip会员,1080p蓝光视频");
}
@Override
public void advertisement() {
System.out.println("vip会员,视频无广告");
}
}
每种用户对应的服务职责都有对应的实现类体现,不会互相干扰。当某一类用户需要添加新的运营规则的时候,操作起来是非常方便的。
比如说:所有的注册的用户都是可以发弹幕的、付费用户可以来进行点播等等。
利用单一职责原则的规则进行优化之后,现在每个类都只负责自己的用户行为。后续无论是扩展新的功能还是需要在某个时刻修改用户的行为类,都可以很方便的开发和维护。
进行单元测试:
public class UpdateTest {
public static void main(String[] args) {
IVideoUserService guestVideoUserService = new GuestVideoUserService();
guestVideoUserService.definition();
guestVideoUserService.advertisement();
System.out.println("-----------------------------");
IVideoUserService ordinaryVideoUserService = new OrdinaryVideoUserService();
ordinaryVideoUserService.definition();
ordinaryVideoUserService.advertisement();
System.out.println("-----------------------------");
IVideoUserService videoUserService = new VipVideoUserService();
videoUserService.definition();
videoUserService.advertisement();
}
}
从上面可以看到,在进行抽象的时候,需要知道抽象的核心功能方法是什么?这点无疑是最重要的
只有抽象出来核心功能方法,才能够准确的实现出来对应的单一职责