在介绍接口隔离原则之前我们先看下面举例说明中的第一个例子——反例
举例说明
反例
类说明
因为类比较清晰,我们先看类可以看出,DogPlays.java和CatPlays.java分别实现了接口PetInterface,DogPlaysUse和CatPlaysUse又分别通过该接口依赖DogPlays和CatPlays,但是都没有用完实现类里的所有方法,造成资源浪费
代码说明
如果类不是很明白的,直接看代码感受一下!直接上代码:如果看代码还有点不明白,往下看测试,感受一下之间的调用
测试
来,我们来看看测试,感受一下当然这个测试稍微有点负责,主要让你体验一下我们开发中对这种情况可能应用的场景,那么平时我们测试的话可以稍微简单点,接下来看简单点的这就省事多了!OK,到这里应该明白彻底明白这个案例了吧!
分析缺点
可以看出,PetInterface的实现有两个,分别是DogPlays.java和CatPlays.javaDogPlaysUse这个类通过接口PetInterface依赖DogPlays类,但是只用到playBall和likeToGoOut方法。而DogPlays类实现了PetInterface接口的所有方法,所以造成浪费同样的,CatPlaysUse这个类通过接口PetInterface依赖CatPlays类,但是只用到playBall、climbTree和catchMouse方法,所以也造成浪费
正例
那么对于上面的案例怎么来优化呢?既然一个接口有浪费,那么我们就把它拆解,这其实就是我们的接口隔离原则,请继续……
类说明
如可见,对于上述案例,如果用接口隔离原则优化的话,我们设计的时候拆成3个接口最为合理
代码说明
对比反例,这样就看着干净舒服多了
测试
测试就没啥好说的了,自己看吧
方案评价
对比第一种写法,使用接口隔离的这种写法明显让旁人看着代码也是很清晰,接口拆开之后各行其职责,代码看着不臃肿,后续功能变更或新增的话维护起来也好维护
总结
客户端不应该依赖它不需要的接口一个类对另外一个类的依赖,应建立在最小的接口上,其实就是一个接口里不要放一个功能模块外的其他方法,理解起来跟单一职责原则有点像,自己体会体会吧
附代码
反例代码
package com.liu.susu.principle.segregation.example1;
import org.springframework.stereotype.Service;
/**
* @Description 接口隔离原则——反例
* @Author susu
* @date 2022-02-12
**/
public interface PetInterface {
void playBall();//玩球
void climbTree();//爬树
void catchMouse();//抓老鼠
void likeToGoOut();//遛狗
}
@Service('dog')
class DogPlays implements PetInterface{
@Override
public void playBall() {
System.out.println('狗狗喜欢玩球……');
}
public void climbTree() {
System.out.println('DogPlays类 实现了 climbTree 方法');
}
public void catchMouse() {
System.out.println('DogPlays类 实现了 catchMouse 方法');
}
public void likeToGoOut() {
System.out.println('狗狗喜欢每天被遛遛……');
}
}
@Service
class CatPlays implements PetInterface{
public void playBall() {
System.out.println('小猫喜欢玩球……');
}
public void climbTree() {
System.out.println('小猫喜欢爬树……');
}
public void catchMouse() {
System.out.println('小猫喜欢抓老鼠……');
}
public void likeToGoOut() {
System.out.println('CatPlays 类 实现了 likeToGoOut 方法');
}
}
/**
* DogPlaysUse 类通过接口PetInterface 依赖(使用)DogPlays类,
* 但是只用到 playBall 和 likeToGoOut 方法
*/
@Service
class DogPlaysUse {
public void playBall(PetInterface petInterface){
petInterface.playBall();
}
public void likeToGoOut(PetInterface petInterface) {
petInterface.likeToGoOut();
}
}
/**
* CatPlaysUse 类通过接口PetInterface 依赖(使用)DogPlays类,
* 但是只用到 playBall、climbTree 和 catchMouse 方法
*/
@Service
class CatPlaysUse {
public void playBall(PetInterface petInterface){
petInterface.playBall();
}
public void climbTree(PetInterface petInterface) {
petInterface.climbTree();
}
public void catchMouse(PetInterface petInterface) {
petInterface.catchMouse();
}
}
class Test {
public static void main(String[] args) {
//DogPlaysUse 这个类通过接口 依赖 DogPlays 类
DogPlaysUse dogPlaysUse = new DogPlaysUse();
dogPlaysUse.playBall(new DogPlays());
dogPlaysUse.likeToGoOut(new DogPlays());
System.out.println('
======小猫开始表演……=====
' );
//DogPlaysUse 这个类通过接口 依赖 CatPlays 类
CatPlaysUse catPlaysUse = new CatPlaysUse();
catPlaysUse.playBall(new CatPlays());
}
}
下面这个是Controller的那个测试
package com.liu.susu.principle.segregation.example1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @FileName PetController
* @Description
* @Author susu
* @date 2022-02-12
**/
@Controller
@RequestMapping('/dog')
public class PetController {
@Autowired
@Qualifier('dog')
private PetInterface petInterface;
@Autowired
@Qualifier('catPlays')
private PetInterface petInterface2;
@Autowired
private DogPlaysUse dogPlaysUse;
@Autowired
private CatPlaysUse catPlaysUse;
@RequestMapping('/hello')
@ResponseBody
public String hello(){
dogPlay();
catPlay();
return 'hello world!';
}
public void dogPlay(){
dogPlaysUse.playBall(petInterface);
System.out.println('dogPlaysUse.playBall(petInterface)--->ok');
}
public void catPlay(){
catPlaysUse.playBall(petInterface2);
System.out.println('catPlaysUse.playBall(petInterface2)--->ok');
}
}
正例代码
其他
文章中用到多个类实现同一个接口的情况,开发中可能会遇到注入问题,不妨看看:解决同一接口有多个实现类的注入问题.
文章为作者独立观点,不代表 股票程序化软件自动交易接口观点