第31章 新的设计模式(3)

31.3 空对象模式(Null Object Pattern)

31.3.1 定义和类图

(1)定义:通过实现一个默认的无意义对象避免NULL值出现。简单地说,就是为了避免在程序中出现NULL值判断而诞生的一种常用设计方法。

(2)类图

31.3.2 应用场景

(1)不使用空对象模式的例子

【编程实验】利用工厂模式创建图书

//新设计模式——空对象模式
//场景:利用简单工厂方法创建图书(不使用空对象模式)
#include <iostream>
#include <string>
using namespace std;

class IBook
{
public:
    //展示Book对象信息内容
    virtual void show() = 0;
};

//具体的书
class Book :public IBook
{
private:
    int id;
    string name;
    string author;
public:
    //构造函数
    Book(int id, string name, string author)
    {
        this->id = id;
        this->name = name;
        this->author = author;
    }

    void show()
    {
        cout <<"ID = " << id <<", Name = "
             << name << ", Author = " << author <<endl;
    }
};

//图书对象的图书工厂代码
class BookFactory
{
public:
    IBook* getBook(int id)
    {
        IBook* book = NULL;
        switch(id)
        {
        case 1:
            book = new Book(id, "设计模式", "GOF");
            break;
        case 2:
            book = new Book(id, "编译原理", "Alfred V.Aho");
            break;
        default:
            book = NULL;
            break;
        }

        return book;
    }
};

int main()
{
    BookFactory bf;
    IBook* book = bf.getBook(3); //传入1、2时正常运行,但其他值时会报错。
    //常规做法是客户端加一个判断,如果为NULL,就不能调用Show
    //但这种做法要依赖客户端,如果是多处调用的话,则每处都必须判断也显得很
    //麻烦,如何解决这个问题?见后面的空对象模式
    if(book == NULL)
    {
        cout << "book对象为NULL" << endl;
    }
    else
    {
        book->show();
    }

    return 0;
};

(2)解决方案:空对象模式

【编程实验】利用工厂模式+空对象模式创建图书

//新设计模式——空对象模式
//场景:利用简单工厂方法创建图书(使用空对象模式)
#include <iostream>
#include <string>
using namespace std;

class IBook
{
public:
    //展示Book对象信息内容
    virtual void show() = 0;
    //判断对象是否为空
    virtual bool isNull() = 0;  //注意,这是新增的方法
};

//具体的书
class Book :public IBook
{
private:
    int id;
    string name;
    string author;
public:
    //构造函数
    Book(int id, string name, string author)
    {
        this->id = id;
        this->name = name;
        this->author = author;
    }

    void show()
    {
        cout <<"ID = " << id <<", Name = "
             << name << ", Author = " << author <<endl;
    }
    bool isNull()
    {
        return false; //返回false
    }
};

//新增的空对象类(继承自IBook)
class NullBook : public IBook
{
public:

    //show
    void show()
    {
        //提示出错信息,一处定制,处处使用,主动权掌握在我们手里,而不是客户端手里
        cout <<"Sorry,未找到符合您输入的ID的图书信息,请确认您输入的不是非法值。" << endl;
    }

    bool isNull()
    {
        return true; //这里返回true
    }
};

//图书对象的图书工厂代码
class BookFactory
{
public:
    IBook* getBook(int id)
    {
        IBook* book = NULL;
        switch(id)
        {
        case 1:
            book = new Book(id, "设计模式", "GOF");
            break;
        case 2:
            book = new Book(id, "编译原理", "Alfred V.Aho");
            break;
        default:
            book = new NullBook(); //创建一个NullBook对象
            break;
        }

        return book;
    }
};

int main()
{
    BookFactory bf;
    IBook* book = bf.getBook(3); //传入1、2时正常运行,但其他值时返回空对象。

    //由于返回的book永远不等于NULL,这里可以直接调用book->show()
    //book->show();

    //但也可以让客户端调用isNull函数,并定制客户端自己的错误提示
    if(book->isNull())
    {
        //这里由客户端定制提示信息
        cout << "兄弟,你输入的ID不符合规范吧?" << endl;
    }
    else
    {
        book->show();
    }

    return 0;
};

31.3.3 小结

(1)空对象模式可以加强系统的稳固性,能有效防止空指针报错对整个系统的影响。

(2)能够实现对空对象情况的定制化的控制,能够掌握处理空对象的主动权

(3)不依赖Client端来保证整个系统的稳定运行

(4)它通过isNull代替“==NULL”,显得更加优雅,更加易懂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值