代理模式

代理模式（）是程式设计中的一种设计模式。所谓的代理者是指一个类别可以作为其它东西的介面。代理者可以作任何东西的介面：网路连接、记忆体中的大物件、档案或其它昂贵或无法复制的资源。
概述.
著名的代理模式例子为参照计数（）指标物件。当一个复杂物件的多份副本须存在时，代理模式可以结合享元模式以减少记忆体用量。典型作法是建立一个复杂物件及多个代理者，每个代理者会参照到原本的复杂物件。而作用在代理者的运算会转送到原本物件。一旦所有的代理者都不存在时，复杂物件会被移除。
结构.
在上面的UML类图中，codice_1类实现了codice_2接口，使它充当codice_2对象的代替者。它维护一个引用（codice_4）至被代替的对象（codice_5），使其可以转发给它（codice_6）。 
序列图展示了运行时交互：The codice_7对象通过合作于codice_1对象，来控制到codice_5对象的访问。在这个例子中，codice_1转发请求至codice_5，它办理这个请求。
示例.
Java.
以下Java范例解释"虚拟代理"模式。codice_12 类别用来存取远端方法。
import java.util.*;
interface Image {
 public void displayImage();
//on System A 
class RealImage implements Image {
 private String filename;
 public RealImage(String filename) { 
 this.filename = filename;
 loadImageFromDisk();
 private void loadImageFromDisk() {
 System.out.println("Loading " + filename);
 public void displayImage() { 
 System.out.println("Displaying " + filename); 
//on System B 
class ProxyImage implements Image {
 private String filename;
 private Image image;
 public ProxyImage(String filename) { 
 this.filename = filename; 
 public void displayImage() {
 if(image == null)
 image = new RealImage(filename);
 image.displayImage();
class ProxyExample {
 public static void main(String[] args) {
 Image image1 = new ProxyImage("HiRes_10MB_Photo1");
 Image image2 = new ProxyImage("HiRes_10MB_Photo2"); 
 image1.displayImage(); // loading necessary
 image2.displayImage(); // loading necessary
程式的输出为：
 Loading HiRes_10MB_Photo1
 Displaying HiRes_10MB_Photo1
 Loading HiRes_10MB_Photo2
 Displaying HiRes_10MB_Photo2
C#.
C#的例子：
using System;
namespace Proxy {
 interface IImage {
 void Display();
 class RealImage : IImage {
 public RealImage(string fileName) {
 FileName = fileName;
 LoadFromFile();
 private void LoadFromFile() {
 Console.WriteLine("Loading " + FileName);
 public void Display() {
 Console.WriteLine("Displaying " + FileName);
 class ProxyImage : IImage {
 public ProxyImage(string fileName) {
 FileName = fileName;
 private IImage image;
 public void Display() {
 if (image == null)
 image = new RealImage(FileName);
 image.Display();
 class Program {
 static void Main(string[] args) {
 IImage image = new ProxyImage("HiRes_Image");
 for (int i = 0; i &lt; 10; i++)
 image.Display();
程式的输出为：
 Loading HiRes_Image
 Displaying HiRes_Image
 Displaying HiRes_Image
 Displaying HiRes_Image
 Displaying HiRes_Image
 Displaying HiRes_Image
 Displaying HiRes_Image
 Displaying HiRes_Image
 Displaying HiRes_Image
 Displaying HiRes_Image
 Displaying HiRes_Image
Python.
下面是Python的例子：
from abc import ABC, abstractmethod
class Image(ABC):
 @abstractmethod
 def display(self): pass
class RealImage(Image):
 def __init__(self, filename):
 self.filename = filename
 self.load_from_disk()
 def load_from_disk(self):
 print("Loading ", self.filename)
 def display(self):
 print("Displaying ", self.filename)
class ProxyImage(Image):
 def __init__(self, filename):
 self.filename = filename
 self.image = None
 def display(self):
 if self.image is None:
 self.image = RealImage(self.filename)
 self.image.display()
def example():
 image1 = ProxyImage("HiRes_10MB_Photo1")
 image2 = ProxyImage("HiRes_10MB_Photo2")
 image1.display()
 image2.display()
 image1.display()
 image2.display()
其执行：
»&gt; example()
Loading HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo1
Loading HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo2