设计模式之代理(Proxy)----对象结构型模式

36 篇文章 0 订阅
16 篇文章 0 订阅

                            设计模式之代理(Proxy)----对象结构型模式

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

2.别名 Surrogate

3.适用性

在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxyy 模式。下面是一 些可以使用Proxy模式常见情况:

1) 远程代理(Remote Proxy )为一个对象在不同的地址空间提供局部代表。 NEXTSTEP[Add94] 使用N X P r o x y 类实现了这一目的。

2 )虚代理(Virtual Proxy )根据需要创建开销很大的对象。在动机一节描述的ImageProxy就是这样一种代理的例子。
3) 保护代理(Protection Proxy )控制对原始对象的访问。保护代理用于对象应该有不同 的访问权限的时候。
4 )智能指引(Smart Reference )取代了简单的指针,它在访问对象时执行一些附加操作。 它的典型用途包括:

*对指向实际对象的引用计数,这样当该对象没有引用时,
*当第一次引用一个持久对象时,将它装入内存。
*在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。

4.结构





5.参与者

*Proxy
---保存一个引用使得代理可以访问实体。若RealSubject和Subject的接口相同,Proxy会引用Subject。
---提供一个与Subject的接口相同的接口,这样代理就可以用来替代实体。
---控制对实体的存取,并可能负责创建和删除他。
---其他功能依赖于代理的类型。
*Subject
---定义RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy.
*RealSubject
---定义Proxy所代表的实体。

6.协作

代理根据其种类,在适当的时候向RealSubject转发请求。

7.代码示例:




#ifdef Implementation
class Image {
public:
virtual void Draw(const Point&);
};


class Image;
extern Image* LoadAnImageFile(const char*);
// external function

class ImagePtr {
public:
ImagePtr(const char* imageFile);
virtual ~ImagePtr();


virtual Image* operator->();
virtual Image& operator*();
private:
Image* LoadImage();
private:
Image* _image;
const char* _imageFile;
};

ImagePtr::ImagePtr (const char* theImageFile) {
_imageFile = theImageFile;
_image = 0;
}

Image* ImagePtr::LoadImage () {
if (_image == 0) {
_image = LoadAnImageFile(_imageFile);
}
return _image;
}

Image* ImagePtr::operator-> () {
return LoadImage();
}

Image& ImagePtr::operator* () {
return *LoadImage();
}

void dummy () {

ImagePtr image = ImagePtr("anImageFileName");
image->Draw(Point(50, 100));
// (image.operator->())->Draw(Point(50, 100))

}

#endif

#ifdef SampleCode
#include "iostream.h"
#include "strings.h"

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"));

}

#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值