编码习惯之参数校验和国际化规范

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

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

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

service:cookie

修改后:ide

service:函数

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

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

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

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%以上),依我看来,大部分业务代码这么简单,你把代码写成我例子那样,还须要什么注释?注释是多此一举。

相关文章
相关标签/搜索