• 代理模式


     代理模式:为其他对象提供一种代理以控制对这个对象的访问

    有四种常用的情况: 

    • 远程代理: 为一个对象在不同的地址空间提供局部代表。例如:

              使用代理服务器访问远程服务器,能够

              1)提高访问速度:因为通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到              缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,以提高访问速度。

        2)隐藏真实IP

             3)突破IP封锁,访问国外站点、访问一些单位或团体内部资源,如某大学内部FTP

    • 虚拟代理: 根据需要创建开销很大的对象,如加载图片
    • 保护代理: 控制对原始对象的访问,用于对象有不同的访问权限的时候
    • 智能指引:取代了简单的指针,在访问对象时执行了一些附加的操作。如C++中的auto_ptr就是使用了代理模式,使我们可以不关注资源的释放。(执行附加的操作可以理解为对原始类作前处理和后处理等)

    先访问代理类再访问真正要访问的对象。似乎这样有点多此一举的味道,其实不然。代理类可以在真正的类执行之前,进行预处理。 比富士康生产的手机之前可能会坚持元器件是否合格,不合格就不生产等。在比如你有一个系统实现了登陆功能,在用户登录时, 真正的登录类和代理登录类都实现了Login接口, 不同的是Proxy类的方法中增加了用户是否合法的判断, 只有合法时才去调用真正登录类的login方法. 用户访问的其实是Proxy的login方法.这都是代理模式的优点。而且采用代理模式的话,并且你可以随时更改代理。还有一点你会发现,真正对象与代理他们实现同一个接口。
    这个模式和装饰者模式有点类似之处,都是包装,但是请注意他们应用场景不一样:一个是动态的给类添加职责,一个是控制对这个对象的访问。最重要的一点不同是他们的结构不同,具体参加UML类图。

    代码:

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Girl
    {
    public:
        Girl(string name) :_name(name){}
        string getName() const { return _name; }
    private:
        string _name;
    };
    
    class IGiveGift
    {
    public:
        virtual ~IGiveGift() {}
    public:
        virtual void giveFlowers() = 0;
        virtual void giveDolls() = 0;
    };
    
    class Pursuit : public IGiveGift
    {
    public:
        Pursuit(string name, Girl *g) :_girl(g), _name(name){}
    public:
        virtual void giveFlowers()
        {
            cout << _girl->getName() << "送你鲜花" << endl;
        }
    
        virtual void giveDolls()
        {
            cout << _girl->getName() << "送你玩具" << endl;
        }
    
        string getName() const { return _name; }
    
    private:
        Girl *_girl;
        string _name;
    };
    
    class Proxy : public IGiveGift
    {
    public:
        Proxy(string name, Girl *g)
        {
            _pursuit = new Pursuit(name, g);
        }
    
        ~Proxy()
        {
            delete _pursuit;
        }
    
        virtual void giveFlowers()
        {
            cout << _pursuit->getName() << "说: ";
            _pursuit->giveFlowers();
        }
    
        virtual void giveDolls()
        {
            cout << _pursuit->getName() << "说: ";
            _pursuit->giveDolls();
        }
    
    private:
        Pursuit *_pursuit;
    };
    
    void test()
    {
        Girl g("marry");
        Proxy p("peter", &g);
        p.giveFlowers();
        p.giveDolls();
    }
    
    int main()
    {
        test();
        cin.get();
        return 0;
    }
    View Code

    效果:

    控制访问权限:

    虚拟代理:

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Image
    {
    public:
        Image(string name) :_name(name){}
        virtual ~Image() {}
        virtual void show() = 0;
    protected:
        string _name;
    };
    
    class BigImage : public Image
    {
    public:
        BigImage(string name) :Image(name){}
        virtual void show()
        {
            cout << "Display big image " << _name << endl;
        }
    };
    
    class BigImageProxy : public Image
    {
    public:
        BigImageProxy(string name):Image(name), _bigImage(NULL){}
        ~BigImageProxy()
        {
            if (_bigImage != NULL)
            {
                delete _bigImage;
                _bigImage = NULL;
            }
        }
        virtual void show()
        {
            if (_bigImage == NULL)
            {
                _bigImage = new BigImage(_name);
            }
            _bigImage->show();
        }
    private:
        BigImage *_bigImage;
        string _name;
    };
    
    void test()
    {
        Image *image = new BigImageProxy("cat.jpg");
        image->show();
        delete image;
    }
    
    int main()
    {
        test();
        cin.get();
        return 0;
    }
    View Code

    智能指针

    #include <iostream>
    #include <string>
    #include <memory>
    using namespace std;
    
    template<class T>
    class Auto_ptr
    {
    public:
        explicit Auto_ptr(T *p = 0) :_ptr(p){}
        Auto_ptr(Auto_ptr<T> &other) :_ptr(other.release()){}
        Auto_ptr &operator=(Auto_ptr<T>&other)
        {
            if (this != &other )
                reset(other.release());
            
            return *this;
        }
    
        ~Auto_ptr()
        {
            delete _ptr;
            _ptr = NULL;
        }
        T & operator*() const
        {
            return *_ptr;
        }
        T * operator->() const
        {
            return _ptr;
        }
        T *get() const
        {
            return _ptr;
        }
    
    
        T * release()
        {
            T *tmp = _ptr;
            _ptr = NULL;
            return tmp;
        }
    
        void reset(T *p)
        {
            if (_ptr != p)
            {
                delete _ptr;
                _ptr = p;
            }
            
        }
        
        
    private:
        T * _ptr;
    };
    
    class A
    {
    public:
        A(string name) :_name(name){ cout << "constructor A() " << name << endl; }
        ~A(){ cout << "destructor ~A() " << _name << endl; }
        void show()
        {
            cout << "I am A" << endl;
        }
    private:
        string _name;
    };
    
    void test()
    {
        Auto_ptr<A> ap(new A("你好"));
        ap->show();
        (*ap).show();
        cout << "ap地址 " << ap.get() << endl;
        cout << "----------------" << endl;
        Auto_ptr<A> ap2(new A("大家好"));
        cout << "ap2地址 " << ap2.get() << endl;
        ap = ap2;
        cout << "ap地址 " << ap.get() << endl;
        cout << "ap2地址 " << ap2.get() << endl;
        ap->show();
        cout << "--------------------" << endl;
        Auto_ptr<A> ap3(ap);
        cout << "ap地址 " << ap.get() << endl;
        cout << "ap3地址 " << ap3.get() << endl;
    
    }
    
    int main()
    {
        test();
        cin.get();
        return 0;
    }
    View Code

    效果:

  • 相关阅读:
    weui若干问题小结(排坑指南)
    Kafka3.1.0集群安装(KRaft模式)
    Kafka3.1.0集群搭建(使用自带zookeeper)
    微信小程序后台获取数据刷新页面
    微信小程序开发知识点汇总
    (打包)打包出错 Failed to execute goal org.apache.maven.plugins:mavensurefireplugin:2.18.1
    C++ noexcept关键字有时候会导致函数体变大
    微信小程序切换时回到顶部
    echarts图例legend中name和数值设置为不同的颜色
    DuckChat
  • 原文地址:https://www.cnblogs.com/hupeng1234/p/6813835.html
Copyright © 2020-2023  润新知