Design Mode note Proxy mode Proxy
// Proxy mode ----- object structure mode
/*
1: Intention:
Provides a proxy for other objects to control access to this object.
2: alias:
Surrogate
3: motivation:
4: Applicability:
1> remote proxy:
Provides a local representation of an object in different address spaces.
2> virtual Proxy:
Create objects with high overhead as needed.
3> protection proxy:
Controls access to the original object. Protection proxy is used when the object should have different access permissions.
4> pointer guide:
Instead of a simple pointer, it performs some additional operations when accessing the object:
1) count the number of times the object is referenced, so that the object can be automatically released if it is not referenced. (Smart pointer)
2) When a persistent object is referenced for the first time, load it into the memory. (Lazy loading)
3) before accessing an actual object, check whether it has been locked to ensure that other objects cannot be changed. (Multi-thread locking)
5: structure:
Client -------------> Subject:
Request ()
|
|
-------------------
|
| Proxy:
RealSubject: <------- realSubject
Request ()
{...
RealSubject-> Request ();
...}
6: participants:
1> Proxy:
1) Save a reference so that the proxy can access the object
2) provide the same interface as the Subject interface, so that the proxy can be used to replace the entity.
3) controls access to an object and may be responsible for creating and deleting it.
4) Other functions are agent-type:
1-Remote Proxy: encodes requests and their parameters, and sends encoded requests to entities in different address spaces.
2-Virtual Proxy: It can cache additional information of an object to delay access to it.
3-Protection Proxy: Check whether the caller has the necessary access permissions to implement a request.
2> Subjet:
Defines the public interfaces of RealSubject and Proxy, so that Proxy can be used in any place where RealSubject is used.
3> RealSubject:
Define the entity represented by the Proxy.
7: collaboration:
The proxy forwards requests to RealSubject as appropriate based on their types.
8: effect:
1> Remote Proxy can hide the fact that an object exists in different address spaces.
2> Virtual Proxy can be optimized, such as creating objects as required.
3> Protecition Proxies and Smart Reference both allow additional housekeeping when accessing an object.
4> Copy-on-wirte:
Copying a large object is a costly operation. If this copy is not modified, these overhead are unnecessary and can be used.
The proxy to delay the copy operation. At first, the proxy only adds one reference count of the object. When the user needs to modify the copy, it will actually execute
Copy action, and reduce the reference count.
9: Implementation:
1> reload the access operators in C ++
C ++ supports the-> and * operators. Therefore, we need to overload these two operators to load real objects before they are used (before these two operators are not called)
We do not need to load.
2> Proxy does not always need to know the object type.
1) The entity does not need to be instantiated. You do not need to generate a specific Proxy class for a specific RealSubject class. The Proxy class can be processed in a unified manner.
All such RealSubject classes.
2) When the object needs to be instantiated. Before instantiation, you can use a specific Identifier to represent an object, such as a file path.
10: Sample Code :*/
// Subject class, which defines the interfaces of RealSubject and Proxy
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 & form) = 0;
Virtual void Save (ostrean & to) = 0;
Protected:
Graphic ();
};
// RealSubject class
Class Image: public Graphic
{
Public:
Image (const char * file );
Virtual ~ Image ();
Virtual void Draw (const Point & );
Virtual void HandleMouse (Event & event );
Virtual const Point & GetExtent ();
Virtual void Load (istream & form );
Virtual void Save (ostrean & );
Private:
...
};
// Proxy class
Class ImageProxy: public Graphic
{
Public:
ImageProxy (const char * file );
Virtual ~ ImageProxy ();
Virtual void Draw (const Point & );
Virtual void HandleMouse (Event & event );
Virtual const Point & GetExtent ();
Virtual void Load (istream & form );
Virtual void Save (ostrean & );
Protected:
Image * GetImage ();
Private:
Image * _ image;
Point _ extent;
Char * fileName;
};
// Constructor, which accepts a fileName (cosnst char *) parameter
ImageProxy: ImageProxy (const char * fileName)
{
_ FileName = strdup (fileName );
_ Extent = Point: Zero;
_ Image = 0;
}
// Only at this time will the Image be created
Image * ImageProxy: GetImage ()
{
If (_ image = 0)
{
_ Image = new Image (_ fileName );
}
Return _ image;
}
// If it has already been cached, _ exyent is returned directly.
Const Point & ImageProxy: GetExtent ()
{
If (_ extent = Point: Zero)
_ Extent = GetImage ()-> GetExtent ();
Return _ extent;
}
// Implement the inherited Interface
Void ImageProxy: Draw (const Point &)
{
GetImage ()-> Draw ();
}
Void ImageProxy: HandleMouse (Event & event)
{
GetImage ()-> HandleMouse (event );
}
Void ImageProxy: Save (ostrean &)
{
To <_ extent <_ fileName;
}
Void ImageProxy: Load (istream & from)
{
From> _ extent> _ fileName;
}
Class TextDocument
{
Public:
TextDocument ();
Void Insert (Graphic *);
};
// How to use
TextDocument * text = new TextDocument;
Text-> Insert (new ImageProxy (naImageFileName ));