پروکسی در UML
پروکسی در LePUS3 (افسانه)
**الگوی وکالت** در برنامه‌نویسی، از جمله الگوهای طراحی نرم‌افزار است.

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

سناریوهای احتمالی استفاده
-------------------------

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

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

### وکالت مجازی

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

### وکالت امنیتی

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

مثال
----

### #C

```
interface ICar
{
 void DriveCar();
}

// Real Object
public class Car : ICar
{
 public void DriveCar()
 {
 Console.WriteLine("Car has been driven!");
 }
}

//Proxy Object
public class ProxyCar : ICar
{
 private Driver driver;
 private ICar realCar;

 public ProxyCar(Driver driver)
 {
 this.driver = driver;
 this.realCar = new Car();
 }

 public void DriveCar()
 {
 if (driver.Age <= 16)
 Console.WriteLine("Sorry, the driver is too young to drive.");
 else
 this.realCar.DriveCar();
 }
}

public class Driver
{
 private int Age { get; set; }

 public Driver(int age)
 {
 this.Age = age;
 }
}

// How to use above Proxy class?
private void btnProxy\_Click(object sender, EventArgs e)
{
 ICar car = new ProxyCar(new Driver(16));
 car.DriveCar();

 car = new ProxyCar(new Driver(25));
 car.DriveCar();
}

```
خروجی

```
Sorry, the driver is too young to drive.
Car has been driven!

```
یادداشت:

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

### ++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 drive
end

class Car <AbstractCar
 def drive
 puts "Car has been driven!"
 end
end

class Driver
 getter age : Int32

 def initialize(@age)
 end
end

class 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
 end
end
# Program
driver = Driver.new(16)
car = ProxyCar.new(driver)
car.drive

driver = 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 pattern
unit DesignPattern.Proxy;

interface

type
 // 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 A
class 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 B
class 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

```

جستارهای وابسته
---------------

* الگوهای طراحی نرم‌افزار
* الگوی دکوراتور
* مقداردهی اولیه کاهلانه

منابع
-----

پیوند به بیرون
--------------

* الگوی وکالت در UML و در LePUS3 (زبان مدل‌سازی فرمال)
* توسط الگوی وکالت کنترل را در دست بگیرید توسط David Geary JavaWorld.com
* پروژه منبع باز PerfectJPattern، پیاده‌سازی الگوی وکالت را به صورت پوشه بندی شده در در جاوا را امکان‌پذیر می‌کند.
* مقایسه الگوهای آداپتور، وکالت و نما
* الگوهای طراحی پروکسی
* الگوهای پیاده‌سازی وکالت در C++ با مثال
* توضیح الگوی وکالت از تاریخچه الگوهای پورتلند

| * ن
* ب
* و
الگوهای طراحی |
| --- |
| الگوهای طراحی GO4 | 

|  |  |
| --- | --- |
| ایجاد | 
* الگوی کارخانه انتزاعی
* الگوی سازنده
* الگوی متد کارخانه شیء
* الگوی نمونه اولیه
* الگوی یگانه

 |
| ساختاری | 
* آداپتور
* پل
* کامپوزیت
* آذینگر
* نما
* مگس وزن
* وکالت

 |
| رفتاری | 
* زنجیره مسئولیت
* الگوی فرمان
* مفسر
* الگوی تکرار
* میانجی
* یادگاری
* ناظر
* وضعیت
* استراتژی
* متد الگو
* بازدیدگر

 |

 |
| Concurrencypatterns | 
* Active object
* Balking
* Binding properties
* Double-checked locking
* Event-based asynchronous
* Guarded suspension
* Join
* قفل
* مانیتور
* Proactor
* Reactor
* Read write lock
* زمان‌بندی
* الگوی مخزن نخ
* Thread-local storage

 |
| الگوهایمعماری | 
* Front controller
* مفسر
* مدل-نما-کنترل‌گر
* ADR
* Entity-component-system
* چندلایه
* Specification
* Publish–subscribe
* اشیای لخت
* Service locator
* ثبت کنشور
* Identity map
* شی دسترسی به داده
* شی انتقال داده
* وارونگی کنترل
* Model 2

 |
| دیگرالگوها | 
* Blackboard
* Business delegate
* Composite entity
* تزریق نیازمندی
* Intercepting filter
* بارگیری تنبلانه
* شیء ساختگی
* Null object
* استخر اشیاء
* Servant
* Twin
* Type tunnel
* Method chaining

 |
| کتاب‌ها | 
* *الگوهای طراحی*
* *Enterprise Integration Patterns*
* *Patterns of Enterprise Application Architecture*
* *Analysis patterns*

 |
| افراد | 
* کریستوفر الکساندر
* Erich Gamma
* Ralph Johnson
* John Vlissides
* گریدی بوچ
* کنت بک
* وارد کانینگهام
* مارتین فولر
* رابرت سسیل مارتین
* Jim Coplien
* Douglas Schmidt
* Linda Rising

 |
| جوامع | 
* The Hillside Group
* The Portland Pattern Repository

 |