Reputation: 22946
From here: http://www.oodesign.com/proxy-pattern.html
Applicability & Examples
The Proxy design pattern is applicable when there is a need to control access to an Object, as well as when there is a need for a sophisticated reference to an Object. Common Situations where the proxy pattern is applicable are:
Virtual Proxies: delaying the creation and initialization of expensive objects until needed, where the objects are created on demand (For example creating the RealSubject object only when the doSomething method is invoked).
Protection Proxies: where a proxy controls access to RealSubject methods, by giving access to some objects while denying access to others.
Smart References: providing a sophisticated access to certain objects such as tracking the number of references to an object and denying access if a certain number is reached, as well as loading an object from database into memory on demand.
Well, can't Virtual Proxies be created by creating an individual function (other than the constructor) for a new object?
Can't Protection Proxies be created by simply making the function private, and letting only the derived classes get the accesses? OR through the friend class?
Can't Smart References be created by a static member variable which counts the number of objects created?
In which cases should the Proxy method be preferred on the access specifiers and inheritance?
What's the point that I am missing?
Upvotes: 3
Views: 5132
Reputation: 1907
Your questions are a little bit abstract, and i'm not sure i can answer at all well, but here are my thoughts on each of them. Personally i dont agree that some of these things are the best designs for the job, but that isn't your question, and is a matter of opinion.
Virtual Proxies I don't understand what you are trying to say here at all. The point of the pattern here is that you might have an object A that you know will take 100MB, and you don't know for sure that you will ever need to use this object.
To avoid allocating memory for this object until it is needed you create a dummy object B that implements the same interface as A, and if any of its methods are called B creates an instance of A, thus avoiding allocating memory until it is needed.
Protection Proxies Here i think you have misunderstood the use of the pattern. The idea is to be able to dynamically control access to an object. For example you might want class A to be able to access class B's methods unless condition C is true. As i'm sure you can see this could not be achieved through the use of access specifiers.
Smart Referances Here i think you misunderstand the need for smart pointers. As this is quite a complicated topic i will simply provide a link to a question about them: RAII and smart pointers in C++
If you have never programmed in a language like C where you manage your memory yourself then this might explain the confusion.
I hope this helps to answer some of your questions.
EDIT:
I didn't notice that this was tagged c++ so i assume you do in fact recognize the need to clean up dynamic memory. The single static reference count will only work if you only intend to ever have one instance of your object. If you create 2000 instances of an object, and then deleted 1999 of them none of them would have their memory freed until the last one left scope which is clearly not desirable (That is assuming you had kept track of the locations of all the allocated memory in order to be able to free it!).
EDIT 2:
Say you have a class as follows:
class A {
public:
static int refcount;
int* allocated_memory;
A() {
++refcount;
allocated_memory = new int[100000000];
}
~A() {
if(! --refcount) {
delete [] allocated_memory;
}
}
}
And some code that uses it:
int main() {
A problem_child; // After this line refcount == 1
while(true) {
A in_scope; // Here refcount == 2
} // We leave scope and refcount == 1.
// NOTE: in_scope.allocated_memory is not deleted
// and we now have no pointer to it. Leak!
return;
}
As you can see in the code refcount counts all references to all objects, and this results in a memory leak. I can explain further if you need, but this is really a seperate question in its own right.
Upvotes: 4
Reputation: 55957
It's good to question whether there are alternatives to standard solutions to problems. Design Patterns represent solutions that have worked for many folks and have the advantage that there's a good chance that an experienced programmer coming to the code will recognize the pattern and so find maintaining the code easier. However, all designs represent trade-offs and patterns have costs. So you are right to challenge the use of patterns and consider alternatives.
In many cases design is not just about making code work, but considering how it is structured. Which piece of code "knows" what. You proposal for an alternative for Virtual Prozy moves (as fizzbuzz says) knowledge of creation from the proxy to the client - the client has to "know" to call Create() and so is aware of the life-cycle of the class. Whereas with the proxy he just makes an object that he treats as the worker, then invisibly creation happens when the proxy decides it makes sense. This refactoring of responsibility into the proxy is found to valuable, it allows us in the future to change those life-cycle rules without changing any clients.
Protection proxy: your proposal requires that clients have an inheritance relationship so that they can use protected methods. Generally speaking that couples client and worker too tightly, so we introduce a proxy.
Smart reference: no, a single static count is no good. You need to count references to individual instances.
If you carefully work through each case you will find there are merits to the design patterns. If you try to implement an alternative you start with some code that sems simpler that the design pattern and then discover that as you start to refactor and improve the code, removing deuplicationand so on you end up reinventing the design pattern - and that's a really nice outcome.
Upvotes: 0
Reputation: 4015
I am no expert, but here are my thoughts on Virtual Proxies : If we control the initialization via a separate function say bool Create();
then the responsibility and control of Initialization lies with the client of the class. With virtual proxies , the goal is to retain creation control within the class, without client being aware of that.
Protection Proxies: The Subject being protected might have different kinds of clients, ones which need to get unprotected/unrestricted access to all Subject methods and the others which should be allowed access to a subset of methods hence need for Protection proxy.
Upvotes: 1
Reputation: 14392
A proxy is an object behaving as a different object to add some control/behavior. A smart pointer is a good example: it accesses the object as if you would use a raw pointer, but it also controls the lifetime of that object.
Upvotes: 0