接口隔离原则——举例说明Java设计模式中的接口隔离原则

  • 在介绍接口隔离原则之前我们先看下面举例说明中的第一个例子——反例

一、举例说明

1.反例

(1)类图说明

  • 因为类图比较清晰,我们先看类图
    在这里插入图片描述

  • 可以看出, DogPlays.java 和 CatPlays.java 分别实现了接口PetInterface ,DogPlaysUse 和 CatPlaysUse 又分别通过该接口依赖 DogPlays 和 CatPlays ,但是都没有用完实现类里的所有方法,造成资源浪费

(2)代码说明

  • 如果类图不是很明白的,直接看代码感受一下!
  • 直接上代码:
    在这里插入图片描述
    在这里插入图片描述
  • 如果看代码还有点不明白,往下看测试,感受一下之间的调用

(3)测试

  • 来,我们来看看测试,感受一下
    在这里插入图片描述
    在这里插入图片描述
  • 当然这个测试稍微有点负责,主要让你体验一下我们开发中对这种情况可能应用的场景,那么平时我们测试的话可以稍微简单点,接下来看简单点的
    在这里插入图片描述
    这就省事多了!
  • OK,到这里应该明白彻底明白这个案例了吧!

(4)分析缺点(总结)

  • 可以看出,PetInterface 的实现有两个,分别是 DogPlays.java 和 CatPlays.java
  • DogPlaysUse 这个类通过接口 PetInterface 依赖 DogPlays 类,但是只用到 playBall 和 likeToGoOut 方法。
    而 DogPlays 类实现了 PetInterface 接口的所有方法,所以造成浪费
  • 同样的,CatPlaysUse 这个类通过接口 PetInterface 依赖 CatPlays 类,但是只用到 playBall、climbTree 和 catchMouse 方法,所以也造成浪费

2.正例

  • 那么对于上面的案例怎么来优化呢?
  • 既然一个接口有浪费,那么我们就把它拆解,这其实就是我们的接口隔离原则,请继续……

(1)类图说明

在这里插入图片描述

  • 如图可见,对于上述案例,如果用接口隔离原则优化的话,我们设计的时候拆成3个接口最为合理

(2)代码说明

在这里插入图片描述
在这里插入图片描述

  • 对比反例,这样就看着干净舒服多了

(3)测试

  • 测试就没啥好说的了,自己看吧
    在这里插入图片描述

(4)方案评价

  • 对比第一种写法,使用接口隔离的这种写法明显让旁人看着代码也是很清晰,接口拆开之后各行其职责,代码看着不臃肿,后续功能变更或新增的话维护起来也好维护

三、总结

  • 客户端不应该依赖它不需要的接口
  • 一个类对另外一个类的依赖,应建立在最小的接口上,
  • 其实就是一个接口里不要放一个功能模块外的其他方法,理解起来跟单一职责原则有点像,自己体会体会吧

四、附代码

1.反例代码

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("\n======小猫开始表演……=====\n" );
        //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");
    }

}

2.正例代码

package com.liu.susu.principle.segregation.example2;

/**
 * @Description 接口隔离原则——正例
 * @Author susu
 * @date 2022-02-12
 **/
public interface PetInterface {
    void playBall();//玩球
}
interface DogInterface {
    void likeToGoOut();//遛狗
}
interface CatInterface {
    void climbTree();//爬树
    void catchMouse();//抓老鼠
}

class DogPlays implements PetInterface,DogInterface{
    public void playBall() {
        System.out.println("狗狗喜欢玩球……");
    }
    public void likeToGoOut() {
        System.out.println("狗狗喜欢每天被遛遛……");
    }
}

class CatPlays implements PetInterface,CatInterface{
    public void playBall() {
        System.out.println("小猫喜欢玩球……");
    }
    public void climbTree() {
        System.out.println("小猫喜欢爬树……");
    }
    public void catchMouse() {
        System.out.println("小猫喜欢抓老鼠……");
    }
}

class DogPlaysUse {
    public void playBall(PetInterface petInterface){
        petInterface.playBall();
    }
    public void likeToGoOut(DogInterface dogInterface) {
        dogInterface.likeToGoOut();
    }
}

class CatPlaysUse {
    public void playBall(PetInterface petInterface){
        petInterface.playBall();
    }
    public void climbTree(CatInterface catInterface) {
        catInterface.climbTree();
    }
    public void catchMouse(CatInterface catInterface) {
        catInterface.catchMouse();
    }
}

/**
 * 测试类
 */
class Test{
    public static void main(String[] args) {
        DogPlaysUse dogPlaysUse = new DogPlaysUse();
        dogPlaysUse.playBall(new DogPlays());
        dogPlaysUse.likeToGoOut(new DogPlays());

        System.out.println("\n======小猫开始表演……=====\n" );

        CatPlaysUse catPlaysUse = new CatPlaysUse();
        catPlaysUse.playBall(new DogPlays());
        catPlaysUse.climbTree(new CatPlays());
        catPlaysUse.catchMouse(new CatPlays());

    }
}

五、其他

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@素素~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值