程序里随处可见的interface,真的有用吗?真的用对了吗?(.interface)

  本篇文章为你整理了程序里随处可见的interface,真的有用吗?真的用对了吗?(.interface)的详细内容,包含有interface有什么用 .interface 界面 interface interface文件夹可以删除吗 程序里随处可见的interface,真的有用吗?真的用对了吗?,希望能帮助你了解 程序里随处可见的interface,真的有用吗?真的用对了吗?。

   四连问:什么情况下定义interface?为什么要定义interface?定义interface是为了什么?你用对interface了吗?

  
这两天在和一小伙伴研究解决RabbitMQ集群重启慢导致Consumer自动重连超时的问题,已经有了解决方案。接下来需要做个整理。由于同时涉及到springboot自动配置、springboot-amqp、spring-rabbit等诸多技术,先往后拖一下。

  本文说什么呢?通过一个程序案例来聊聊程序里随处可见的interface。

  先来个四连问:什么情况下定义interface?为什么要定义interface?定义interface是为了什么?你用对interface了吗?

  

  接下来看这个案例吧。
程序里使用了RabbitMQ,下面 MQSender 是个interface,定义了生产者往mq放消息的两种方式:

  

package com.yft.rabbitmq.service;

 

  import com.yft.rabbitmq.constant.BindingEnum;

   * 延迟发送服务类

   * @author liuhongjie hongjie.liu@serviceshare.com

   * @date 2022年06月12日

  public interface MQSender {

   * 发送消息

   * @param bindingEnum 声明binding的enum

   * @param msg 推送的消息

   * @param delaySeconds 延迟的时间,秒

   void sendDelayMsg(BindingEnum bindingEnum, Object msg, int delaySeconds);

   * 发送消息

   * @param bindingEnum 声明binding的enum

   * @param msg 推送的消息

   void sendMsg(BindingEnum bindingEnum, Object msg);

  }

 

  其中 BindingEnum 是个枚举,封装定义了exchange和queue及两者的binding关系

  

package com.yft.rabbitmq.constant;

 

  public enum BindingEnum {

   SYNC_REVIEW_RECORD("sync-review-record", "sync-review-record", "sync-review-record"),

   PAY_SETTLE("pay-settle","pay-settle","pay-settle"),

   PAY_SETTLE_QUERY_DELAY("pay-settle-query-delay", "pay-settle-query-delay", "pay-settle-query-delay"),

   String exchangeName;

   String queueName;

   String routingKey;

   private static final String EXCHANGE_NAME_PREFIX = "exchange.levy-platform.";

   private static final String QUEUE_NAME_PREFIX = "queue.levy-platform.";

   private static final String ROUTING_KEY_PREFIX = "bindingKey.levy-platform.";

   BindingEnum(String exchangeName, String queueName, String routingKey) {

   this.exchangeName = exchangeName;

   this.queueName = queueName;

   this.routingKey = routingKey;

   public String getExchangeName() {

   return EXCHANGE_NAME_PREFIX + exchangeName;

   public String getQueueName() {

   return QUEUE_NAME_PREFIX + queueName;

   public String getRoutingKey() {

   return ROUTING_KEY_PREFIX + routingKey;

  }

 

  View Code

  MQSender只有一个实现类 DefaultMQSender 。我们同样贴出来它的代码

  

package com.yft.rabbitmq.service;

 

  import com.yft.rabbitmq.constant.BindingEnum;

  import lombok.RequiredArgsConstructor;

  import org.springframework.amqp.core.AmqpTemplate;

   * 延迟发送的默认实现

   * @author liuhongjie hongjie.liu@serviceshare.com

   * @date 2022年06月12日

  @RequiredArgsConstructor

  public class DefaultMQSender implements MQSender {

   private final AmqpTemplate amqpTemplate;

   @Override

   public void sendDelayMsg(BindingEnum bindingEnum, Object msg, int delaySeconds) {

   amqpTemplate.convertAndSend(bindingEnum.getExchangeName(), bindingEnum.getRoutingKey(), msg, message - {

   message.getMessageProperties().setDelay(delaySeconds * 1000);

   return message;

   @Override

   public void sendMsg(BindingEnum bindingEnum, Object msg) {

   amqpTemplate.convertAndSend(bindingEnum.getExchangeName(), bindingEnum.getRoutingKey(), msg);

  }

 

  View Code

  使用的话,见下面的 MQSenderConfig,它定义了相关的bean

  

package com.cn.yft.config;

 

  import com.yft.rabbitmq.service.DefaultMQSender;

  import com.yft.rabbitmq.service.MQSender;

  import org.springframework.amqp.core.AmqpTemplate;

  import org.springframework.beans.factory.annotation.Autowired;

  import org.springframework.context.annotation.Bean;

  import org.springframework.context.annotation.Configuration;

   * @Author wjx

   * @Date 2022/7/6

  @Configuration

  public class MQSenderConfig {

   @Autowired

   private AmqpTemplate rabbitTemplate;

   @Bean

   public MQSender mqSender() {

   return new DefaultMQSender(rabbitTemplate);

  }

 

  View Code

  

  案例介绍完毕。

  

  那么,MQSender 这个interface的作用是什么?

  当事人回答:作用是我能很方便的看到这个接口的能力。
当事人回答:如果以后不用RabbitMQ,新的消息中间件直接实现这个interface就行了。

  如此几次对答后,几分钟后,小伙子开始觉得这个interface好像意义并不明显。

  以这个程序实现场景来看,去掉这个interface是可以的,反而还会增强程序易读性。

  那么,以这个场景来说,怎么定义一个合理的interface呢?
我画了下面的草图,图样图森破。可爱的小伙立即提出了新的疑惑,我当然明白他的疑惑。秉承我的风格,我并没有继续阐开,而是让这小伙后续琢磨琢磨。

  

  好,在这里,我揭晓我的想法。

  MQSender 摇身一变成:

  

package com.yft.rabbitmq.service;

 

  import com.yft.dto.MQMsgModel;

   * 延迟发送服务类

  public interface MQSender {

   * 发送消息

   * @param mqMsg mq消息对象

   void sendMsg(MQMsgModel mqMsg);

  }

 

  它的两个实现类:DefaultMQSender 是实时发送消息,DelayMQSender 是延迟发送消息

  
public void sendMsg(MQMsgModel mqMsgModel) {

   BindingEnum bindingEnum = mqMsgModel.getBindingEnum();

   amqpTemplate.convertAndSend(bindingEnum.getExchangeName(), bindingEnum.getRoutingKey(), mqMsgModel.getMsg());

  }

 

 

  

  
public void sendMsg(MQMsgModel mqMsgModel) {

   BindingEnum bindingEnum = mqMsgModel.getBindingEnum();

   amqpTemplate.convertAndSend(bindingEnum.getExchangeName(), bindingEnum.getRoutingKey(), mqMsgModel.getMsg(), message - {

   message.getMessageProperties().setDelay(mqMsgModel.getDelaySeconds() * 1000);

   return message;

  }

 

 

  

  
注意到多了一个 MQMsgModel, 好,我们来看这个 MQMsgModel,它是一个数据传输对象,定义了mq消息的属性

  

package com.yft.dto;

 

  import com.yft.rabbitmq.constant.BindingEnum;

  import lombok.Data;

   * mq消息对象

  @Data

  public class MQMsgModel{

   private BindingEnum bindingEnum;

   private Object msg;

   * 指定消息的延迟时间,单位:秒 →→→→(非延迟消息,不用指定)

   private Integer delaySeconds;

  }

 

  使用的话, MQSenderConfig 定义两个bean就OK了

  

package com.cn.yft.config;

 

  @Configuration

  public class MQSenderConfig {

   @Autowired

   private AmqpTemplate rabbitTemplate;

   @Bean

   public MQSender mqSender() {

   return new DefaultMQSender(rabbitTemplate);

   @Bean

   public MQSender delayMqSender() {

   return new DelayMQSender(rabbitTemplate);

  }

 

  

  (完毕)

  再贴一下上面的四连问:什么情况下定义interface?为什么要定义interface?定义interface是为了什么?你用对interface了吗?

  不知你是否有了一些答案?

  

  
当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!--buguge
本文来自,转载请注明原文链接:https:///buguge/p/16526595.html

  以上就是程序里随处可见的interface,真的有用吗?真的用对了吗?(.interface)的详细内容,想要了解更多 程序里随处可见的interface,真的有用吗?真的用对了吗?的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: