Un wrapper (dal verbo inglese to wrap, "avvolgere") o funzione wrapper (in italiano talvolta definita funzione-involucro o funzione di confezionamento), in informatica e in particolare nella programmazione software, è un modulo o una funzione il cui scopo principale consiste nel fungere da tramite chiamando un secondo sottoprogramma, una classe o una chiamata di sistema, eseguendo al contempo poche o nessuna elaborazione aggiuntiva.
A differenza di una generica funzione, un wrapper opera come delegato, "rivestendo" il componente software originale in modo che i client interagiscano esclusivamente con l'interfaccia esposta dal wrapper stesso, mentre l'effettiva esecuzione del servizio viene demandata al modulo sottostante. Questo principio di astrazione e delega può essere applicato a singoli sottoprogrammi (come funzioni e metodi) oppure a interi tipi di dati, classi, oggetti e librerie software.
Scopi principali e utilizzo#edit
Praticità di programmazione e manutenibilità#edit
L'uso dei wrapper semplifica la scrittura di programmi e migliora il disaccoppiamento del codice, in particolare quando si integrano librerie di terze parti. Creando una funzione wrapper per ciascuna delle funzioni fornite dalla libreria esterna, l'applicazione nativa interagirà solo con i wrapper. Qualora la libreria di terze parti venga aggiornata o modificata (ad esempio, con cambi di firma o di parametri nelle sue funzioni), lo sviluppatore dovrà modificare unicamente i wrapper interni, senza dover rintracciare e correggere ogni singola istanza nel codice dell'applicazione. Un esempio di questa astrazione è rappresentato dalle classi di tipo MouseAdapter nella libreria Java AWT.
Adattamento delle interfacce (Adapter pattern)#edit
I wrapper consentono di convertire l'interfaccia di una classe o di un oggetto esistente in un'altra interfaccia attesa dai client, garantendo la compatibilità tra componenti altrimenti non integrabili. Questo concetto si ricollega direttamente al design pattern strutturale noto come Adapter (lett. adattatore).
Test del codice e gestione centralizzata degli errori#edit
Scrivere controlli di errore e procedure di verifica per ogni singola chiamata a funzioni di sistema può appesantire notevolmente la lettura del codice. Sostituendo le chiamate dirette con chiamate a una funzione wrapper, i controlli di sicurezza e la gestione delle eccezioni possono essere scritti una sola volta all'interno del wrapper stesso, sollevando il programmatore dal ripeterli nel flusso principale del programma.
- Test driver: È un tipo speciale di wrapper utilizzato per sottoporre a test rigorosi un modulo di codice, richiamandolo ripetutamente con parametri e configurazioni differenti per verificare ogni possibile percorso logico (molto comune nei test di regressione).
- Adattatore di interfaccia: Un wrapper che semplifica, adatta o amplia l'interfaccia di un modulo (ad esempio rinominando parametri, combinandoli o impostando valori predefiniti) per renderla più chiara all'utente.
Simulazione dell'ereditarietà multipla#edit
Nei linguaggi di programmazione che non supportano l'ereditarietà multipla delle classi (come Java), i wrapper e il meccanismo della delega permettono di simularne il comportamento. Una classe può implementare più interfacce contemporaneamente e delegare l'effettiva esecuzione dei metodi a istanze interne di classi diverse, avvolgendole.
Astrazione di chiamate di sistema e funzioni di libreria#edit
Molte funzioni presenti nelle librerie standard, come la Libreria standard del C (ad esempio all'interno di glibc), agiscono come interfacce e wrapper per le chiamate di sistema (system call) di basso livello del sistema operativo. Funzioni come fork ed execve in glibc chiamano internamente le rispettive e omonime chiamate di sistema del kernel, semplificando l'interazione per il programmatore.
Funzioni di supporto (Helper functions)#edit
Una funzione di supporto (helper function) è un tipo di wrapper che raggruppa parti di un calcolo o operazioni frequenti assegnando loro nomi descrittivi e facilitandone il riutilizzo. Sebbene non tutti i wrapper siano funzioni di supporto, tutte le funzioni di supporto sono strutturalmente dei wrapper. Esse trovano largo impiego, ad esempio, nella traduzione binaria dinamica per convertire le istruzioni da un set di architettura a un altro.
Interoperabilità tra linguaggi (Language Binding)#edit
I wrapper facilitano l'interoperabilità e il riutilizzo del codice in ambienti software eterogenei. Strumenti come SWIG (Simplified Wrapper and Interface Generator) o GNU Guile consentono di generare automaticamente wrapper per collegare e utilizzare librerie scritte in un linguaggio (come C o C++) all'interno di altri linguaggi di programmazione, risolvendo i problemi di binding.
Esempio di codice#edit
Il seguente esempio in linguaggio Java mostra come una classe (StackSet) possa simulare l'ereditarietà multipla implementando due interfacce diverse (Stack e Set). La classe agisce come un wrapper, delegando internamente l'effettiva logica e memorizzazione dei dati a due oggetti standard della libreria Java (LinkedList e HashSet):
import java.util.HashSet;
import java.util.LinkedList;
// Definizione dell'interfaccia Stack
interface Stack {
boolean push(Object o);
Object pop();
}
// Definizione dell'interfaccia Set
interface Set {
boolean contains(Object o);
}
// Classe wrapper che implementa entrambe le interfacce simulando l'ereditarietà multipla
public class StackSet implements Stack, Set {
// Componenti interni "avvolti" dal wrapper
private LinkedList stack = new LinkedList();
private HashSet set = new HashSet();
// Metodo wrapper che delega l'operazione di push a HashSet e LinkedList
@Override
public boolean push(Object o) {
if (set.add(o)) {
return stack.push(o); // Delega alla struttura LinkedList sottostante
} else {
return false;
}
}
// Metodo wrapper che delega la rimozione dell'elemento
@Override
public Object pop() {
Object o = stack.pop(); // Delega a LinkedList
set.remove(o); // Delega a HashSet
return o;
}
// Metodo wrapper che delega la verifica di presenza del dato
@Override
public boolean contains(Object o) {
return set.contains(o); // Delega a HashSet
}
}
Note e riferimenti bibliografici#edit
- Bob Reselman, Richard Peasley, Wayne Pruchniak, Using Visual Basic 6, Que, 1998, p. 446. ISBN 9780789716330.
- W. Richard Stevens, Bill Fenner, Andrew M. Rudoff, UNIX Network Programming, Addison-Wesley, 2003, pp. 5–6, 29. ISBN 9780131411555.
- Kathi Fisler, CS 1101: Helper functions, Worcester Polytechnic Institute, 2005.
- Wenwen Wang, Helper function inlining in dynamic binary translation, CC: Compiler Construction, Association for Computing Machinery, 2021, p. 107. doi:10.1145/3446804.3446851. ISBN 978-1-4503-8325-7.
Voci correlate#edit
- Adapter pattern (Pattern adattatore)
- Decorator pattern (Pattern decoratore)
- Delegazione (programmazione)
- Forwarding (programmazione orientata agli oggetti)
- Language binding
- SWIG (generatore automatico di wrapper)
- Funzione annidata (Nested function)
- Applicazione parziale (Partial application)
Altri progetti#edit
- Wikizionario contiene il lemma di dizionario «wrapper»
Collegamenti esterni#edit
- (EN) Denis Howe, Wrapper, in Free On-line Dictionary of Computing. Disponibile con licenza GFDL
This article is mirrored from “Wrapper” on Italiano Wikipedia, revision 152222968, written by Wikipedia's contributors and licensed CC BY-SA 4.0. Editing it here creates a Quire copy with its own history.
Synced with Wikipedia revision 152222968 · just now