设计模式之空对象模式--- Pattern Null Object

模式的定义

空对象模式(Null Object Pattern)定义如下:

Provide an object as a surrogate for the lack of an object of a given type. The Null Object provides intelligent do nothing behavior, hiding the details from its collaborators.

空对象模式提供一个给定类型的空对象代理,这个空对象不执行任何动作,对他的合作对象隐藏细节。

模式的使用场景

避免在程序中频繁的出现null值的判断

UML类图

设计模式之空对象模式--- Pattern Null Object_第1张图片

模式的简单实现

先定义一个AbstractObject类:

public abstract class AbstractObject {  
    public int id;
    public String name;
    //抽象方法
    public abstract void doAction();
    //抽象方法
    public abstract boolean isNull();
}

再定义一个实现类:ConcreteObject

public class ConcreteObject extends AbstractObject {
    public ConcreteObject(int id,String name) {
        // TODO Auto-generated constructor stub
        super.id = id;
        super.name = name;
    }

    @Override
    public void doAction() {
        // TODO Auto-generated method stub
        System.out.println("id:"+id+"--name:"+name+"---doAction()");
    }

    @Override
    public boolean isNull() {
        // TODO Auto-generated method stub
        return false;
    }
}

我们再定义一个工厂方法类:Factory

public class Factory {
    public static AbstractObject creator(int id) {
        // TODO Auto-generated method stub
        AbstractObject result = null;
        switch (id) {
        case 1:
            result = new ConcreteObject(1, "hello");
            break;
        case 2:
            result = new ConcreteObject(2, "world");
            break;
        default:
            result = null;
            break;
        }
        return result;
    }
}

再定义一个客户端:

public class clent {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        AbstractObject aObject = Factory.creator(1);
        aObject.doAction();
        System.out.println("----------------------------");
        aObject = Factory.creator(2);
        aObject.doAction();
        System.out.println("----------------------------");
        aObject = Factory.creator(-1);
        aObject.doAction();
        System.out.println("----------------------------");
    }
}

代码输出:

id:1--name:hello---doAction()Exception in thread "main" java.lang.NullPointerException
    at clent.main(clent.java:14)

----------------------------
id:2--name:world---doAction()
----------------------------

提示说空指针报错,当然这个错误非常明显,我们一下就可以知道是什么原因。解决如下:
修改客户端代码,加上非空判断:

public class clent {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        AbstractObject aObject = Factory.creator(1);
        if(aObject != null){
            aObject.doAction();
        }       
        System.out.println("----------------------------");
        aObject = Factory.creator(2);
        if(aObject != null){
            aObject.doAction();
        }
        System.out.println("----------------------------");
        aObject = Factory.creator(-1);
        if(aObject != null){
            aObject.doAction();
        }
        System.out.println("----------------------------");
    }
}

我们加上对对象的非空判断,可能觉得没有什么,如果这个对象运行的地方特别多,那我们每个地方都要加上这样一个非空判断,是不是又重复了大量的代码,增加了工作量,也显示不那么美观啊。

那么这时候空对象模式就闪亮登场了,它就是处理此问题的。

我们再定义一个空对象类:NullObject

public class NullObject extends AbstractObject {

    //此方法我们一般是不做任何处理,只是输出一些提示信息
    @Override
    public void doAction() {
        // TODO Auto-generated method stub
        System.out.println("NullObject"+"---doAction(),please make sure you input is right!!!!");
    }
    @Override
    public boolean isNull() {
        // TODO Auto-generated method stub
        return true;
    }
}

修改工厂方法类:Factory


public class Factory {

    public static AbstractObject creator(int id) {
        // TODO Auto-generated method stub
        AbstractObject result = null;
        switch (id) {
        case 1:
            result = new ConcreteObject(1, "hello");
            break;
        case 2:
            result = new ConcreteObject(2, "world");
            break;
        default:
            //返回空对象
            result = new NullObject();
            break;
        }
        return result;
    }
}

再定义客户端:

public class clent {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        AbstractObject aObject = Factory.creator(1);
        aObject.doAction();
        System.out.println("----------------------------");
        aObject = Factory.creator(2);
        aObject.doAction();
        System.out.println("----------------------------");
        aObject = Factory.creator(-1);
        aObject.doAction();
        System.out.println("----------------------------");
    }
}

程序输出:

id:1--name:hello---doAction()
----------------------------
id:2--name:world---doAction()
----------------------------
NullObject---doAction(),please make sure you input is right!!!!
----------------------------

看到了没,空对象模式不但可以避免对对象的非空判断,还可以把对象为空的异常信息打印出来。

优点

  • 可以加强系统的稳固性,能有有效地防止空指针报错对整个系统的影响,使系统更加稳定。
  • 能够实现对空对象情况的定制化的控制,能够掌握处理空对象的主动权。
  • 并不依靠Client来保证整个系统的稳定运行。
  • 通过isNull对==null的替换,显得更加优雅,更加易懂。

参考资料

1.在代码中引入Null Object模式
http://blog.csdn.net/liuhe688/article/details/6586458
2.被遗忘的设计模式——空对象模式(Null Object Pattern)
http://www.2cto.com/kf/201504/388387.html

你可能感兴趣的:(设计模式之样例篇,设计模式之android,设计模式,空对象模式,Null-Objec)