Proxy pattern - applicability and examples

From here: http://www.oodesign.com/proxy-pattern.html

Applicability and 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 complex reference to an object. Common situations where a proxy pattern is applicable:

Virtual proxies : delay creation and initialization of expensive objects until they are needed, where objects are created on demand (For example of creating a RealSubject object only when the doSomething method is called).

Security Profiles : where a proxy controls access to the RealSubject methods, granting access to some objects without denying access to others.

Smart Links : Providing complex access to specific objects such as keeping track of the number of references to an object and denying access if a certain number is reached, and loading an object from the database into memory on demand.

Well, can't Virtual Proxies create a separate function (besides the constructor) for the new object?

Can't create Security Proxies just by making the function private and only allowing access to derived classes? OR through a class of friends?

Can't create smart links with a static member variable that counts the number of objects created?

When should the proxy method be preferred on access specs and inheritance?

What's the point in what I'm missing?

+3


source to share


4 answers


Your questions are a little abstract and I'm not sure I can answer all of them well, but here are my thoughts on each one. Personally, I disagree that some of these things are the best projects to work with, but that's not your question and it's a matter of opinion.

Virtual Proxies I don't understand what you are trying to say here at all. The point of the template here is that you might have an object A that you know will take up 100MB and you don't know for sure that you will ever need that object.

To avoid allocating memory for that object until you need it, you will create a dummy object B that implements the same interface as A, and if any of its methods are called B, A is instantiated, thus avoiding allocating memory until needed.

Protective proxies Here I think you misunderstood the use of the pattern. The idea is to be able to dynamically control access to an object. For example, you may want class A to be able to access the methods of class B if condition C is not true. As I'm sure you can see that this cannot be achieved with access specifiers.

Smart pointers Here I think you are misunderstanding the need for smart pointers. Since this is a rather complex topic, I'll just post a link to the question about them: RAII and smart pointers in C ++

If you've never programmed in a language like C where you manage your own memory, this might explain the confusion.

Hope this helps answer some of your questions.

EDIT:



I didn’t notice that this was marked as C ++, so I assume that you do acknowledge the need for heap cleanup. A single static reference count will only work if you are only going to have one instance of your object. If you instantiate 2000 object instances and then delete 1999 from them, none of them will free their memory until the last one leaves the scope, which is clearly undesirable (assuming you followed the locations of all allocated memory to free it !).

EDIT 2:

Say you have a class like this:

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, all references to all objects are taken into account in the code recalculation, and this leads to a memory leak. I can explain if you need to, but this is really a separate question.

+3


source


I'm not an expert, but here are my thoughts on Virtual Proxies . If we control initialization through a separate say function bool Create();

, then responsibility and control of initialization rests with the client class. With virtual proxies, the goal is to retain control over creation within the class, without the client being unaware of it.



Protection profiles . A topic that can be protected can have different types of clients, which must get unprotected / unrestricted access to all Themes . > and others that must be allowed access to a subset of the methods, therefore a security proxy is required.

+1


source


A proxy is an object that behaves like another object in order to add some control / behavior. A smart pointer is a good example: it accesses an object as if you were using a raw pointer, but it also controls the lifetime of that object.

0


source


It's good to ask if there are alternatives to standard problem solutions. Design patterns are solutions that have worked for a lot of people, and have the advantage that there is a good chance that an experienced programmer coming to code will recognize the pattern and thus make the code easier to maintain. However, all designs are trade-offs and models have costs. So you are right to challenge the use of templates and consider alternatives.

In many cases, design is not just about creating code, but how it is structured. Which part of the code "knows" what. You are offering an alternative to Prozy virtual moves (as fizzbuzz says) creation knowledge from proxy to client - the client must "know" to call Create (), and therefore is aware of the lifecycle of that class. Whereas with the proxy it just creates an object that it sees as a worker, then invisible creation happens when the proxy decides it makes sense. This refactoring of responsibility in the proxy resource proves to be valuable, it allows us to change these lifecycle rules in the future without changing any clients.

Protective Proxy: Your proposal requires clients to have inheritance relationships in order for them to use protected methods. Generally speaking, the pairs of clients and workers are too dense, so we introduce proxies.

Smart link: no, one static account won't do. You need to count the links to individual instances.

If you work carefully in each case, you will find that there are merits to design patterns. If you try to implement an alternative, you'll start with some code that will simplify the design pattern, and then find that when you refactor and improve the code, removing the spread and so on, you end up reinventing the design pattern - and that's a really nice end result.

0


source







All Articles