Proxy pattern

From Wikipedia, the free encyclopedia

Contents

In computer programming, the proxy pattern is a software design pattern.

A proxy, in its most general form, is a class functioning as an interface to another thing. The other thing could be anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.

A well-known example of the proxy pattern is a reference counting pointer object, also known as an "auto pointer". (See [auto_ptr]] for the C++ standard library's version of this pattern.)

The proxy pattern can be used in situations where multiple copies of a complex object must exist. In order to reduce the application's memory footprint in such situations, one instance of the complex object is created, and multiple proxy objects are created, all of which contain a reference to the single original complex object. Any operations performed on the proxies are forwarded to the original object. Once all instances of the proxy are out of scope, the complex object's memory may be deallocated.

Types of proxy pattern include:

  • Remote proxy: Provides a reference to an object located in a different address space on the same or different machine.
  • Virtual proxy: Allows the creation of a memory intensive object on demand. The object will not be created until it is really needed. (See also Lazy evaluation.)
  • Copy-on-write proxy: Defers copying (cloning) a target object until required by client actions. This is really a special case of the "virtual proxy" pattern.
  • Protection (access) proxy: Provides different clients with different levels of access to a target object.
  • Cache proxy: Provides temporary storage of the results of expensive target operations so that multiple clients can share the results. (See also Memoization.)
  • Firewall proxy: Protects targets from bad clients (or vice versa).
  • Synchronization proxy: Provides concurrency control over an unsynchronized target object.
  • Smart reference proxy: Provides additional actions whenever a target object is referenced, such as counting the number of references to the object.

[edit] Examples

[edit] Virtual proxy (in Java)

The following Java example illustrates the "virtual proxy" pattern. The program's output is:

Loading    HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo1
Loading    HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo1

The ProxyImage class is used to delay the expensive operation of loading a file from disk until the result of that operation is actually needed. If the file is never needed, then the expensive load has been totally eliminated.

import java.util.*;

interface Image {
   public void displayImage();
}

class RealImage implements Image {
   private String filename;
   public RealImage(String filename) { 
       this.filename = filename;        
       System.out.println("Loading   "+filename);
   }
   public void displayImage() { System.out.println("Displaying "+filename); }
}

class ProxyImage implements Image {
   private String filename;
   private RealImage image;

   public ProxyImage(String filename) { this.filename = filename; }
   public void displayImage() {
       if (image == null) {
           image = new RealImage(filename); // load only on demand
       }
       image.displayImage();
   }
}

class ProxyExample {
   public static void main(String[] args) {
       List<Image> images = new ArrayList<Image>();
       images.add( new ProxyImage("HiRes_10MB_Photo1") );
       images.add( new ProxyImage("HiRes_10MB_Photo2") );
       images.add( new ProxyImage("HiRes_10MB_Photo3") );

       images.get(0).displayImage(); // loading necessary
       images.get(1).displayImage(); // loading necessary
       images.get(0).displayImage(); // no loading necessary; already done 
       // the third image will never be loaded - time saved!
   }
}

[edit] Protection proxy (in C#)

In this C# example, the RealClient stores an account number. Only users who know a valid password can access this account number. The RealClient is protected by a ProtectionProxy which knows the password. If a user wants to get an account number, first the proxy asks the user to authenticate; only if the user entered a correct password does the proxy invoke the RealClient to get an account number for the user.

using System;

namespace ConsoleApplicationTest.FundamentalPatterns.ProtectionProxyPattern
{
   public interface IClient{
       string GetAccountNo();
   }

   public class RealClient : IClient{
       private string accountNo="AB-111111";
       public RealClient(){
           Console.WriteLine("RealClient: Initialized");
       }
       public string GetAccountNo(){
           Console.WriteLine("RealClient's AccountNo: " + accountNo);
           return accountNo;
       }
   }


   public class ProtectionProxy : IClient 
   {
       private string password=null;  //password to get secret
       RealClient client=null;

       public ProtectionProxy(string pwd)
       {
           Console.WriteLine("ProtectionProxy: Initialized");
           password=pwd;
           client=new RealClient();
       }

       /// <summary>
       /// Authenticate the user and return the Account Number
       /// </summary>
       /// <returns></returns>
       public String GetAccountNo()
       {
           Console.WriteLine("Password: ");
           string tmpPwd= Console.ReadLine();

           if(tmpPwd == password)
           {
               return client.GetAccountNo();
           }
           else
           {
               Console.WriteLine("ProtectionProxy: Illegal password!");
               return "";
           }
       }
   }
    
   class ProtectionProxyExample 
   {
       [STAThread]
       public static void Main(string[] args){

           IClient client =new ProtectionProxy("thePassword");
           Console.WriteLine("main received: "+client.GetAccountNo());        
           Console.WriteLine("main received: "+client.GetAccountNo());        

           Console.Read();
       }
   }
}

[edit] See also

[edit] External links