Java设计模式—单一职责原则(SRP)

来源:互联网 发布:u3d 无法使用java 编辑:程序博客网 时间:2024/05/22 00:38

一、定义

单一职责原则(Single Responsibility Principle),简称SRP。

There should never be more than one reason for a class to change.

应该有且仅有一个原因引起类的变更。

单一职责的意义:

1、降低类的复杂性,实现什么样的职责都有清晰的定义

2、提高可读性

3、提高可维护性

4、降低变更引起的风险,对系统扩展性和维护性很有帮助

个人理解是:接口和方法一定要做到单一职责,不能在一个接口中定义多种业务逻辑;也尽量避免在一个方法里完成多项任务。对于类来说,如果严格按照单一职责原则来的话会导致类过多,代码过于分散,依赖关系变得复杂,所以在类中需要结合业务来对其职责进行折中划分。


二、示例

在平时开发过程中,增删改查是遇到最常见的业务逻辑,用大类来划分,增删改属于写操作,查询属于读操作。所以在对外提供服务的时候一般是将读和写分开的,因为对于读来说,也许需求变化会更多一些,而写操作则是变化少一些,如果都放在一个接口里定义,那么,在增加读操作的时候,势必会影响到写操作,反之亦然。如下示例:

先定一个JavaBean

package com.dp.srp;public class UserVO {private String name;private String sex;private int height;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}}

定义接口:

package com.dp.srp;public interface IUserService {public UserVO query(String name );public void insert(UserVO user);public void update(UserVO user);public void delete(UserVO user);}

定义读操作实现类:

package com.dp.srp.impl;import com.dp.srp.IUserService;import com.dp.srp.UserVO;public class UserQueryServiceImpl implements IUserService{@Overridepublic UserVO query(String name) { System.out.println("我是查询");//过程省略UserVO user = new UserVO();return user;}@Overridepublic void insert(UserVO user) {   //do nothing}@Overridepublic void update(UserVO user) {  //do nothing}@Overridepublic void delete(UserVO user) {  //do nothing}}

定义写操作实现类:

package com.dp.srp.impl;import com.dp.srp.IUserService;import com.dp.srp.UserVO;public class UserMaintainServiceImpl implements IUserService{@Overridepublic UserVO query(String name) { //do nothingreturn null;}@Overridepublic void insert(UserVO user) {  System.out.println("我是新增");}@Overridepublic void update(UserVO user) { System.out.println("我是修改");}@Overridepublic void delete(UserVO user) { System.out.println("我是删除");}}

我们可以看到,在读和写的实现类里都有跟自己业务不相关的操作定义,如果我们现在想增加一个方法,根据多个名称查询,那现在读写操作需要去实现新增的方法。

public UserVO query(String []  names );

这就违背了单一职责原则。


三、修改

现在定义两个接口,读和写。

写操作接口定义:

package com.dp.srp;public interface IUserMaintainService {public void insert(UserVO user);public void update(UserVO user);public void delete(UserVO user);}


读操作接口定义:

package com.dp.srp;public interface IUserQueryService {public UserVO query(String name );public UserVO[] query(String []  names );}

读和写操作实现类定义:

写操作实现定义:

package com.dp.srp.up.impl;import com.dp.srp.IUserMaintainService;import com.dp.srp.UserVO;public class UserMaintainServiceImpl implements IUserMaintainService{@Overridepublic void insert(UserVO user) {  System.out.println("我是新增");}@Overridepublic void update(UserVO user) { System.out.println("我是修改");}@Overridepublic void delete(UserVO user) { System.out.println("我是删除");}}

读操作实现定义:

package com.dp.srp.up.impl;import com.dp.srp.IUserQueryService;import com.dp.srp.UserVO;public class UserQueryServiceImpl implements IUserQueryService{@Overridepublic UserVO query(String name) { System.out.println("我是查询");//过程省略UserVO user = new UserVO();return user;}@Overridepublic UserVO[] query(String[] names) {// TODO Auto-generated method stubreturn null;}}

这样再我们修改读写的时候就不要相互干扰。

当然可能有的网友会问,为什么不为每个操作定义一个接口,这样不是依赖更小,职责更单一么?

这样的认为也是对的,单一职责原则没有说一定要严格遵循,划分尺度也是要按照业务要求来进行。如果我们的服务是对外的,比如微信的各种号,那么我认为是需要划分到最细的粒度,尽量减小改变带来的影响;如果服务是对内,没有跨模块或者系统,那么按照读写来分离我认为是比较合理的。






0 0
原创粉丝点击