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

一、定义

单一职责原则(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{

	@Override
	public UserVO query(String name) {
	
		 System.out.println("我是查询");
		//过程省略
		UserVO user = new UserVO();
		
		return user;
	}

	@Override
	public void insert(UserVO user) {
	   //do nothing
		
	}

	@Override
	public void update(UserVO user) {
		  //do nothing
		
	}

	@Override
	public 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{

	@Override
	public UserVO query(String name) {
	
		 
		//do nothing
		
		
		return null;
	}

	@Override
	public void insert(UserVO user) {
	  System.out.println("我是新增");
		
	}

	@Override
	public void update(UserVO user) {
		 System.out.println("我是修改");
		
	}

	@Override
	public 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{

	

	@Override
	public void insert(UserVO user) {
	  System.out.println("我是新增");
		
	}

	@Override
	public void update(UserVO user) {
		 System.out.println("我是修改");
		
	}

	@Override
	public 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{

	@Override
	public UserVO query(String name) {
	
		 System.out.println("我是查询");
		//过程省略
		UserVO user = new UserVO();
		
		return user;
	}

	@Override
	public UserVO[] query(String[] names) {
		// TODO Auto-generated method stub
		return null;
	}

	

}

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

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

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






你可能感兴趣的:(设计模式)