重构实例-消息发送-去除static关键字-3

面向对象编程中类变量与实例变量的核心区别与应用实践 在面向对象编程中,变量根据其作用域和生命周期可分为不同类型,其中类变量和实例变量是两种基础且关键的概念。类变量属于类本身,在类加载时初始化,所有实例共享同一份数据,常用于存储全局配置、共享资源或状态计数器。实例变量则属于每个对象实例,在对象创建时初始化,用于描述对象独有的状态和属性,如对象身份标识和核心状态。理解两者的内存模型差异至关重要:实例变量存储在堆内存中,生命周期与对象绑定;类变量存储在方法区或类对象区域,生命周期与类本身绑定。这一原理直接关系到程序的数据封装性、内存使用效率和线程安全性。在实际开发 阅读详情

3. 重构实例-消息发送-去除static关键字

由于这是一个长文,分成了好几章来介绍如何重构。

  1. 原始代码及准备
  2. 职责独立
  3. 去除static关键字
  4. 接口添加转换方法
  5. 方法合并
  6. 使用策略进行重构-Map方式
  7. 使用策略进行重构-枚举方式

现在来思考下NotifySendUtils中直接调用发送代码的做法,是否合理呢?或者说在我们原来的代码中,增加了一层调用,有必要吗?我觉得这个问题得分场景
来看,如果是一个大系统中的一部分,NotifySendUtils被几十甚至上百的文件引用,那么这样的改动是相当合理的,毕竟这样子我们改动相对较小。但如果
像本例中NotifySendUtils仅被很少的客户端使用,或者说只有一个客户端在用,那么这样的改动还合理吗?这显然是不合理的。这仅增加了类。但却是没有
任何的用处,这样的类就应该被拿掉。

既然发现了问题,那就直接改掉吧。

3.1 操作步骤

  1. 将单元测试从NotifySendUtils中方法移动到MessageSender中。
  2. 将NotifySendUtils中方法复制到MessageSender中。
  3. 让编译通过.
  4. 让单元测试通过。
  5. 删除空单元测试文件TestNotifySendUtils。
  6. 修改单元测试,为去除static关键字准备
  7. 去除方法的static关键字。
  8. 删除空的NotifySendUtils文件。

3.2 将单元测试从NotifySendUtils中方法移动到MessageSender中。

public class TestMockMessageSender {

  private MessageSender instance = new MessageSender();

  .......

  @Test
  @DisplayName("测试发送短信通知")
  public void testSmsSender() {
    MessageSender.sendSms("datatest", "13412345678", "测试短信息的内容信息");
    // 无异常即为成功
    assertTrue(true);
  }

  @Test
  @DisplayName("邮件发送邮件通知")
  public void testEmailSender() {
    MessageSender.sendMail("dataTest", "134@163.com", "测试邮件通知", "测试邮件的内容信息");
    // 无异常即为成功
    assertTrue(true);
  }

  @Test
  @DisplayName("微信发送通知")
  public void testWechatSender() {
    MessageSender.sendWxMsg("dataTest", "131234567", "微信消息内容");
    // 无异常即为成功
    assertTrue(true);
  }

  @Test
  @DisplayName("钉钉发送通知")
  public void testDingDingSender() {
    MessageSender.sendDingDingMsg("dataTest", "134123456", "钉钉发送通知");
    // 无异常即为成功
    assertTrue(true);
  }

  @Test
  @DisplayName("微信企业发送通知")
  public void testWorkWechatSender() {
    MessageSender.sendWorkWeChatMsg("dataTest", "1231231", "企业钉钉通知");
    // 无异常即为成功
    assertTrue(true);
  }

}

3.3 将NotifySendUtils中方法复制到MessageSender中。

public class MessageSender {

  public void sendMessage(String msgType, MessageData notify) {
    MessageTypeEnum typeEnum = MessageTypeEnum.getEnumType(msgType);
    switch (typeEnum) {
        // 短信发送
      case SMS:
        NotifySendUtils.sendSms(notify.getFunCode(), notify.getNotifyNumber(), notify.getContent());
        break;
        // email的发送
      case EMAIL:
        NotifySendUtils.sendMail(
            notify.getFunCode(), notify.getNotifyNumber(), notify.getTitle(), notify.getContent());
        break;
        // 微信的发送
      case WECHAT:
        NotifySendUtils.sendWxMsg(
            notify.getFunCode(), notify.getNotifyNumber(), notify.getContent());
        break;
        // 钉钉的消息发送
      case DINGDING:
        NotifySendUtils.sendDingDingMsg(
            notify.getFunCode(), notify.getNotifyNumber(), notify.getContent());
        break;
        // 企业钉钉的消息发送
      case WORKWECHAT:
        NotifySendUtils.sendWorkWeChatMsg(
            notify.getFunCode(), notify.getNotifyNumber(), notify.getContent());
        break;
        // 其他不做处理
      case OTHER:
        break;
      default:
        break;
    }
  }


  /**
   * 给一个邮箱,发送邮件
   *
   * @param funCode 功能类型编码
   * @param sendToMail 地址
   * @param subject 主题
   * @param content 内容
   * @return 返回发送结果
   */
  public static boolean sendMail(
          String funCode, String sendToMail, String subject, String content) {
    EmailMsgData msgData = new EmailMsgData(sendToMail, subject, content);
    MessageSenderInf emailSender = new SmsSender();
    emailSender.sender(msgData);
    return true;
  }

  /**
   * 给单个手机号,发送短信
   *
   * @param funCode 功能类型编码
   * @param sendToMobileNos 接收的号码
   * @param smsContent 短信内容
   */
  public static void sendSms(String funCode, String sendToMobileNos, String smsContent) {
    MsgData smsData = new MsgData(sendToMobileNos, smsContent);
    MessageSenderInf smsSender = new SmsSender();
    smsSender.sender(smsData);
  }

  /**
   * 给单个微信openID,发送模板消息(类似银行交易提醒通知)
   *
   * @param funCode 功能类型编码
   * @param toUserOpenId 发送的目标用户(微信openId)
   * @param context 内容
   */
  public static void sendWxMsg(String funCode, String toUserOpenId, String context) {
    FunCodeMsgData weChatData = new FunCodeMsgData(toUserOpenId, context, funCode);
    MessageSenderInf weChatSender = new WeChatSender();
    weChatSender.sender(weChatData);
  }

  /**
   * 发送钉钉消息
   *
   * @param funCode 功能类型编码
   * @param toUserOpenId 接收的id
   * @param context 发送的内容
   */
  public static void sendDingDingMsg(String funCode, String toUserOpenId, String context) {
    FunCodeMsgData dingDingData = new FunCodeMsgData(toUserOpenId, context, funCode);
    MessageSenderInf dingDingSender = new DingDingSender();
    dingDingSender.sender(dingDingData);
  }

  /**
   * 企业微信消息的发送
   *
   * @param funCode 功能类型编码
   * @param toUserOpenId 接收消息的id
   * @param context 发送的内容
   */
  public static void sendWorkWeChatMsg(String funCode, String toUserOpenId, String context) {
    FunCodeMsgData dingDingData = new FunCodeMsgData(toUserOpenId, context, funCode);
    MessageSenderInf workWeChatSender = new DingDingSender();
    workWeChatSender.sender(dingDingData);
  }

}

3.4 让编译通过。

public class MessageSender {

  public void sendMessage(String msgType, MessageData notify) {
    MessageTypeEnum typeEnum = MessageTypeEnum.getEnumType(msgType);
    switch (typeEnum) {
        // 短信发送
      case SMS:
        sendSms(notify.getFunCode(), notify.getNotifyNumber(), notify.getContent());
        break;
        // email的发送
      case EMAIL:
        sendMail(
            notify.getFunCode(), notify.getNotifyNumber(), notify.getTitle(), notify.getContent());
        break;
        // 微信的发送
      case WECHAT:
        sendWxMsg(notify.getFunCode(), notify.getNotifyNumber(), notify.getContent());
        break;
        // 钉钉的消息发送
      case DINGDING:
        sendDingDingMsg(notify.getFunCode(), notify.getNotifyNumber(), notify.getContent());
        break;
        // 企业钉钉的消息发送
      case WORKWECHAT:
        sendWorkWeChatMsg(notify.getFunCode(), notify.getNotifyNumber(), notify.getContent());
        break;
        // 其他不做处理
      case OTHER:
        break;
      default:
        break;
    }
  }

  /**
   * 给一个邮箱,发送邮件
   *
   * @param funCode 功能类型编码
   * @param sendToMail 地址
   * @param subject 主题
   * @param content 内容
   * @return 返回发送结果
   */
  public static boolean sendMail(
      String funCode, String sendToMail, String subject, String content) {
    EmailMsgData msgData = new EmailMsgData(sendToMail, subject, content);
    MessageSenderInf emailSender = new SmsSender();
    emailSender.sender(msgData);
    return true;
  }

  /**
   * 给单个手机号,发送短信
   *
   * @param funCode 功能类型编码
   * @param sendToMobileNos 接收的号码
   * @param smsContent 短信内容
   */
  public static void sendSms(String funCode, String sendToMobileNos, String smsContent) {
    MsgData smsData = new MsgData(sendToMobileNos, smsContent);
    MessageSenderInf smsSender = new SmsSender();
    smsSender.sender(smsData);
  }

  /**
   * 给单个微信openID,发送模板消息(类似银行交易提醒通知)
   *
   * @param funCode 功能类型编码
   * @param toUserOpenId 发送的目标用户(微信openId)
   * @param context 内容
   */
  public static void sendWxMsg(String funCode, String toUserOpenId, String context) {
    FunCodeMsgData weChatData = new FunCodeMsgData(toUserOpenId, context, funCode);
    MessageSenderInf weChatSender = new WeChatSender();
    weChatSender.sender(weChatData);
  }

  /**
   * 发送钉钉消息
   *
   * @param funCode 功能类型编码
   * @param toUserOpenId 接收的id
   * @param context 发送的内容
   */
  public static void sendDingDingMsg(String funCode, String toUserOpenId, String context) {
    FunCodeMsgData dingDingData = new FunCodeMsgData(toUserOpenId, context, funCode);
    MessageSenderInf dingDingSender = new DingDingSender();
    dingDingSender.sender(dingDingData);
  }

  /**
   * 企业微信消息的发送
   *
   * @param funCode 功能类型编码
   * @param toUserOpenId 接收消息的id
   * @param context 发送的内容
   */
  public static void sendWorkWeChatMsg(String funCode, String toUserOpenId, String context) {
    FunCodeMsgData dingDingData = new FunCodeMsgData(toUserOpenId, context, funCode);
    MessageSenderInf workWeChatSender = new DingDingSender();
    workWeChatSender.sender(dingDingData);
  }
}

3.5 修改单元测试,让单元测试可以通过

public class TestMockMessageSender {

  @Test
  @DisplayName("测试发送短信mock")
  public void testSmsSenderMock() {
    MessageSender instance = new MessageSender();
    new Expectations(instance) {
      {
        // 将方法给mock掉,无需与真实的操作进行交互
        instance.sendSms(anyString, anyString, anyString);
      }
    };
    MessageData data = new MessageData();
    data.setFunCode("dataTest");
    data.setNotifyNumber("13412345678");
    data.setTitle("测试短信息通知");
    data.setStatus(0);
    data.setContent("测试短信息的内容信息..");
    instance.sendMessage(MessageTypeEnum.SMS.getMsgType(), data);
    new Verifications() {
      {
        instance.sendSms(anyString, anyString, anyString);
        minTimes = 1;
      }
    };
  }

  @Test
  @DisplayName("邮件发送邮件通知Mock")
  public void testEmailSenderMock() {
    MessageSender instance = new MessageSender();
    new Expectations(instance) {
      {
        // 将方法给mock掉,无需与真实的操作进行交互
        MessageSender.sendMail(anyString, anyString, anyString, anyString);
      }
    };
    MessageData data = new MessageData();
    data.setFunCode("dataTest");
    data.setNotifyNumber("13412345678@163.com");
    data.setTitle("测试邮件息通知");
    data.setStatus(0);
    data.setContent("测试邮件的内容信息..");
    instance.sendMessage(MessageTypeEnum.EMAIL.getMsgType(), data);
    // 无异常即为成功
    assertTrue(true);
    new Verifications() {
      {
        // 验证邮件是否被成功调用
        MessageSender.sendMail(anyString, anyString, anyString, anyString);
        minTimes = 1;
      }
    };
  }

  @Test
  @DisplayName("微信发送通知mock")
  public void testWechatSenderMock() {
    MessageSender instance = new MessageSender();
    new Expectations(instance) {
      {
        // 将方法给mock掉,无需与真实的操作进行交互
        MessageSender.sendWxMsg(anyString, anyString, anyString);
      }
    };
    MessageData data = new MessageData();
    data.setFunCode("dataTest");
    data.setNotifyNumber("1234567");
    data.setTitle("测试微信息通知");
    data.setStatus(0);
    data.setContent("测试微信的内容信息..");
    instance.sendMessage(MessageTypeEnum.WECHAT.getMsgType(), data);
    // 无异常即为成功
    assertTrue(true);

    new Verifications() {
      {
        // 验证邮件是否被成功调用
        MessageSender.sendWxMsg(anyString, anyString, anyString);
        minTimes = 1;
      }
    };
  }

  @Test
  @DisplayName("钉钉发送通知mock")
  public void testDingDingSenderMock() {
    MessageSender instance = new MessageSender();
    new Expectations(instance) {
      {
        // 将方法给mock掉,无需与真实的操作进行交互
        MessageSender.sendDingDingMsg(anyString, anyString, anyString);
      }
    };
    MessageData data = new MessageData();
    data.setFunCode("dataTest");
    data.setNotifyNumber("1234567");
    data.setTitle("测试钉钉通知");
    data.setStatus(0);
    data.setContent("测试钉钉的内容信息..");
    instance.sendMessage(MessageTypeEnum.DINGDING.getMsgType(), data);
    // 无异常即为成功
    assertTrue(true);
    new Verifications() {
      {
        // 验证邮件是否被成功调用
        MessageSender.sendDingDingMsg(anyString, anyString, anyString);
        minTimes = 1;
      }
    };
  }

  @Test
  @DisplayName("微信企业发送通知mock")
  public void testWorkWechatSenderMock() {
    MessageSender instance = new MessageSender();
    new Expectations(instance) {
      {
        // 将方法给mock掉,无需与真实的操作进行交互
        MessageSender.sendWorkWeChatMsg(anyString, anyString, anyString);
      }
    };
    MessageData data = new MessageData();
    data.setFunCode("dataTest");
    data.setNotifyNumber("1234567");
    data.setTitle("测试企业微信通知");
    data.setStatus(0);
    data.setContent("测试企业微信的内容信息..");
    instance.sendMessage(MessageTypeEnum.WORKWECHAT.getMsgType(), data);
    // 无异常即为成功
    assertTrue(true);
    new Verifications() {
      {
        // 验证邮件是否被成功调用
        MessageSender.sendWorkWeChatMsg(anyString, anyString, anyString);
        minTimes = 1;
      }
    };
  }

  @Test
  @DisplayName("测试发送短信通知")
  public void testSmsSender() {
    MessageSender.sendSms("datatest", "13412345678", "测试短信息的内容信息");
    // 无异常即为成功
    assertTrue(true);
  }

  @Test
  @DisplayName("邮件发送邮件通知")
  public void testEmailSender() {
    MessageSender.sendMail("dataTest", "134@163.com", "测试邮件通知", "测试邮件的内容信息");
    // 无异常即为成功
    assertTrue(true);
  }

  @Test
  @DisplayName("微信发送通知")
  public void testWechatSender() {
    MessageSender.sendWxMsg("dataTest", "131234567", "微信消息内容");
    // 无异常即为成功
    assertTrue(true);
  }

  @Test
  @DisplayName("钉钉发送通知")
  public void testDingDingSender() {
    MessageSender.sendDingDingMsg("dataTest", "134123456", "钉钉发送通知");
    // 无异常即为成功
    assertTrue(true);
  }

  @Test
  @DisplayName("微信企业发送通知")
  public void testWorkWechatSender() {
    MessageSender.sendWorkWeChatMsg("dataTest", "1231231", "企业钉钉通知");
    // 无异常即为成功
    assertTrue(true);
  }
}

3.6 删除空单元测试文件TestNotifySendUtils。

TestNotifySendUtils单元测试类中的文件已经被移动到其他单元测试文件中,已经是一个空文件,直接删除即可。

3.7 修改单元测试,为去除static关键字准备

public class TestMockMessageSender {
......

  @Test
  @DisplayName("测试发送短信通知")
  public void testSmsSender() {
    MessageSender instance = new MessageSender();
    instance.sendSms("datatest", "13412345678", "测试短信息的内容信息");
    // 无异常即为成功
    assertTrue(true);
  }

  @Test
  @DisplayName("邮件发送邮件通知")
  public void testEmailSender() {
    MessageSender instance = new MessageSender();
    instance.sendMail("dataTest", "134@163.com", "测试邮件通知", "测试邮件的内容信息");
    // 无异常即为成功
    assertTrue(true);
  }

  @Test
  @DisplayName("微信发送通知")
  public void testWechatSender() {
    MessageSender instance = new MessageSender();
    instance.sendWxMsg("dataTest", "131234567", "微信消息内容");
    // 无异常即为成功
    assertTrue(true);
  }

  @Test
  @DisplayName("钉钉发送通知")
  public void testDingDingSender() {
    MessageSender instance = new MessageSender();
    instance.sendDingDingMsg("dataTest", "134123456", "钉钉发送通知");
    // 无异常即为成功
    assertTrue(true);
  }

  @Test
  @DisplayName("微信企业发送通知")
  public void testWorkWechatSender() {
    MessageSender instance = new MessageSender();
    instance.sendWorkWeChatMsg("dataTest", "1231231", "企业钉钉通知");
    // 无异常即为成功
    assertTrue(true);
  }
}

3.8 去除方法的static关键字。

public class MessageSender {

  public void sendMessage(String msgType, MessageData notify) {
    MessageTypeEnum typeEnum = MessageTypeEnum.getEnumType(msgType);
    switch (typeEnum) {
        // 短信发送
      case SMS:
        sendSms(notify.getFunCode(), notify.getNotifyNumber(), notify.getContent());
        break;
        // email的发送
      case EMAIL:
        sendMail(
            notify.getFunCode(), notify.getNotifyNumber(), notify.getTitle(), notify.getContent());
        break;
        // 微信的发送
      case WECHAT:
        sendWxMsg(notify.getFunCode(), notify.getNotifyNumber(), notify.getContent());
        break;
        // 钉钉的消息发送
      case DINGDING:
        sendDingDingMsg(notify.getFunCode(), notify.getNotifyNumber(), notify.getContent());
        break;
        // 企业钉钉的消息发送
      case WORKWECHAT:
        sendWorkWeChatMsg(notify.getFunCode(), notify.getNotifyNumber(), notify.getContent());
        break;
        // 其他不做处理
      case OTHER:
        break;
      default:
        break;
    }
  }

  /**
   * 给一个邮箱,发送邮件
   *
   * @param funCode 功能类型编码
   * @param sendToMail 地址
   * @param subject 主题
   * @param content 内容
   * @return 返回发送结果
   */
  public boolean sendMail(String funCode, String sendToMail, String subject, String content) {
    EmailMsgData msgData = new EmailMsgData(sendToMail, subject, content);
    MessageSenderInf emailSender = new SmsSender();
    emailSender.sender(msgData);
    return true;
  }

  /**
   * 给单个手机号,发送短信
   *
   * @param funCode 功能类型编码
   * @param sendToMobileNos 接收的号码
   * @param smsContent 短信内容
   */
  public void sendSms(String funCode, String sendToMobileNos, String smsContent) {
    MsgData smsData = new MsgData(sendToMobileNos, smsContent);
    MessageSenderInf smsSender = new SmsSender();
    smsSender.sender(smsData);
  }

  /**
   * 给单个微信openID,发送模板消息(类似银行交易提醒通知)
   *
   * @param funCode 功能类型编码
   * @param toUserOpenId 发送的目标用户(微信openId)
   * @param context 内容
   */
  public void sendWxMsg(String funCode, String toUserOpenId, String context) {
    FunCodeMsgData weChatData = new FunCodeMsgData(toUserOpenId, context, funCode);
    MessageSenderInf weChatSender = new WeChatSender();
    weChatSender.sender(weChatData);
  }

  /**
   * 发送钉钉消息
   *
   * @param funCode 功能类型编码
   * @param toUserOpenId 接收的id
   * @param context 发送的内容
   */
  public void sendDingDingMsg(String funCode, String toUserOpenId, String context) {
    FunCodeMsgData dingDingData = new FunCodeMsgData(toUserOpenId, context, funCode);
    MessageSenderInf dingDingSender = new DingDingSender();
    dingDingSender.sender(dingDingData);
  }

  /**
   * 企业微信消息的发送
   *
   * @param funCode 功能类型编码
   * @param toUserOpenId 接收消息的id
   * @param context 发送的内容
   */
  public void sendWorkWeChatMsg(String funCode, String toUserOpenId, String context) {
    FunCodeMsgData dingDingData = new FunCodeMsgData(toUserOpenId, context, funCode);
    MessageSenderInf workWeChatSender = new DingDingSender();
    workWeChatSender.sender(dingDingData);
  }
}

3.9 将NotifySendUtils删除

由于NotifySendUtils文件已经为空文件无任何用处,将其删除。

3.10 运行单元测试

运行单元测试检查是否存在错误的修改。

C#方法设计最佳实践:粒度、异常、访问性与重构指南 方法是软件工程中最基础的可执行单元,其设计质量直接决定代码可维护性、线程安全性与团队协作效率。从认知科学视角看,30行限制本质是对人类短期记忆负荷的工程约束;异常处理需依循上下文契约——静态构造函数必须沉默以保障类型可用性,析构函数严禁抛出异常,属性Getter应杜绝副作用。C#中方法签名设计需兼顾PascalCase命名规范与动词+名词语义表达,访问修饰符实为模块演进的契约防火墙。结合virtual/override语义、Dispose模式协同及静态/实例方法选型原则,本文系统梳理高危陷阱(如构造函数调用 阅读详情

相关推荐

《Sigrity SystemSI 2023+LPDDR4仿真自学笔记》(一)创建工程(Part1)

为了加强SystemSI 2023软件的熟悉度,咱们完整的走一个仿真全流程。

weixin_45199544的博客 6324

C#学习-static使用错误改正

参考:https://blog.youkuaiyun.com/Carey_Lu/article/details/84585012?biz_id=102&utm_term=static%E4%B8%8D%E8%83%BD%E5%9C%A8main%E4%B8%AD%E5%A3%B0%E6%98%8E&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-84585012&spm=1018.2

晴天下的大头娃娃 1141

Stata实战:5步搞定PSM倾向得分匹配(附完整代码与常见报错解决)

本文详细介绍了使用Stata进行PSM(倾向得分匹配)的5步实战流程,包括数据预处理、模型构建、匹配算法选择、匹配质量诊断和结果解释。提供完整代码示例和常见报错解决方案,帮助研究者高效完成实证分析,提升匹配成功率。

weixin_29214559的博客 590

声明static变量报错(常见错误)

【一】错误代码 package demo; public class demo6 { public static void main(String[] args) { static int i=0; } } 【二】错误解析 Java中 规定static只能修饰类成员变量,不能修饰方法内的局部变量。 【三】错误修改 方式一:去掉static。 ...

The_Best_Hacker的博客 3301

SAP SD核心流程解析:从销售订单到财务结算的实战指南

本文深入解析SAP SD模块从销售订单到财务结算的核心流程,重点剖析了销售订单中的行项目类别如何作为流程的“总开关”,决定了后续交货、开票及财务集成的走向。文章结合实战案例,详细拆解了正常销售、退货、第三方销售、寄售等典型流程的配置要点与国内化适配方案,并阐述了SD与财务模块集成的关键连接点,为顾问和用户提供了一份全面的实战指南。

weixin_29250403的博客 426

目标检测YOLO实战应用案例100讲-基于数据融合的SAR图像中海上目标检测与跟踪(中)

本文使用的数据集为欧空局(European Space Agency, ESA)提供的Sentinal-1 数据集,Sentinel-1是欧洲“哥白尼计划”的SAR卫星机群,主要是用于陆地和海 洋服务的极地轨道全天候昼夜雷达成像任务[ 34]。Sentinel-1A于2014年4月3日发 射升空,Sentinel-1B于2016年4月25日发射升空,每颗卫星都携带C波段SAR, 共同提供地球表面的全天候、昼夜图像。

qq_36130719的博客 355

java关键字之static

static 我们知道在java中并没有全局变量这个概念,但是如果想要使用类似于全局变量时,我们可以使用static来实现一个模拟的全局变量的效果。static表示“全局”或者“静态”的意思,可以用来修饰成员变量和成员方法。 首先来了解一下java的内存分布: java的内存分为堆内存和栈内存,栈内存主要用来存放一些基本数据类型的变量、数组和对象引用;堆内存主要用于存放一些对象。在JVM加载一...

hnu_zhangzhijian的博客 365

VLA仿真平台:Isaac sim、MuJoCo

在虚拟仿真领域,VLA(Virtual Learning Agent)仿真器是用于开发和训练虚拟机器人代理的环境,它们为机器人提供了一个平台来进行各种任务的模拟和学习,特别是在强化学习(RL)中。两款广泛应用的仿真器是和。这两者各有其特点和优势,适用于不同类型的机器人研究和开发。

u013250861的博客 860

常用公用方法 -> 使用时把static去掉

public class LhjCommon { public static void main(String[] args) { String name = "62281642564124845"; String name1 = bankCardNoTM(name); System.out.println(name1); } /** * 功能描述: 客户名称脱敏 * 作 者: liuhoujun

weixin_42193405的博客 839

药物对接仿真软件:HADDOCK_(16).实践项目:抗体-抗原对接案例

定义分子结构文件。

kkchenjj的博客 578

3.嵌入式控制器EC学习,源码框架(60/64端口)(一)

服务函数剖析 上一篇讲到while循环会一直查询十六个标志位是否满足要求,一旦其中某个标志位为1时,程序将会执行相应的服务函数,而执行服务函数是通过函数指针(service_table[ _R1 ])();来实现的。接下来我们分别来看看这十六个服务函数分别包含了哪些内容。 16个函数的函数名如下: const FUNCT_PTR_V_V code service_table[16] = { // Hi-Level Service Service_PCI, // Host 6

qq_30135687的博客 4160

c语言中static作用

有关c语言中static声明的作用 最近学习和工作的时候碰到了很多static,在网上搜索学习看了很多文章,结合我的实际应用,记录一下以加深记忆,也希望可以给大家帮助,若有错误,请及时指正 static的三大作用:①修饰局部变量②修饰全局变量③修饰函数 修饰局部变量 static修饰局部变量,变量被static修饰之后,会被自动赋初值0,且变为了静态局部变量,程序运行过程中对变量进行操作改变了变量的值会保留下来,在下一次运行到此函数时变量值为上次操作结束的值。(很有用) 修饰全局变量 static修

qq_44690153的博客 522

使用MATLAB结合EasySpin进行ESR模拟的详细步骤及示例代码

安装EasySpin:确保你已经安装了EasySpin工具箱,它可以帮助你进行ESR模拟。你可以从EasySpin的官方网站(https://easyspin.org/)下载并安装。准备实验数据:将实验得到的EPR数据整理成合适的格式,一般包含磁场(Magnetic Field)和信号强度(Intensity)两列。进行模拟:使用EasySpin的函数对单线态氧自由基和超氧自由基进行模拟。调整参数:通过调整模拟参数,使模拟得到的峰型和峰位置与实验数据尽可能匹配。导出数据。

AI的内部世界的博客 2004

重构实例-消息发送-职责独立-2

2. 重构-策略模式-职责独立 由于这是一个长文,分成了好几章来介绍如何重构。 原始代码及准备 职责独立 去除static关键字 接口添加转换方法 方法合并 使用策略进行重构-Map方式 使用策略进行重构-枚举方式 现在来分析下代码的问题 先从入口MessageSender开始吧,这个类第一眼看上去,觉得很简单吧,就是按类型判断下,执行NotifySendUtils类中 的发送逻辑代码。这样子看这个类没有什么大的问题么,再说NotifySendUtils吧,它封装了各种发送渠道的调用方法,还做成了静态方

bug_null的博客 312

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

java关键字简介

【代码】java关键字简介。

a186878484的博客 918

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

黑马程序员——面向对象——static关键字——代码块

 ------http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

fuxiaoyuqing的专栏 596

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

黑马程序员__面向对象__Static静态__代码块

------http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- ——万物皆对象 1.面向对象针对面向过程而言,强调对象,我们充当指挥者,Java语言、C++语言是面向对象的。而面向过程强调过程,执行者,C语言是面向过程的,

haojude的专栏 608

AI自主代理重构遗留代码的实战风险与防御策略

代码重构是提升软件可维护性的基础工程实践,其核心在于保障行为一致性前提下的结构优化。随着大语言模型驱动的自主代理(Autonomous Agent)兴起,自动化重构能力显著增强,但其决策高度依赖静态分析与提示词约束,缺乏对遗留系统中隐性契约(如时间维度逻辑、数据兼容约定、运维脚本依赖)的理解能力。这导致在真实生产环境中易引发同步/异步误改、DTO破坏下游解析、日志格式变更致监控失效等典型生产风险。本文基于Java单体服务重构实战,系统揭示Agent‘优化’与业务稳定间的根本张力,并提出以防御性提示词、人机协

weixin_30527423的博客 424

IPython 发布流程完全指南:从发布说明、Git 标签到 PyPI 上传的 10 步操作手册

> 本文以仓库内 [docs/source/contributing/ipython-dev-guide/releasing.rst](https://link.gitcode.com/i/d1d6cf07eb3655d43ed4929c8d415276) 这份 IPython 开发者指南为骨架,系统讲解 IPython 从"整理发布说明"到"打 Tag、构建制品、上传 PyPI、更新官网、管理里

gitblog_00815的博客 373

Java重构实战:从祖传代码到清晰架构的渐进式改造指南

重构是软件工程中持续改善代码质量的核心实践,其本质是在不改变外部行为的前提下优化内部结构,以提升可维护性、可测试性和可扩展性。其原理遵循小步快跑、测试先行等原则,通过一系列可控的原子操作逐步偿还技术债务。这一过程的技术价值在于降低系统复杂度、减少缺陷引入风险,并为团队协作与新功能开发奠定坚实基础。应用场景广泛覆盖遗留系统维护、性能优化和架构演进等领域。本文以Java语言为例,聚焦于处理高耦合、巨型方法等典型“轮椅”场景,通过依赖注入、方法提取等具体重构手法,演示如何将混乱的“祖传代码”模块转化为职责清晰、易

weixin_34239169的博客 662

ROS消息序列化与适配类型原理深度解析

ROS消息序列化是实现跨进程、跨语言数据交换的基础机制,其本质是将C++对象安全转换为平台无关的扁平字节流,核心涉及内存布局控制、网络字节序转换与POD类型约束。该机制通过预计算MD5签名保障类型一致性,利用字段顺序线性序列化规避递归开销,并依赖适配类型(message_traits/Printer)在无运行时反射的C++中模拟动态元数据能力。技术价值在于支撑零拷贝传输、rosbag高效录制及rqt等工具的通用消息解析;典型应用场景包括自定义消息开发、带宽敏感的嵌入式通信及多语言节点互操作。本文深入剖析序列

weixin_30384217的博客 674

嵌入式秋招实战:从技术栈重构到项目深度解析

在嵌入式系统开发领域,掌握核心编程语言如C/C++是基础,理解其在资源受限环境下的应用范式至关重要。其原理涉及内存管理、硬件直接操作及实时性保证。这项技术的价值在于能构建高效、可靠的底层软件,直接影响设备的性能和稳定性。应用场景广泛覆盖从微控制器(MCU)裸机程序到实时操作系统(RTOS)下的任务开发。深入理解实时操作系统(如FreeRTOS)的调度机制、任务同步与通信原理,是提升系统设计能力的关键。本文将自然引导至如何将这些基础知识与项目经验深度融合,以应对**嵌入式秋招**中对**系统能力**和**设计

weixin_30709061的博客 375

从八股到能力题:如何设计一场真正区分候选人的技术面试

技术面试中,基础概念与工程能力的边界常被忽视。很多候选人能熟练背诵TCP三次握手、C语言static关键字等高频考点,却在面对丢包处理、链接错误等真实场景时无从下手。这是因为知识停留在点状记忆,未形成因果网络。优秀的面试题设计,应通过场景化改造、追问链和评分锚点,将封闭式背诵题转化为开放式能力题,从而考察候选人的原理理解、边界判断和工程权衡能力。无论是面试官还是求职者,掌握这套方法都能更高效地识别和构建真正的技术能力。本文以真实复盘为例,展示如何把八股题改造成能力题,并避开常见设计陷阱。

weixin_33787529的博客 415

C++类模板机制深度解析:从泛型编程到编译期实例化

类模板是C++泛型编程的核心实现机制,本质是在编译期根据类型参数生成独立特化类,而非运行时参数化类型。其原理基于模板声明、定义、实例化与显式实例化的四阶段编译流水线,依赖SFINAE、偏特化、CRTP和C++20 Concepts等关键技术支撑类型约束与行为定制。技术价值在于零开销抽象、静态多态与极致性能优化,广泛应用于STL容器、日志系统、网络协议栈及嵌入式实时组件等对ABI稳定性、内存布局和编译期决策有严苛要求的场景。本文聚焦类模板的工程级行为边界与生命周期机制。

WGH100817的博客 404

遗留代码治理实战:从识别到渐进式重构的工程实践

在软件工程领域,技术债务与遗留代码是影响系统长期可维护性与稳定性的核心挑战。其本质源于代码结构混乱、逻辑耦合以及缺乏有效测试覆盖,导致变更风险高、开发效率低下。通过运用静态分析、依赖梳理等工程手段,可以量化评估代码复杂度,并建立由单元测试、集成测试构成的安全网,为后续改造奠定基础。从技术价值看,系统性地治理遗留代码能显著降低缺陷率、提升团队交付效率,并增强系统应对业务变化的能力。典型的应用场景包括核心业务模块改造、第三方服务集成优化以及历史系统的现代化迁移。本文聚焦于通过设计模式、防腐层与适配器等技术,对承

weixin_34331102的博客 336

Java面向对象编程核心:从封装继承多态到内存管理实践

面向对象编程是一种通过封装、继承和多态三大支柱来组织代码的编程范式,其核心思想是将数据与操作数据的方法捆绑为对象,从而更好地模拟现实世界并管理复杂性。从技术原理看,它通过类定义对象蓝图,利用封装隐藏实现细节保障数据安全,通过继承实现代码复用与扩展,借助多态实现运行时动态绑定提升灵活性。在工程实践中,面向对象设计能显著提升代码的可维护性、可扩展性和复用性,是构建大型复杂系统的基石。本文以Java语言为例,深入解析类与对象的内存模型、构造方法重载、this关键字等关键概念,并结合高内聚低耦合的设计原则,探讨抽象

weixin_30619101的博客 400
上一篇: 重构实例-消息发送-职责独立-2
下一篇: 重构实例-消息发送-添加转换方法-4
null_null_bug
博客等级 码龄7年 72粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值