**Պրոքսի** (անգլ.՝ Proxy), կառուցվածքային նախագծման ձևանմուշ, որը տրամադրում է մեկ այլ օբյեկտի հասանելիությունը ղեկավորող օբյեկտ։ Այդ օբյեկտը բոլոր կանչերը վերցնում է իր վրա։

Ընդհանուր առմամբ Պրոքսին իրենից ներկայացնում է դասի ինտերֆեյս կամ դրա նման մի բան։ Պրոքսին կարող է ինտերֆեյս ունենալ ամեն ինչին՝ համացանցին, հիշողության մեջ մեծ օբյեկտին, ֆայլին կամ մեկ այլ ռեսուրսի, որը «թանկարժեք» է կամ անհնար է վերարտադրել։

Պրոքսի ձևանմուշի լավ օրինակ է հղումների հաշվումը խելացի ցուցիչ օբյեկտը։

Այն դեպքերում, երբ հարկ է լինում օգտագործել բարդ օբյեկտների կրնօրինակներ, պրոքսի ձևանմուշը կարելի է իրականացնել հարմարեցնող ձևանմուշով, որի միջոցով կարելի է նվազեցնել անհրաժեշտ հիշողության չափը։ Հատկանշական է այն, որ բարդ նմուշի պատճենները և պրոքսիի բազմակի օբյեկտները ստեղծվում են որպես ցուցիչներ մեկ օրիգինալ բարդ օբյեկտի վրա։ Պրոքսիների կողմից իրականացված ցանկացած գործողություն ուղարկվում է օրիգնալ օբյեկտի վրա։ Երբ արդեն պրոքսիի բոլոր նմուշները իրենց աշխատանքն իրականացրել են, բարդ օբյեկտի զբաղեցրած հիշողությունը կարելի է ազատել։

Ընդհանուր հասկացողություններ
----------------------------

* Client - հայցող
* Instance - նմուշ
* Implementation - իրականացում
* Product - արգասիք

Կառուցվածք
----------

Կիրառություն
------------

Պրոքսի ձևանմուշը այլ օբյեկտների համար ինտերֆեյս է տրամադրում դասը՝ որպես պրոքսի ծրարելով (անգլ.՝ wrap)։ Պրոքսի հանդիսացող ծրարված դասի (անգլ.՝ wrapper class) մեջ կարելի է ավելացնել օբյեկտի լրացուցիչ ֆունկցիոնալություն՝ առանց փոփոխություն անելու օբյեկտի կոդում։

Ստորև բերված է տարածված օրինակներ, որտեղ օգտագործվում է պրոքսի ձևանմուշը.

* Գոյություն ունեցող օբյեկտի համար անվտանգության ապահովում։ Պրոքսին կորոշի, թե հայցողը կարող է հասանելիություն ստանալ օբյեկտին, թե՝ ոչ։
* API բարդ օբյեկտների պարզեցում։ Պրոքսին կարող է ավելի պարզ API տրամադրել և հայցողի կոդը այնքան բարդ չի լինի, որքան օբյեկտինը։
* Հեռակա ռեսուրսների համար ինտերֆեյսի տրամադրում։ Օրինակ վեբ ծառայություններ կամ REST ռեսուրսներ։
* Հեռակա ռեսուրսների վրա կիրառվող գործողությունների կոորդինացում, որպեսզի աշխատանքը սկսվի հնարավորնիս շուտ մինչ այն կհասնի ռեսուրսին։
* Հոսքատիպ ֆունկցիաներ ավելանցելով գոյություն ունեցող դասին՝ առանց փոփոխելով գոյություն ունեցող դասը։

Կարճ ասած, պրոքսին հանդիսանում է օբյեկտ, որն հասանելիություն ունի ռեալ օբյեկտին։

Տարատեսակներ
------------

* **Պրոտակոլիզացնող պրոքսի** - լոգի մեջ պահում է «Սուբյեկտի» բոլոր կանչերն իր պարամետրերով
* **Հեռակա փոխարինիչ** (անգլ.՝ remote proxies) - ապահովում է կապ «Սուբյեկտի» հետ, որը գտնվում է մեկ այլ անվատարածքում կամ էլ հեռակա մեքենայում։ Ինչպես նաև կարող է պատասխանատու լինել հարցման և նրա արգումնետների կոդավորման և հարցումը ռեալ «Սուբյեկտին» կոդավորված ձևով ուղարկելով։
* **Վիրտուալ փոխարինիչ** (անգլ.՝ virtual proxies) - ռեալ «Սուբյեկտի» ստեղծումը ապահովում է միայն այն ժամանակ, երբ այն անհրաժեշտ է։ Ինչպես նաև կարող է ռեալ «Սուբյեկտին» ինֆորմացիայի մի մասը քեշավորել, որպեսզի նրա ստեղծումը հետաձգի։
* **Գրելու ժամանակ պատճենում** - ապահովում է «Սուբյեկտի» պատճենումը հայցողի կողմից որոշակի գործողություններ կատարելիս։ Հանդիսանում է «Վիրտուալ պրոքսիի» մասնավոր դեպք։
* **Պաշտպանող փոխարինիչ** (անգլ.՝ protection proxies - կարող է ստուգել, թե կանչված օբյեկտը հարցումը կատարելու իրավունք ունի, թե ոչ։
* **Քեշավորող պրոքսի** - ապահովում է տվյալների ժամանակավոր պահպանում մի քանի հայցողների համար, որոնց համար անհրաժեշտ է այդ ինֆորմացիան։
* **Էկրանավորող պրոքսի** պաշտպանում է «Սուբյեկտին» վտանգավոր հայցողներից (կամ հակառակը)։
* **Սինխրոնիզացնող պրոքսի** - իրականացնում է սինխրոնիզացված հասանելիություն «Սուբյեկտի» նկատմամբ ասինխրոն բազմահոս միջավայրում։
* **«Խելացի» հղում** (անգլ.՝ smart reference proxy) - իրականացնում է լրացուցիչ գործողություններ, երբ «Սուբյեկտի» վրա ստեղծվում է ցուցիչ։ Օրինակ հաշվարկում է «Սուբյեկտի» վրա եղած ակտիվ ցուցիչների քանակը։

Առավելություններ և թերություններ
--------------------------------

### Առավելություններ

* Հեռակա փոխարինիչ
* Վիրտուալ փոխարինիչը կարող է իրականացնել ցանկացած օպտիմիզացիա
* Պաշտպանող փոխարինչ
* «Խելացի» հղում

### Թերություններ

* Արձագանքի ժամանակի կտրուկ մեծացում

Օրինակներ
---------

### C++

```
class ICar {
public:
 virtual void DriveCar() = 0;
};

class Car : public ICar {
public:
 Car(int driver\_age, ICar\* pCar) : \_pImpl(pCar), \_driver\_age(driver\_age) {}

 void DriveCar() { 
 if (\_driver\_age >= 16)
 \_pImpl->DriveCar();
 }

private:
 ICar\* \_pImpl;
 int \_driver\_age;
};

```

### C#

```
//IVSR: Proxy Design pattern

namespace IVSR.DesignPattern.Proxy
{
 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;
 realCar = new Car();
 }

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

 public class Driver
 {
 public 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!
```

Նոթեր. 

* Պրոքսին կարող է թաքցնել ռեալ օբյեկտի մասին տեղեկությունը հայցողից։
* Պրոքսին կարող է օպտիմիզացումներ անել՝ օրինակ թեթևացնել ծանրաբեռնվածությունը
* Պրոքսի ձևանմուշը հայտնի է նաև որպես նախագծման սուռագատային ձևանմուշ

### Java

```
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(String[] args) {
 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
```

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * դ
* ք
* խ
Նախագծման ձևանմուշներ |
| --- |
|  |
| ԳօՖիձևանմուշներ | 

|  |  |
| --- | --- |
| Ստեղծող | Աբստրակտ ֆաբրիկա • Կառուցող • Ֆաբրիկային մեթոդ • Նախատիպ • Եզակի օգտագործման |
| Կառուցվածքային | Ադապտեր • Կամուրջ • Կազմող • Դեկորատոր • Ճակատ • Հարմարեցնող • Պրոքսի |
| Վարքագծային | Պարտականությունների շղթա • Հրաման • Թարգմանիչ • Իտերատոր • Միջնորդ • Պահպանող • Դիտորդ • Վիճակ • Մարտավարություն • Կաղապարային մեթոդ • Այցելող |

 |
|  |
| Ստեղծող ձևանմուշներ | Ծույլ բեռնում • Բազմակի օգտագործման • Օբյեկտների ավազան • Ռեսուրսի ստանալը ինիցիալիզացիա է |
|  |
| Կառուցվածքային ձևանմուշներ | Ճակատը հսկող • Մոդուլ |
|  |
| Համաձայնեցման ձևանմուշներ | Ակտիվ օբյեկտ • Հենվող • Մեկուսացում կրկնակի ստուգումով • Ասինքրոն կանչի մեթոդ • Պահպանվող կախոց • Ռեգիստրացնող • Կողպեքավորող • Մոնիտոր • Նախագործող • Ապագործող • Ընթերցողներ-գրողի կողպեք • Պլանավորման • Հոսքերի ավազանի • Հոսքերի լոկալ հիշողություն |
|  |
| Ճարտարապետական ձևանմուշներ | Ճակատը հսկող ձևանմուշ • Զավթող ձևանմուշ • ձևանմուշի ներկայացման վերահսկում • Բազմաշերտ • Հատկորոշում • Հրատարակող-ստորագրող • Մերկ օբյեկտներ • Ծառայության լոկատոր • Ակտիվ գրառման • Բազմության իդենտիֆիկացման • Data access object • Data transfer object |
|  |
| Այլ ձևանմուշներ | Կախվածության ներդնում • Mock օբյեկտ • Զրոյական օբյեկտ • Ծառայող • Թունելային տարատեսակի |

 |