Helyettes programtervezési minta
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
Ez a szócikk részben vagy egészben a Proxy pattern című angol Wikipédia-szócikk ezen változatának fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.
- Informatikai portál • összefoglaló, színes tartalomajánló lap