设计模式学习笔记(十三)——Proxy代理

    技术2022-05-11  91

    十二、Proxy(代理)

    情景举例:

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

    四种常见情况:(1)远程代理(2)虚代理(3)保护代理(4)智能指针

    代码示例:

    /* 这个例子是虚代理的例子。 */ /* 代理类与实际类公共接口 */ class Graphic { public:     virtual ~Graphic(); /* */     virtual void Draw(const Point& at) = 0;     virtual void HandleMouse(Event& event) = 0; /* */     virtual const Point& GetExtent() = 0; /* */     virtual void Load(istream& from) = 0;     virtual void Save(ostream& to) = 0; protected:     Graphic(); }; /* 实际类 */ class Image : public Graphic { public:     Image(const char* file);  // loads image from a file     virtual ~Image(); /* */     virtual void Draw(const Point& at);     virtual void HandleMouse(Event& event); /* */     virtual const Point& GetExtent(); /* */     virtual void Load(istream& from);     virtual void Save(ostream& to); private:     // ... }; /* 代理类 */ class ImageProxy : public Graphic { public:     ImageProxy(const char* imageFile);     virtual ~ImageProxy(); /* */     virtual void Draw(const Point& at);     virtual void HandleMouse(Event& event); /* */     virtual const Point& GetExtent(); /* */     virtual void Load(istream& from);     virtual void Save(ostream& to); protected:     Image* GetImage(); private:     Image* _image;     Point _extent;     char* _fileName; }; /* 构造函数只保存了文件名,并不实际打开文件。 */ ImageProxy::ImageProxy (const char* fileName)  {     _fileName = strdup(fileName);     _extent = Point::Zero;  // don't know extent yet     _image = 0; } /* 只有当实际需要使用文件时才真正生成对象(延迟处理) */ Image* ImageProxy::GetImage() {     if (_image == 0) {         _image = new Image(_fileName);     }     return _image; } const Point& ImageProxy::GetExtent () {     if (_extent == Point::Zero) {         _extent = GetImage()->GetExtent();     }     return _extent; } /* */ void ImageProxy::Draw (const Point& at) {     GetImage()->Draw(at); } /* */ void ImageProxy::HandleMouse (Event& event) {     GetImage()->HandleMouse(event); } /* */ void ImageProxy::Save (ostream& to) {     to << _extent << _fileName; } /* */ void ImageProxy::Load (istream& from) {     from >> _extent >> _fileName; } /* */ class TextDocument { public:     TextDocument();       void Insert(Graphic*);     // ... }; /* 主程序中演示了代理的用法。 */ void dummy () { /* */ TextDocument* text = new TextDocument; // ... text->Insert(new ImageProxy("anImageFileName")); /* */ }

    个人理解:

    代理模式是一种有各种变形的、应用非常广泛的模式。模式的关键是代理类与实际类拥有共同的父类(例中的Graphic类),而在代理类中保存着实际类的引用,代理类则可以在使用实际类之前添加自己的操作。

     

    最新回复(0)