الگوی وکالت

الگوی وکالت در برنامه‌نویسی، از جمله الگوهای طراحی نرم‌افزار است.
وکیل، در کلی‌ترین حالت، کلاس واسطه‌ای برای انجام کار دیگری است. پروکسی می‌تواند رابط هر چیزی باشد: یک ارتباطه تحت شبکه، شیء بزرگی در داخل حافظه، یک فایل، یا یک سری از منابع دیگر که نمونه‌سازی از آن‌ها بسیار سخت یا غیرممکن است. به صورت خلاصه، وکیل پوشه‌بند یا نیروی اجرایی‌ای است که توسط مشتری صدا زده می‌شود تا به شیء اصلی در پشت‌پرده دسترسی پیدا کند. استفاده از وکیل می‌تواند انتقال به شی واقعی را راحت‌تر کند یا روش‌های دیگری برای آن به وجود بیاورد. در الگوی وکالت قابلیت‌های اضافه‌تر می‌تواند به وجود بیاید، به‌طور مثال، استفاده از حافظه موقت، برای وقتی که استفاده از شیء اصلی هزینه پردازشی و هزینه دسترسی به حافظه زیادی داشته باشد، یا در چک کردن شرایط اولیه قبل از آن که عملیات بر روی شیء اصلی اعمال شود. برای مشتری با استفاده از وکیل مانند استفاده از شیء اصلی است، چرا که رابط هر دو مشابه است.

وکالت از راه دور

در ارتباطات اشیاء توزیع شده، از یک شیء محلی به عنوان نمایش‌دهنده شیء خارجی (که متعلق به یک فضای خارجی از آدرس‌دهی‌ها است) است. شیء محلی به عنوان وکیل شیء خارجی شناخته می‌شود، و اجرای توابع شیء محلی به اجرای توابع در شیء اصلی می‌انجامد. به عنوان مثال: دستگاه خودپرداز، که در آن یک وکیل از اطلاعات بانکی در سرور خارجی وجود دارد.

وکالت مجازی

در مواجهه به شیء پیچیده یا سنگین وزن (از نظر حافظه)، در بعضی موارد نشان دادن تنها بدنه‌ای از شیء می‌تواند مفیدتر باشد. وقتی که تصویر ایجاد شده اندازه بزرگی داشته باشد، می‌تواند توسط یک وکیل مجازی، که بر روی شیء واقعی پیاده‌سازی شده، نشان داده شود.

وکالت امنیتی

برای محافظت از کنترل دسترسی‌ها می‌توان این وظیفه را به یک وکیل سپرد.

C++

class ICar {public:
  virtual void DriveCar() = 0;};class Car : public ICar {
  void DriveCar() override {
    std::cout <<"Car has been driven!";
  }};class ProxyCar : public ICar {private:
  ICar* realCar = new Car();
  int _driver_age;public:
  ProxyCar (const int driver_age) : _driver_age(driver_age) {}

  void DriveCar() {
    if (_driver_age> 16)
      realCar->DriveCar();
    else
      std::cout <<"Sorry, the driver is too young to drive.";
  }};// How to use above Proxy class?void main(){
    ICar* car = new ProxyCar(16);

    car->DriveCar();

    delete car;

    car = new ProxyCar(25);

    car->DriveCar();

    delete car;}

کریستال

abstract class AbstractCar
  abstract def driveendclass Car <AbstractCar
  def drive
    puts "Car has been driven!"
  endendclass Driver
  getter age : Int32

  def initialize(@age)
  endendclass ProxyCar <AbstractCar
  private getter driver : Driver
  private getter real_car : AbstractCar

  def initialize(@driver)
    @real_car = Car.new
  end

  def drive
    if driver.age <= 16
      puts "Sorry, the driver is too young to drive."
    else
      @real_car.drive
    end
  endend# Programdriver = Driver.new(16)car = ProxyCar.new(driver)car.drivedriver = Driver.new(25)car = ProxyCar.new(driver)car.drive
خروجی
Sorry, the driver is too young to drive.
Car has been driven!

Delphi / Object Pascal

// Proxy Design patternunit DesignPattern.Proxy;interfacetype
    // Car Interface
    ICar = interface
      procedure DriveCar;
    end;

    // TCar class, implementing ICar
    TCar = Class(TInterfacedObject, ICar)
      class function New: ICar;
      procedure DriveCar;
    End;

    // Driver Interface
    IDriver = interface
      function Age: Integer;
    end;

    // TDriver Class, implementing IDriver
    TDriver = Class(TInterfacedObject, IDriver)
    private
      FAge: Integer;
    public
      constructor Create(Age: Integer); Overload;
      class function New(Age: Integer): IDriver;
      function Age: Integer;
    End;

    // Proxy Object
    TProxyCar = Class(TInterfacedObject, ICar)
    private
      FDriver: IDriver;
      FRealCar: ICar;
    public
      constructor Create(Driver: IDriver); Overload;
      class function New(Driver: IDriver): ICar;
      procedure DriveCar;
    End;implementation{ TCar Implementation }class function TCar.New: ICar;begin
     Result := Create;end;procedure TCar.DriveCar;begin
     WriteLn('Car has been driven!');end;{ TDriver Implementation }constructor TDriver.Create(Age: Integer);begin
     inherited Create;
     FAge := Age;end;class function TDriver.New(Age: Integer): IDriver;begin
     Result := Create(Age);end;function TDriver.Age: Integer;begin
     Result := FAge;end;{ TProxyCar Implementation }constructor TProxyCar.Create(Driver: IDriver);begin
     inherited Create;
     Self.FDriver  := Driver;
     Self.FRealCar := TCar.Create AS ICar;end;class function TProxyCar.New(Driver: IDriver): ICar;begin
     Result := Create(Driver);end;procedure TProxyCar.DriveCar;begin
     if (FDriver.Age <= 16)
        then WriteLn('Sorry, the driver is too young to drive.')
        else FRealCar.DriveCar();end;end.
استفاده
program Project1;
{$APPTYPE Console}
uses
    DesignPattern.Proxy in 'DesignPattern.Proxy.pas';
begin
     TProxyCar.New(TDriver.New(16)).DriveCar;
     TProxyCar.New(TDriver.New(25)).DriveCar;
end.

جاوا

این کد Java یک نمونه از «وکالت مجازی» را به نمایش می‌گذارد. کلاس ProxyImage برای دسترسی به کنترل از راه دور استفاده می‌شود.
مثال به جای آن که ابتدا کلاس را بسازد ابتدا یک رابط به نام displayImage ساخته است که توسط تمامی کلاس‌هایی که آن را پیاده می‌کنند نوشته می‌شود.

کلاس وکالت ProxyImage بر روی سامانه دیگری اجرا می‌شود و تصویر اصلی RealImage را در آن‌جا نمایش می‌دهد. اطلاعات تصویر از روی حافظه دسترسی پیدا می‌کنند. با استفاده از الگوی وکالت، کد ProxyImage جلوی دسترسی‌های متعدد به تصویر را می‌گیرد و دسترسی به آن از سامانه دیگر موجب بهینه سازی در استفاده از حافظه خواهد بود. لازم به ذکر است که هرچند فراخوانی کاهلانه‌ای که در این مثال نمایش داده شده جزو الگوی وکالت اصلی نیست، در حقیقت یک ویژگی پیشرفته‌تر است که توسط الگوی وکالت امکان‌پذیر شده‌است.
interface Image {
    public void displayImage();}// On System Aclass RealImage implements Image {

    private String filename = null;
    /**     * Constructor     * @param filename     */
    public RealImage(final String filename) {
        this.filename = filename;
        loadImageFromDisk();
    }

    /**     * Loads the image from the disk     */
    private void loadImageFromDisk() {
        System.out.println("Loading   " + filename);
    }

    /**     * Displays the image     */
    public void displayImage() {
        System.out.println("Displaying " + filename);
    }}// On System Bclass ProxyImage implements Image {

    private RealImage image = null;
    private String filename = null;
    /**     * Constructor     * @param filename     */
    public ProxyImage(final String filename) {
        this.filename = filename;
    }

    /**     * Displays the image     */
    public void displayImage() {
        if (image == null) {
           image = new RealImage(filename);
        }
        image.displayImage();
    }}class ProxyExample {

   /**    * Test method    */
   public static void main(final String[] arguments) {
        final Image image1 = new ProxyImage("HiRes_10MB_Photo1");
        final Image image2 = new ProxyImage("HiRes_10MB_Photo2");

        image1.displayImage(); // loading necessary
        image1.displayImage(); // loading unnecessary
        image2.displayImage(); // loading necessary
        image2.displayImage(); // loading unnecessary
        image1.displayImage(); // loading unnecessary
    }}
خروجی برنامه:
Loading   HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo1
Loading   HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo1