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

news/2024/7/8 8:45:17

模式的定义

空对象模式(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类图

这里写图片描述

模式的简单实现

先定义一个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


http://www.niftyadmin.cn/n/4545740.html

相关文章

(MFC)CPropertySheet的生成

在进行书本上例子代码的编写中发现,在属性对话框的类生成中没有发现CPropertySheet这个基类,后来经仔细阅读才知道,这是一个MFC类,在类生成器中选择MFC类能自动生成,不能通过属性对话框的类生成器来指定基类为CPropert…

如果我是面试官,我要出什么面试题(持续更新)

最近在看书,觉得自己也是可以出一些非常好的面试题,真的是非常的好,可以测试一个人的真实水平。哈哈,来吧,就积累几道吧,以后做面试官直接来用。 开发的基础 什么样的子程序是高质量的?&#…

如果我是面试官,我要出什么面试题(持续更新)--参考答案

开发的基础 什么样的子程序是高质量的?(什么样的方法或函数是高质量的) 参考答案: 这是《代码大全2》的第7章高质量的子程序讲解的内容,我大概总结了一下: (1)方法的名称要清晰描述方法的功能&#xff…

java核心技术之反转排序算法

基本思想 反转排序,就是以相反的顺序把原来的数组的内容重新排序。比较简单,也是经常用到的。 算法示例 反转排序是对数组两边的元素进行替换,所以只需要循环数组长度的一半。如数组为【1,2,3,4&#xf…

【图的最短路径】迪杰斯特拉算法求图的最短路径

要求:求带权有向图中某一结点到其他结点的最短路径。 用迪杰斯特拉算法求解,迪杰斯特拉算法书上的描述如下:对于图G(V,{E}),将图中的顶点归为两组:第一组S:已求出的最短路…

java核心技术之直接选择排序算法

基本思想 直接选择排序是选择排序的一种,其排序速度比冒泡排序要快一些,是常用的排序算法之一。 其基本思想是的将指定排序位置与其他数组元素分别比较,如果满足条件就交换元素值。注意,这里与冒泡排序的区别是不是交换相邻元素…

github项目之安卓开发小助手

安卓开发小助手是我开发的一个小工具集: 现在主要有下面几方面的内容: 1.android develop helper—-安卓开发小助手 安卓开发小助手的主界面: 2.显示手机所有的应用详细信息 可以显示手机所有的应用的详细信息,可以对手机的所有应用进行管…

navigationBar设置透明度

将NavigationBar设置透明&#xff08;仅将指定视图控制器进行透明处理&#xff09;&#xff0c;步骤如下&#xff1a;1.在视图控制器的头文件中实现UINavigationControllerDelegate&#xff0c;例如&#xff1a;interface PicturePreviewViewController : UIViewController<…