thumb|400px|Helyettes UML-ben thumb|300px|Helyettes LePUS3-ban (legend)

A számítástudományban a helyettes minta vagy helyettesítő minta egy programtervezési minta.

Egy helyettes a legáltalánosabb formájában egy olyan osztály funkcionalitása, amely egy interfész valami máshoz. A helyettes interfészként tud viselkedni valamihez: egy hálózati kapcsolathoz, egy nagy objektumhoz a memóriában, egy fájlhoz vagy számos más erőforráshoz, amely költséges vagy lehetetlen duplikálni.

A helyettes programtervezési mintára egy jól ismert példa egy referencia számláló mutató objektum.

Olyan esetekben, ahol egy összetett objektum több példányának kell léteznie, a helyettesítő minta adaptálható a pehelysúlyú mintára, azért hogy csökkentse az alkalmazás memóriában elfoglalt méretét. Tipikus módon az összetett objektumból 1 példány és sok helyettes objektum készül, melyek tartalmaznak az egy darab eredeti összetett objektumra mutató referenciát. Bármilyen művelet végrehajtása a helyettesítőkön az eredeti objektumnak való továbbítást jelent. Amint az összes helyettes példány érvényessége megszűnik, az összetett objektum tárhelye felszabadíthatóvá válik. Használata A helyettes megvalósítja az eredeti objektum interfészét. Információkat rejthet el, kérésre végezhet optimalizációt vagy betöltést. Elláthat további feladatokat is, mint auditálás vagy naplózás.

A védelmi helyettes ellenőrzi a hozzáférést, és csak megfelelő jogosultság esetén engedélyezi.

A virtuális helyettes egy erőforrás-igényes objektumot helyettesít, és csak akkor tölti be, ha tényleg szükség van az eredeti objektumra.

A távoli helyettes egy távoli objektumot reprezentál helyben, és ha metódushívás történik, akkor továbbítja a távoli objektumnak. Például az ATM automaták így állnak kapcsolatban a bankkal.

A helyettes tesztelési célra is használható, ekkor fake, stub vagy mock objektum a neve.

Példák A következő Java példa a "virtuális helyettes" mintát szemlélteti. A ProxyImage osztály használható egy távoli metódus eléréséhez.

A példa először létrehoz egy interfészt, amihez a minta szerint létrehozzuk a megvalósító osztályokat. Ez az interfész csak egy metódust tartalmaz, amely megjeleníti a képet (displayImage()), és ezt kell lekódolni az összes osztálynak, amely azt megvalósítja.

A helyettes osztály a ProxyImage egy másik rendszerben fut, mint a valódi kép osztály maga és reprezentálja a valódi osztályt RealImage a felett. A kép információk elérhetők a lemezről. A helyettes minta használatával a ProxyImage kódja elkerüli a kép többszöri betöltését, elérhetővé téve azt egy másik rendszerből memóriatakarékos módon.

interface Image { public void displayImage(); }

//on System A class RealImage implements Image {

private String filename = null; /** * Constructor * @param FILENAME */ public RealImage(final String FILENAME) { 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) { 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

A program kimenete: 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

C# A következő C# és C++ példa a védelmi helyettest szimulálja.

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(); } Kimenet: 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!" << std::endl;

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." << std::endl;

// 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; }

Kapcsolódó szócikkek Összetétel programtervezési minta Díszítő programtervezési minta Lusta inicializálás

Jegyzetek

További információk

Helyettes minta UML-ben és LePUS3-ban (egy formális modellező nyelv) Take control with the Proxy design pattern by David Geary, JavaWorld.com PerfectJPattern Open Source Project, Provides componentized implementation of the Proxy Pattern in Java Adapter vs. Proxy vs. Facade minta összehasonlítása Helyettes tervezési minta Proxy pattern description from the Portland Pattern Repository

Fordítás

Kategória:Programtervezési minták Kategória:Java-kódpéldák Kategória:C Sharp-kódpéldák