程序员你为什么这么累【续】:编码习惯之参数校验和国际化规范

今天我们说说参数校验和国际化,这些代码没有什么技术含量,却大量充斥在业务代码上,很可能业务代码只有几行,参数校验代码却有十几行,非常影响代码阅读,所以很有必要把这块的代码量减下去。

今天的目的主要是把之前例子里面的和业务无关的国际化参数隐藏掉,以及如何封装好校验函数。

今天累,少说话多贴代码,先看对比图,修改前:

service

修改后:

services

Controll的非业务代码如何去掉参考我的编码习惯 - Controller规范,下面说说去掉Local参数。

强调一下:业务代码里面不要出现和业务无关的东西,如local,MessageSource 。

去掉国际化参数还是使用的技术还是ThreadLocal。国际化信息可以放好几个地方,但建议不要放在每一个url上,除了比较low还容易出很多其他问题。这里演示的是放在cookie上面的例子:

UserUtil

public class UserUtil {

  private final static ThreadLocal<String> tlUser = new ThreadLocal<String>();

  private final static ThreadLocal<Locale> tlLocale = new ThreadLocal<Locale>() {
    protected Locale initialValue() {
      // 语言的默认值
      return Locale.CHINESE;
    };
  };

  public static final String KEY_LANG = "lang";

  public static final String KEY_USER = "user";

  public static void setUser(String userid) {
    tlUser.set(userid);

    // 把用户信息放到log4j
    MDC.put(KEY_USER, userid);
  }

  public static String getUser() {
    return tlUser.get();
  }

  public static void setLocale(String locale) {
    setLocale(new Locale(locale));
  }

  public static void setLocale(Locale locale) {
    tlLocale.set(locale);
  }

  public static Locale getLocale() {
    return tlLocale.get();
  }

  public static void clearAllUserInfo() {
    tlUser.remove();
    tlLocale.remove();

    MDC.remove(KEY_USER);
  }
}

CheckUtil,这里需要得到用户的语言

package plm.common.utils;

import org.springframework.context.MessageSource;

import plm.common.exceptions.CheckException;

public class CheckUtil {
  private static MessageSource resources;

  public static void setResources(MessageSource resources) {
    CheckUtil.resources = resources;
  }

  public static void check(boolean condition, String msgKey, Object... args) {
    if (!condition) {
      fail(msgKey, args);
    }
  }

  public static void notEmpty(String str, String msgKey, Object... args) {
    if (str == null || str.isEmpty()) {
      fail(msgKey, args);
    }
  }

  public static void notNull(Object obj, String msgKey, Object... args) {
    if (obj == null) {
      fail(msgKey, args);
    }
  }

  private static void fail(String msgKey, Object... args) {
    throw new CheckException(resources.getMessage(msgKey, args, UserUtil.getLocale()));
  }
}

这里有几个小技术点:

工具类里面使用spring的bean,使用了MethodInvokingFactoryBean的静态方法注入:

<!-- 国际化 -->
<bean id="messageSource"
  class="org.springframework.context.support.ResourceBundleMessageSource">
  <property name="basenames">
    <list>
      <value>format</value>
      <value>exceptions</value>
      <value>windows</value>
    </list>
  </property>
</bean>

<bean
  class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
  <property name="staticMethod" value="plm.common.utils.CheckUtil.setResources" />
  <!-- 这里配置参数 -->
  <property name="arguments" ref="messageSource">
  </property>
</bean>

server里面调用的使用没有出现类名

这里使用的jdk的import static 特性,可以在ide上配置,请自行google。

import static plm.common.utils.CheckUtil.*;

还有一小点注意,我建议参数非法的时候,把值打印出来,否则你又要浪费时间看是没有传呢还是传错了,时间就是这样一点点浪费的。

check(id > 0L, "id.error", id); // 当前非法的id也传入提示出去

另外有些项目用valid来校验,从我实际接触来看,用的不多,可能是有短木板吧。如果你的项目valid就能满足,那就更加好了,不需要看了。但是大部分场景,校验比例子复杂N多,提示也千变万化,所以我们还是自己调用函数校验。

做了这几步之后,代码会漂亮很多,记住,代码最主要的不是性能,而是可读性,有了可读性才有才维护性。而去掉无关的代码后的代码,和之前的代码对比一下,自己看吧。

还有人说代码要注释率到多少(我们公司有段时间工具扫描要求注释率到30%以上),依我看来,大部分业务代码这么简单,你把代码写成我例子那样,还需要什么注释?注释是画蛇添足。

本文分享自微信公众号 - 程序猿DD(didispace)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-09-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序猿DD

使用Spring StateMachine框架实现状态机

Spring StateMachine框架可能对于大部分使用Spring的开发者来说还比较生僻,该框架目前差不多也才刚满一岁多。它的主要功能是帮助开发者简化状态...

79090
来自专栏程序猿DD

新年彩蛋:Spring Boot自定义Banner

在2016年的最后一天,借用Spring Boot的Banner向各位程序猿同仁们问候一声:Happy New Year。 ? 接下来我们就来介绍一下这个轻松愉...

26070
来自专栏程序猿DD

Spring Boot Actuator监控端点小结

初识Actuator 在Spring Boot的众多Starter POMs中有一个特殊的模块,它不同于其他模块那样大多用于开发业务功能或是连接一些其他外部资源...

40680
来自专栏java达人

Springboot 注解如何工作

作者:Parmod 译者:java达人 来源:http://parmodarora.com/2016/01/06/springbootapplication-a...

314100
来自专栏程序猿DD

在传统Spring应用中使用spring-boot-actuator模块提供监控端点

在之前发布的《Spring Boot Actuator监控端点小结》一文中,我们介绍了Spring Boot Actuator模块为应用提供的强大监控能力。在S...

28850
来自专栏java达人

Spring Boot指南

欢迎投稿 erixhao作品 Spring Boot是由Pivotal公司(Spring目前隶属于Pivotal)于2014发布的一个框架,如上图官网所示...

35760
来自专栏java达人

SpringBoot编写自定义的starter

作者:Format 来源:http://fangjian0423.github.io/2016/11/16/springboot-custom-starter/...

41870
来自专栏程序猿DD

Spring Boot应用的后台运行配置

酱油一篇,整理一下关于Spring Boot后台运行的一些配置方式。在介绍后台运行配置之前,我们先回顾一下Spring Boot应用的几种运行方式: - 运行S...

58060
来自专栏程序猿DD

使用Intellij中的Spring Initializr来快速构建Spring Boot/Cloud工程

在之前的所有Spring Boot和Spring Cloud相关博文中,都会涉及Spring Boot工程的创建。而创建的方式多种多样,我们可以通过Maven来...

25380
来自专栏程序猿DD

Spring Boot 1.5.x新特性:动态修改日志级别

前天Spring Boot 1.5终于迎来了第一个RELEASE版本:1.5.0,但是由于一个编译依赖问题在第二天直接连击到了1.5.1。该版本的发布包含了超过...

29290

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励