Question

I was reading about Proxy on DoFactory and Wikipedia, and Stack Overflow, of course. Everything is clear, except Real Subject. On DoFactory, Proxy is defined as:

Provide a surrogate or placeholder for another object to control access to it. (added bold font)

If its purpose is to control access to Real Subject, why Real Subject is not hidden from the Client ?

Here is a UML Diagram of Proxy:

Proxy UML

In code example, Real Subject is defined as:

class RealSubject : Subject
{
    ...
}

Client creates an instance of Proxy and "controls access" to Real Subject through it:

Proxy proxy = new Proxy();
proxy.Request();

But (from several example that I saw) there is nothing that stops Client from instantiating Real Subject and accessing its methods. I would like to know why is that?

Was it helpful?

Solution

You could certainly implement the Proxy pattern so that RealSubject is invisible to Client. Indeed, if every client is expected to use only the proxy, that would be a good OO approach.

On the other hand, a proxy is typically used to increase efficiency or security, or to add functionality such as lazy loading. If there are many clients, some of them may not need what the proxy adds, and will use RealSubject directly.

In the case of a library API, RealSubject might be exposed (public) to allow any client to implement its own proxy. RealSubject is then visible to the client, even though the client only uses its proxy.

Another scenario is that Proxy may only provide a partial interface to RealSubject. Take the example of a protection proxy that controls access to RealSubject. After the client is authenticated, it may be allowed direct access to RealSubject, and the proxy can be disposed of.

As you can see, the value of a proxy often depends on the client(s) involved. Some clients may use it exclusively, in which case RealSubject can be hidden. Other clients may use it temporarily, while other clients may not use it at all.

OTHER TIPS

I'll give you an example that i suppose will help you get the purpose/power of a proxy and try to show the meaning of controlling access to an object.

Assume I have a store DataStore of objects (or entities) implementing a given interface IModel.

My contracts are as follows:

public interface IDataStore(){

   // Return a given model by its id
   public IModel getModelById(Long ID);

   // Return the set of models that were modified by DataStore Clients.
   public Collection<IModel> getModifiedModels();
}

The second method contract is is a bit sophisticated and can be cumbersome to solve. A (sophisticated) solution would be to keep a copy of each IModel returned, then make a comparison between the original elements. Using the proxy pattern, our DataStore can fulfill his contract in an elegant way : when queried about a model with a given id, he'll actually returns to you a proxy that notifies back the data store of any modification.

For illustration purpose, here is how should look like the solustion to the contract:

// The following is equivalent to "Subject" using your nomenclature
public interface IModel{

   public Long getId()
   public void setId(Long id);
}

// The following is equivalent to the "RealSubject"
public class RealModel implements IModel{

   Long id;
   public void getId(){
      return id;
   }
   public void setId(Long newid){
      this.id = newid;
   }
}

and finally here is our proxy :

public class ModelProxy extends RealModel implements IModel{

   IModel proxiedModel;
   DataStore datastore;//our datastore

   public ModelProxy(IModel model, DataStore ds){
       proxiedModel=model;
       datastore = ds;
   }

   public void setId(Long newid){

      datastore.addModified(this);
      //  (Assume the DataStore implementation has the addModified method)
      //  The more important here is that we are really "controlling access" to 
      //  our model : before allowing client to modify the id, we're
      //  notifying the store of the modification, and the client hasn't to know about 
      //  that as he's only aware of the IModel interface contract.
      this.id = newid;


   }

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top