In informatica, il proxy pattern è un design pattern.

Nella sua forma più generale, un proxy è una classe che funziona come interfaccia per qualcos'altro. L'altro potrebbe essere qualunque cosa: una connessione di rete, un grosso oggetto in memoria, un file e altre risorse che sono costose o impossibili da duplicare.

Un esempio ben conosciuto di proxy pattern è la tecnica reference counting dei puntatori.

Nelle situazioni in cui molte copie di un oggetto complesso devono esistere, il proxy pattern può essere adottato per incorporare il Flyweight pattern per ridurre l'occupazione di memoria dell'oggetto. Tipicamente viene creata un'istanza di oggetto complesso, e molteplici oggetti proxy, ognuno dei quali contiene un riferimento al singolo oggetto complesso. Ogni operazione svolta sui proxy viene trasmessa all'oggetto originale. Una volta che tutte le istanze del proxy sono distrutte, l'oggetto in memoria può essere deallocato.

Diagramma

modifica

Esempi

modifica

Virtual proxy (in Java)

modifica

Il seguente esempio Java illustra il pattern "virtual proxy". L'output del programma è:

Loading    HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo1
Loading    HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo2
Loading    HiRes_10MB_Photo3
Displaying HiRes_10MB_Photo3

La classe ProxyImage è utilizzata per ritardare l'operazione (onerosa) di caricamento di un file dal disco finché il risultato di questa operazione non è effettivamente necessario. Se il file non è mai necessario, il caricamento risulta essere completamente eliminato.

import java.util.*;
 
interface Image {
    public void displayImage();
}
 
class RealImage implements Image {
    private String filename;
    public RealImage(String filename) { 
        this.filename = filename;
        loadImageFromDisk();
    }

    private void loadImageFromDisk() {
        // Potentially expensive operation
        // ...
        System.out.println("Loading   "+filename);

    	try {
    		Thread.sleep(5000);
    	} catch (InterruptedException e) {
    		e.printStackTrace();
    	}
    }

    public void displayImage() { System.out.println("Displaying "+filename); }
}
 
class ProxyImage implements Image {
    private String filename;
    private RealImage image;
 
    public ProxyImage(String filename) { this.filename = filename; }
    public void displayImage() {
        if (image == null) {
            image = new RealImage(filename); // load only on demand
        }
        image.displayImage();
    }
}
 
class ProxyExample {
    public static void main(String[] args) {
        Image image1 = new ProxyImage("HiRes_10MB_Photo1");
        Image image2 = new ProxyImage("HiRes_10MB_Photo2");   
        Image image3 = new ProxyImage("HiRes_10MB_Photo3");

        image1.displayImage(); // loading necessary
        image2.displayImage(); // loading necessary
        image1.displayImage(); // no loading necessary; already done
        image2.displayImage(); // no loading necessary; already done
        image3.displayImage(); // loading necessary
    }
}

Protection proxy

modifica

In questo esempio scritto in C#, nella classe RealClient è memorizzato un numero di conto. Soltanto gli utenti che conoscono una password valida possono accedere a questo conto. Il RealClient è protetto dal ProtectionProxy che conosce la password. Prima di far leggere il numero di conto all'utente, il proxy richiede che questi si autentichi; Solo se la password introdotta è corretta il proxy invoca il RealClient per restituire il numero di conto all'utente.

In questo esempio thePassword è la password corretta

using System;

namespace ConsoleApplicationTest.FundamentalPatterns.ProtectionProxyPattern
{
    public interface IClient {
        string GetAccountNo();
    }
 
    public class RealClient : IClient {
        private string accountNo = "12345";
        public RealClient() {
            Console.WriteLine("RealClient: Initialized");
        }
        public string GetAccountNo() {
            Console.WriteLine("RealClient's AccountNo: " + accountNo);
            return accountNo;
        }
    }

    public class ProtectionProxy : IClient
    {
        private string password;  //password to get secret
        RealClient client;
 
        public ProtectionProxy(string pwd) {
            Console.WriteLine("ProtectionProxy: Initialized");
            password = pwd;
            client = new RealClient();
        }
 
        // Authenticate the user and return the Account Number
        public String GetAccountNo() {
            Console.Write("Password: ");
            string tmpPwd = Console.ReadLine();
 
            if (tmpPwd == password) {
                return client.GetAccountNo();
            } else {
                Console.WriteLine("ProtectionProxy: Illegal password!");
                return "";
            }
        }
    }
     
    class ProtectionProxyExample
    {
        [STAThread]
        public static void Main(string[] args) {
            IClient client = new ProtectionProxy("thePassword");
            Console.WriteLine();
            Console.WriteLine("main received: " + client.GetAccountNo());
            Console.WriteLine("\nPress any key to continue . . .");
            Console.Read();
        }
    }
}

Segue lo stesso esempio implementato in Java, in questo caso le implementazioni dell'interfaccia Client sono RealClientImpl e ProtectionProxyClientImpl .

package fundamentalPatterns.protectionProxyPattern;

import java.util.Scanner;

public interface Client {
    String getAccountNo();
}
 
public class RealClientImpl implements Client {
    private String accountNo = "12345";
    public RealClientImpl() {
        System.out.println("RealClient: Initialized");
    }
    @Override
    public String getAccountNo() {
        System.out.println("RealClient's AccountNo: " + accountNo);
        return accountNo;
    }
}

public class ProtectionProxyClientImpl implements Client {
    private String password;  //password to get secret
    private Client client;
    private Scanner scanner = new Scanner(System.in);

    public ProtectionProxyClientImpl(String pwd) {
        System.out.println("ProtectionProxy: Initialized");
        password = pwd;
        client = new RealClientImpl();
    }

    /**
     *  Authenticate the user and return the Account Number
     */
    @Override
    public String getAccountNo() {
        System.out.print("Password: ");
        String tmpPwd = scanner.nextLine();

        if (password == null || password.equals(tmpPwd)) {
            return client.getAccountNo();
        } else {
            System.out.println("ProtectionProxy: Illegal password!");
            return "";
        }
    }
}
 
public class ProtectionProxyExample {
    public static void main(String[] args) {
        Client client = new ProtectionProxyClientImpl("thePassword");
        System.out.println();
        System.out.println("main received: " + client.getAccountNo());
    }
}

Voci correlate

modifica

Altri progetti

modifica

Collegamenti esterni

modifica
  Portale Informatica: accedi alle voci di Wikipedia che trattano di informatica

📚 Artikel Terkait di Wikipedia

Design pattern

linee guida sull'uso delle fonti. Nell'ingegneria del software un design pattern (lett. "schema progettuale o schema di progettazione" in italiano) é una

Model-view-viewmodel

dati (DTOs), Plain Old CLR Objects (pocos), e oggetti generati di entità e proxy. View (vista): La vista è responsabile della definizione della struttura

Adapter pattern

pattern Bridge pattern Decorator Proxy pattern Altri progetti Wikimedia Commons Wikimedia Commons contiene immagini o altri file sull'adapter pattern

Objective-C

usato per implementare semplicemente alcuni design pattern quali l'Observer pattern o il Proxy pattern. Il run-time system di Objective C specifica una

Broker pattern

Gli elementi essenziali sono: client (PROXY) broker oggetto remoto Come in un normale sistema client server il proxy interroga il broker per ricevere un

Cookie

altri programmi, da usare come proxy, permettono all'utente un grado maggiore di controllo su cosa succede. Un Tor o un proxy server hanno l'effetto finale

SuperCollider

l'esecutore modificando ed eseguendo codice on-the-fly. Tipi specifici di proxy pattern possono essere utilizzati come placeholder ("segnaposto") di alto livello

Memoizzazione

Java memoization - un esempio in Java che utilizza classi proxy dinamiche per creare un pattern di memoizzazione generica. Nota: Questo articolo contiene