什么是空对象模式

用一个空对象取代 NULL 对象实例的检查。Null 对象不是检查空值,而是反应一个不做任何动作的关系。这样的 Null 对象也可以在数据不可用的时候提供默认的行为。

适用场景

提供默认行为,提供默认值。

  1. abstract class AbstractCustomer {
  2. protected String name;
  3. public abstract boolean isNull();
  4. public abstract String getName();
  5. }
  6. class RealCustomer extends AbstractCustomer {
  7. public RealCustomer(String name) {
  8. this.name = name;
  9. }
  10. @Override
  11. public String getName() {
  12. return name;
  13. }
  14. @Override
  15. public boolean isNull() {
  16. return false;
  17. }
  18. }
  19. class NullCustomer extends AbstractCustomer {
  20. @Override
  21. public String getName() {
  22. return "Not Available in Customer Database";
  23. }
  24. @Override
  25. public boolean isNull() {
  26. return true;
  27. }
  28. }
  29. class CustomerFactory {
  30. public static final String[] NAMES = {"Rob", "Joe", "Julie"};
  31. public static AbstractCustomer getCustomer(String name) {
  32. for (String s : NAMES) {
  33. if (s.equalsIgnoreCase(name)) {
  34. return new RealCustomer(name);
  35. }
  36. }
  37. return new NullCustomer();
  38. }
  39. }
  40. /**
  41. * 空对象模式 测试类
  42. */
  43. public class NullObjectPattern {
  44. public static void main(String[] args) {
  45. AbstractCustomer customer1 = CustomerFactory.getCustomer("Rob");
  46. AbstractCustomer customer2 = CustomerFactory.getCustomer("Bob");
  47. AbstractCustomer customer3 = CustomerFactory.getCustomer("Julie");
  48. AbstractCustomer customer4 = CustomerFactory.getCustomer("Laura");
  49. System.out.println("Customers");
  50. System.out.println(customer1.getName());
  51. System.out.println(customer2.getName());
  52. System.out.println(customer3.getName());
  53. System.out.println(customer4.getName());
  54. //输出:
  55. //Customers
  56. //Rob
  57. //Not Available in Customer Database
  58. //Julie
  59. //Not Available in Customer Database
  60. }
  61. }

Java8提供的Optional

  1. public class OptionalDemo {
  2. public static void main(String[] args) {
  3. //JAVA的败笔之一 就是提供了null这个默认值 使得NPE到处出现,空指针异常编译时无法发现,运行时系统崩溃
  4. // String s = null;
  5. // System.out.println(s.length()); //NullPointerException
  6. //改进如下
  7. // if (null != s) {
  8. // System.out.println(s.length());
  9. // }
  10. //JDK8 提供了Optional
  11. //默认EMPTY值
  12. Optional<Object> empty = Optional.empty();
  13. System.out.println(empty);//Optional.empty
  14. System.out.println("-----------------------------");
  15. String str1=null;
  16. // Optional<String> s1 = Optional.of(str1);//NullPointerException
  17. Optional<String> s1 = Optional.ofNullable(str1);//NullPointerException
  18. System.out.println(s1);//Optional.empty
  19. // System.out.println(s1.get());//NullPointerException
  20. System.out.println(s1.isPresent());//false
  21. System.out.println(s1.orElse("默认值"));//默认值
  22. System.out.println("-----------------------------");
  23. String str2="test";
  24. Optional<String> s2 = Optional.of(str2);
  25. System.out.println(s2);//Optional[test]
  26. Optional<String> s3 = Optional.ofNullable(str2);
  27. System.out.println(s3);//Optional[test]
  28. System.out.println(s3.get());//test
  29. System.out.println(s3.isPresent());//true
  30. System.out.println(s3.orElse("默认值"));//test
  31. }
  32. }