首页 > 其他分享 >接口隔离原则

接口隔离原则

时间:2024-08-16 11:41:22浏览次数:12  
标签:原则 PetInterface void 接口隔离 println playBall public DogPlays

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

一、举例说明

1.反例

(1)类图说明

  • 因为类图比较清晰,我们先看类图

在这里插入图片描述

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

(2)代码说明

  • 如果类图不是很明白的,直接看代码感受一下!
  • 直接上代码:
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());

    }
}

测试类

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");
    }

}

(4)分析缺点(总结)
可以看出,PetInterface 的实现有两个,分别是 DogPlays.java 和 CatPlays.java
DogPlaysUse 这个类通过接口 PetInterface 依赖 DogPlays 类,但是只用到 playBall 和 likeToGoOut 方法。
而 DogPlays 类实现了 PetInterface 接口的所有方法,所以造成浪费
同样的,CatPlaysUse 这个类通过接口 PetInterface 依赖 CatPlays 类,但是只用到 playBall、climbTree 和 catchMouse 方法,所以也造成浪费
2.正例
那么对于上面的案例怎么来优化呢?
既然一个接口有浪费,那么我们就把它拆解,这其实就是我们的接口隔离原则,请继续……
(1)类图说明

在这里插入图片描述

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

(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());

    }
}

(4)方案评价
对比第一种写法,使用接口隔离的这种写法明显让旁人看着代码也是很清晰,接口拆开之后各行其职责,代码看着不臃肿,后续功能变更或新增的话维护起来也好维护
三、总结
客户端不应该依赖它不需要的接口
一个类对另外一个类的依赖,应建立在最小的接口上,其实就是一个接口里不要放一个功能模块外的其他方法,理解起来跟单一职责原则有点像,自己体会体会吧

标签:原则,PetInterface,void,接口隔离,println,playBall,public,DogPlays
From: https://www.cnblogs.com/ZWJ7671277/p/18362546

相关文章

  • 高级java每日一道面试题-2024年8月15日-设计模式篇-设计模式与面向对象原则的关系是什
    如果有遗漏,评论区告诉我进行补充面试官:设计模式与面向对象原则的关系是什么?我回答:在设计模式与面向对象原则的关系中,两者紧密相连且相互促进。面向对象的原则为设计模式的形成提供了理论基础和指导思想,而设计模式则是这些原则在特定问题域中的具体实践和实现方式。下......
  • 面向对象设计原则
    面向对象设计原则总结单一职责原则(SRP)不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。问题由来:类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。一句话总结:不能为图代码量少......
  • 设计模式的7大基本原则
    设计模式是解决问题的经验总结,是软件开发中常用的一种设计思想和方法。在软件开发过程中,遵循设计模式可以提高代码的可重用性、可维护性和可扩展性。设计模式的基本原则是软件开发过程中的指导方针,它们是在解决问题时需要遵循的基本原则。本文将介绍设计模式的7大基本原则,......
  • 设计原则与思想:规范与重构 理论一 - 三 什么情况下要重构?到底重构什么?又该如何重构?有
    理论一:什么情况下要重构?到底重构什么?又该如何重构?重构的目的:为什么要重构(why)?对于项目来言,重构可以保持代码质量持续处于一个可控状态,不至于腐化到无可救药的地步。对于个人而言,重构非常锻炼一个人的代码能力,并且是一件非常有成就感的事情。它是我们学习的经典设计思想......
  • 什么是依赖倒置原则
    依赖倒置原则(DependencyInversionPrinciple,DIP)是面向对象设计原则之一,它是SOLID原则中的"D"。依赖倒置原则的核心思想是高层策略性业务规则不应该依赖于低层的具体实现细节,而两者都应该依赖于抽象。依赖倒置原则主要包含两个基本点:抽象不应该依赖于细节:系统中的抽象层(高层......
  • 爵士编曲:和弦排列 躯壳排列 四度排列 无根音排列 Drop 就近原则 So what排列
    和弦排列法是和弦在四部和声中的纵向排列方式称为“和弦排列法”。根据和弦排列时上方三声部各相邻声部之间的音程距离,原位三和弦可以有“密集排列”和“开放排列”以及“混合排列”三种排列法。①密集排列法:密集排列法(Closeposition)为上方三声部中相邻声部之间的距离在四度......
  • 2.2 C 语言常量的定义与变量命名的规范及原则
    目录1常量1.1常量的分类1.2符号常量(#define)1.2.1定义不同类型的符号常量1.2.2 注意事项1.3使用const 定义常量1.3.1定义不同类型的常量1.3.2常量的命名规范2变量2.1变量名的作用2.2变量的命名规范2.3变量的命名原则2.4大小驼峰命名法1常量 ......
  • 合成复用原则(CRP)
    目录一、概念1.合成2.复用二、合成复用原则的优点1.降低耦合度2.提高灵活性3.避免继承的复杂性三、示例合成复用原则(CompositeReusePrinciple,CRP)是面向对象设计中的一个重要指导原则,强调通过组合(而不是继承)来实现代码复用。它鼓励开发者利用对象的组合......
  • SQL-----索引设计原则
    索引设计原则1、针对于数据量较大,于且查询比较频繁的表建立索引2、针对常作为查询条件(where)、排序(orderby)、分组(groupby)操作的字段建立索引3、尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高4、如果是字符串类型的字段,字符的长度......
  • 里氏替换原则(LSP)
    目录一、理论二、要点1.替换性2.行为一致性3.不缩减功能4.接口和抽象类5.避免异常6.代码重用性三、举例说明里氏替换原则(LiskovSubstitutionPrinciple,LSP)是面向对象设计中的一种基本原则,是SOLID原则中的第二个。这个原则的核心思想是:如果对于某个类型的对......