再话设计模式-空对象模式

1 说明

      在实际编程中,总会遇到空值校验,这种惯用法很常见,例如下述代码:

		Employee e = DB.getEmployee("Bob");
        if (e != null && e.isTimeToPay(today)) {
            e.pay();
        }

但这样的代码却是丑陋且易出错的。使用空对象模式可以解决这个问题。该模式可以消除对null进行校验的代码,有助于简化代码。

2 空对象模式(Null Object Pattern)

      鉴于该模式比较简单就直接看代码即可。

  1. Employee.java —接口
  2. EmployeeImpl.java
  3. NullObjectMain.java

1 Employee.java

public interface Employee {
    boolean isTimeToPay(Date payDate);

    void pay();

    Employee NULL = new Employee() {
        @Override
        public boolean isTimeToPay(Date payDate) {
            System.out.println("Null Object can't get salary!");
            return false;
        }

        @Override
        public void pay() {
        }
    };
}

2 EmployeeImpl.java

public class EmployeeImpl implements Employee {

    private String name;

    public EmployeeImpl(String name) {
        this.name = name;
    }

    @Override
    public boolean isTimeToPay(Date payDate) {
        String dateStr = getDateString(payDate);
        if("25".equals(dateStr)){
            return true;
        }
        return false;
    }

    @Override
    public void pay() {
        System.out.println("Get Salary");
    }

    private String getDateString(Date date){
        SimpleDateFormat sd = new SimpleDateFormat("dd");
        return sd.format(date);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

3 NullObjectMain.java

public class NullObjectMain {
    public static void main(String[] args) {
        // 正常逻辑测试
        Employee employee1 =getEmployee("Bob");
        if(employee1.isTimeToPay(new Date())){
            employee1.pay();
        }

        // 空对象测试
        Employee employee2 =getEmployee("Peter");
        if(employee2.isTimeToPay(new Date())){
            employee2.pay();
        }
    }

    public static Employee getEmployee(String name){
        try{
            if("Bob".equals(name)){
                return new EmployeeImpl(name);
            }
            throw new Exception("获取失败!");
        } catch (Exception e){
            return Employee.NULL;
        }
    }
}

      现在再看下述代码是不是美观多了?

        Employee employee1 =getEmployee("Bob");
        if(employee1.isTimeToPay(new Date())){
            employee1.pay();
        }

3 结论

      对于惯用写法(因为某种失败返回null或者0的情况,对这样的返回值进行检查。)空对象模式可以改变这种写法,确保函数总是返回有效的对象,即使失败也是如此。失败对象将什么也不做,从而使代码得到简化。


版权声明:本文为weixin_37624828原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。