韩国设计欣赏网站,wordpress tag 拼音,wordpress登记打印,临清网站制作设计模式第九讲#xff1a;常见重构技巧 - 去除不必要的! 项目中会存在大量判空代码#xff0c;多么丑陋繁冗#xff01;如何避免这种情况#xff1f;我们是否滥用了判空呢#xff1f;本文是设计模式第九讲#xff0c;讲解常见重构技巧#xff1a;去除不必要的! 文章目录…设计模式第九讲常见重构技巧 - 去除不必要的! 项目中会存在大量判空代码多么丑陋繁冗如何避免这种情况我们是否滥用了判空呢本文是设计模式第九讲讲解常见重构技巧去除不必要的! 文章目录 设计模式第九讲常见重构技巧 - 去除不必要的!1、场景一null无意义之常规判断空2、场景二null无意义之使用断言Assert3、场景三写util类是否都需要逐级判断空4、场景四让null变的有意义5、场景五Java8中使用Optional推荐 1、场景一null无意义之常规判断空
通常是这样的
private void xxxMethod(String key){if(key ! null !.equals(key)){// do something}
}初步的使用Apache CommonsGuvavaHutool等 StringUtils
private void xxxMethod(String key){if(StringUtils.isNotEmpty(key)){// do something}
}2、场景二null无意义之使用断言Assert
考虑用Assert断言
private void xxxMethod(String key){Assert.notNull(key);// do something
}3、场景三写util类是否都需要逐级判断空 逐级判断空还是抛出自定义异常还是不处理It Depends… hutool IdcardUtil 显然是交给调用者判断的。
/*** 是否有效身份证号** param idCard 身份证号支持18位、15位和港澳台的10位* return 是否有效*/
public static boolean isValidCard(String idCard) {idCard idCard.trim();// 这里idCard没判断空int length idCard.length();switch (length) {case 18:// 18位身份证return isValidCard18(idCard);case 15:// 15位身份证return isValidCard15(idCard);case 10: {// 10位身份证港澳台地区String[] cardVal isValidCard10(idCard);return null ! cardVal true.equals(cardVal[2]);}default:return false;}
}再比如 Apache Common IO中, 并没判断空
/*** Copy bytes from a codebyte[]/code to an codeOutputStream/code.* param input the byte array to read from* param output the codeOutputStream/code to write to* throws IOException In case of an I/O problem*/
public static void copy(final byte[] input, final OutputStream output)throws IOException {output.write(input);
}4、场景四让null变的有意义 返回一个空对象而非null对象比如NO_ACTION是特殊的Action那么我们就定义一个ACTION。下面举个例子假设有如下代码 public interface Action {void doSomething();
}public interface Parser {Action findAction(String userInput);
}其中Parse有一个接口FindAction这个接口会依据用户的输入找到并执行对应的动作。假如用户输入不对可能就找不到对应的动作Action因此findAction就会返回null接下来action调用doSomething方法时就会出现空指针。
解决这个问题的一个方式就是使用 Null Object pattern空对象模式 NullObject模式首次发表在“ 程序设计模式语言 ”系列丛书中。一般的在面向对象语言中对对象的调用前需要使用判空检查来判断这些对象是否为空因为在空引用上无法调用所需方法。 我们来改造一下
类定义如下这样定义findAction方法后确保无论用户输入什么都不会返回null对象
public class MyParser implements Parser {private static Action NO_ACTION new Action() {public void doSomething() { /* do nothing */ }};public Action findAction(String userInput) {// ...if ( /* we cant find any actions */ ) {return NO_ACTION;}}
}对比下面两份调用实例
1.冗余: 每获取一个对象就判一次空
Parser parser ParserFactory.getParser();
if (parser null) {// now what?// this would be an example of where null isnt (or shouldnt be) a valid response
}
Action action parser.findAction(someInput);
if (action null) {// do nothing}
else {action.doSomething();
}2.精简
ParserFactory.getParser().findAction(someInput).doSomething();因为无论什么情况都不会返回空对象因此通过findAction拿到action后可以放心地调用action的方法。
顺便再提下一个插件 .NR Null Object插件 NR Null Object是一款适用于Android Studio、IntelliJ IDEA、PhpStorm、WebStorm、PyCharm、RubyMine、AppCode、CLion、GoLand、DataGrip等IDEA的Intellij插件。其可以根据现有对象便捷快速生成其空对象模式需要的组成成分其包含功能如下 分析所选类可声明为接口的方法抽象出公有接口创建空对象自动实现公有接口对部分函数进行可为空声明可追加函数进行再次生成自动的函数命名规范
5、场景五Java8中使用Optional推荐
假设我们有一个像这样的类层次结构:
class Outer {Nested nested;Nested getNested() {return nested;}
}
class Nested {Inner inner;Inner getInner() {return inner;}
}
class Inner {String foo;String getFoo() {return foo;}
}解决这种结构的深层嵌套路径是有点麻烦的。我们必须编写一堆 null 检查来确保不会导致一个 NullPointerException:
Outer outer new Outer();
if (outer ! null outer.nested ! null outer.nested.inner ! null) {System.out.println(outer.nested.inner.foo);
}我们可以通过利用 Java 8 的 Optional 类型来摆脱所有这些 null 检查。map 方法接收一个 Function 类型的 lambda 表达式并自动将每个 function 的结果包装成一个 Optional 对象。这使我们能够在一行中进行多个 map 操作。Null 检查是在底层自动处理的。
Optional.of(new Outer()).map(Outer::getNested).map(Nested::getInner).map(Inner::getFoo).ifPresent(System.out::println);还有一种实现相同作用的方式就是通过利用一个 supplier 函数来解决嵌套路径的问题:
Outer obj new Outer();
resolve(() - obj.getNested().getInner().getFoo()).ifPresent(System.out::println);调用 obj.getNested().getInner().getFoo()) 可能会抛出一个 NullPointerException 异常。在这种情况下该异常将会被捕获而该方法会返回 Optional.empty()。
public static T OptionalT resolve(SupplierT resolver) {try {T result resolver.get();return Optional.ofNullable(result);}catch (NullPointerException e) {return Optional.empty();}
}请记住这两个解决方案可能没有传统 null 检查那么高的性能。不过在大多数情况下不会有太大问题。
更多Optional可以看这篇 Java8特性第三讲如何使用Optional类优雅解决业务npe问题 Optional类的意义Optional类有哪些常用的方法Optional举例贯穿所有知识点多重类嵌套Null值判断