餐馆那些事之:Null Object

1. 概述
在开发过程中,我们常常会越到这么一种case:向一个对象发送消息,每次都必须先检查对应的对象是否存在。如果对象存在执行相应操作,对象不存在则获取默认值或者做一些默认的操作。
NULL object即使这么一种模式:通过提供NULL对象,从而使客户在向对象发送消息时,不关心对象是否存在,NULL对象中保存相应的默认值或方法。
NULL object的优势个人理解:
1)降低代码复杂度
2)统一管理对象的默认值或方法
类图:

Client: 使用者
Object:使用接口
Concrete_object:client期待的real object
Null_object:do nothing 的接口类,用以替代Concrete_object

2. 实例
餐馆里面有很多waiter,把他们管理起来,每个waiter有个id,可以通过id给某个waiter发薪,也可以整体发薪
composite pattern + Null object pattern
代码:
#include <iostream>  
    #include <list>  
    #include <algorithm>  
    using namespace std;  
      
    //object
    class Emp_pay_base  
    {  
    public:  
            Emp_pay_base()  
            {  
            }  
      
            virtual ~Emp_pay_base()  
            {  
            }  
      
            virtual void pay()  = 0; 

                        virtual int get_id()
                        {
                                return _id;
                        }
        protected:
            int _salary;  
                        int _id;
    };  

    //concrete_object
    class Waiter : public Emp_pay_base  
    {  
    public:  
            Waiter(int salary, int id)  
            {  
                    _salary = salary;
                                        _id = id;
            }  
      
            virtual ~Waiter()  
            {  
            }  
      
            virtual void pay()  
            {  
                    cout << "Pay waiter salary: " << _salary << endl;  
            }  
      
    };  
      
    //NULL object
    class Null_emp : public Emp_pay_base  
    {  
    public:  
            Null_emp()  
            {  
                    _salary = 0;  
            }  
      
            virtual ~Null_emp()  
            {  
            }  
      
            virtual void pay()
            {  
                    cout << "Pay salary: " << _salary << endl;  
            }  
    };  
      

    //composite  
    class Emp_manage : public Emp_pay_base 
    {  
    public:  
            Emp_manage()
            {
                    Emp_pay_base* emp = new Null_emp();
                    _emp_list.push_back(emp);  
            }

            virtual ~Emp_manage()  
            {  
                    list<Emp_pay_base*>::iterator iter,tmp;  
                    for(iter = _emp_list.begin(); iter != _emp_list.end();)  
                    {  
                            if(*iter)  
                            {  
                                    tmp = iter;  
                                    iter++;  
                                    if(*tmp)  
                                    {  
                                            delete (*tmp);  
                                            *tmp = NULL;  
                                    }  
                            }  
                    }  
            }  
      
            virtual void add(int id)  
            {  
                   Emp_pay_base* emp= new Waiter(2000, id);
                    _emp_list.push_back(emp);  
            }  
      
            virtual Emp_pay_base* get_emp(int search_id)
           {
                    list<Emp_pay_base*>::iterator iter;  
                    for(iter = _emp_list.begin(); iter != _emp_list.end(); iter++)  
                    {  
                            if((*iter)->get_id() == search_id)  
                            {
                                                                return *iter;
                            }  
                    }

                     return *(_emp_list.begin());
            }  

            virtual void remove(Emp_pay_base* emp)  
            {  
                    list<Emp_pay_base*>::iterator iter;  
                    iter = find(_emp_list.begin(), _emp_list.end(), emp);  
                    while(iter != _emp_list.end())  
                    {  
                            _emp_list.erase(iter);  
                    }  
            }  
      
            virtual void pay()  
            {  
                    list<Emp_pay_base*>::iterator iter;  
                    for(iter = _emp_list.begin(); iter != _emp_list.end(); iter++)  
                    {  
                            (*iter)->pay();  
      
                    }  
            }  
        private:
                list<Emp_pay_base*> _emp_list;
        };

      
    int main(int argc, char** argv)  
    {  
            Emp_manage* emp_manage = new Emp_manage;  
      
            for(int i = 0; i <10; i++)
            {
                   emp_manage->add(i);    
             }
      
            Emp_pay_base* emp_pay1 = emp_manage->get_emp(5);
            emp_pay1->pay();

            //NULL object 使用
            Emp_pay_base* emp_pay2 = emp_manage->get_emp(50);
            emp_pay2->pay();
      
            emp_manage->pay();

            delete emp_manage;  
      
            return 0;  
    }
输出:
Pay waiter salary: 2000
Pay salary: 0
Pay salary: 0
Pay waiter salary: 2000
Pay waiter salary: 2000
Pay waiter salary: 2000
Pay waiter salary: 2000
Pay waiter salary: 2000
Pay waiter salary: 2000
Pay waiter salary: 2000
Pay waiter salary: 2000
Pay waiter salary: 2000
Pay waiter salary: 2000

转载于:https://my.oschina.net/zipu888/blog/549695

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值