Cos’è un wrapper in programmazione?
Il termine inglese “wrapper” indica letteralmente un imballaggio, qualcosa che si avvolge intorno a qualcos'altro come copertura o protezione: un involucro. In riferimento ai software, il termine indica un programma o un codice che riveste altri componenti del programma.
I wrapper vengono utilizzati per vari motivi: spesso ai fini della compatibilità o dell’interoperabilità tra diverse strutture software o anche per motivi di rappresentazione grafica, come nel caso dei wrapper HTML o CSS. Un wrapper può essere un singolo componente software, un prodotto software indipendente, un’architettura software, una classe nella programmazione orientata agli oggetti o un framework.
Se, all’interno di un programma, è necessario utilizzare funzioni o blocchi di programma di un altro linguaggio di programmazione, è possibile “avvolgere” questi elementi con un wrapper. Il programma principale comunica esclusivamente con il wrapper, il quale inoltra i comandi al programma incorniciato e, viceversa, restituisce i risultati. Il wrapper è di fatto l’unico componente che comunica direttamente con le due parti del programma.
I wrapper possono essere utilizzati in diversi modi nell’ambito della programmazione e dello sviluppo di software. Attraverso i seguenti esempi applicativi vi spieghiamo come funziona esattamente un wrapper e quali compiti svolge.
I wrapper come traduttori degli input dell’utente
I moduli all’interno dei programmi o le applicazioni web sono predisposti per ricevere dati che il programma possa elaborare. Nel caso dei programmi provenienti dall’area anglosassone, ad esempio, è pressoché ovvio che i numeri vengano immessi con il punto per separare i decimali, anziché con la virgola, e che le misure vengano espresse in piedi e pollici.
Non sempre, quando si utilizzano questi componenti di programma nelle proprie applicazioni, c’è la possibilità di adeguarli ai formati di dati comunemente utilizzati nel proprio paese, cosa che ovviamente determina risultati errati o persino errori del programma.
In questi casi è utile ricorrere a un wrapper. Il modulo di inserimento dei dati non inoltra le informazioni direttamente al programma esterno, ma al wrapper. Quest’ultimo analizza i dati immessi e li traduce in dati validi per il programma esterno, senza che questo debba essere modificato.
I wrapper per l’accesso alle banche dati
È piuttosto infrequente che banche dati di autori diversi possano essere utilizzate insieme, in quanto le tabelle dei dati, le query o i linguaggi di interrogazione non sono compatibili gli uni con gli altri. Anche in questo caso, la soluzione può essere un wrapper. Tutti i tipi di wrapper hanno lo scopo di individuare le incoerenze tra diverse interfacce software e permetterne il superamento.
La Java Database Connectivity (JDBC), un’interfaccia per banche dati della piattaforma Java di Oracle, è un tipico esempio di wrapper. JDBC permette, nella sua funzione di wrapper, di accedere alle banche dati relazionali di diversi fornitori di software.
JDBC crea il collegamento alle singole banche dati tramite speciali driver. Le query SQL dei programmi vengono rivolte esclusivamente a JDBC e non alle banche dati. JDBC converte le query nel linguaggio di interrogazione utilizzato dalla rispettiva banca dati e restituisce il risultato in una forma compatibile con Java. Il programma richiedente riceve così i dati sempre nello stesso formato, indipendentemente dalla banca dati utilizzata.
I wrapper nella programmazione orientata agli oggetti
Nella programmazione orientata agli oggetti si utilizzano diversi pattern strutturali che, in linea di principio, funzionano sempre allo stesso modo indipendentemente dal linguaggio di programmazione utilizzato. I design pattern Adapter e Decorator appartengono alla categoria dei pattern strutturali e vengono denominati wrapper.
Un adapter avvolge interfacce incompatibili tra di loro tra le singole classi. Grazie alla traduzione di un’interfaccia in un’altra, le classi possono nuovamente comunicare. Questo è particolarmente importante nel caso in cui le classi o intere librerie di classi debbano essere riutilizzate in nuovi progetti. Queste librerie utilizzano interfacce univoche e standardizzate che non possono essere modificate, in quanto devono essere valide per diversi programmi. Il wrapper, in questo caso l’adapter, rappresenta l’anello intermedio fondamentale per la comunicazione.
Un decorator permette di ampliare una classe con funzioni aggiuntive senza doverla modificare. Nei confronti dell’oggetto di programma chiamante, il decorator ha la stessa interfaccia della classe originale. In questo modo, nell’oggetto chiamante non deve essere apportata alcuna modifica. Il decorator, in quanto wrapper, inoltra le chiamate alla classe. Le nuove funzioni che non sono contenute nella classe vengono elaborate direttamente dal decorator. Quest’ultimo restituisce i risultati in modo tale che, sull’oggetto chiamante, vengono visualizzati come risultati della classe decorata.
I wrapper per la realizzazione di documenti HTML
Per la realizzazione o la rielaborazione di siti web con HTML e CSS vengono spesso utilizzati wrapper. In caso contrario, anche solo per modifiche di piccola entità come ad esempio la modifica delle distanze sul margine della finestra del browser, bisognerebbe modificare vari fogli di stile e verificare che alla fine siano nuovamente compatibili.
Molto più semplice è, in questo caso, utilizzare un wrapper sotto forma di contenitore DIV per organizzare tutto il contenuto della pagina come nell’esempio seguente:
<html>
<head>
...
</head>
<body>
<div class="wrapper">
…
</div>
</body>
</html>
All’interno dei questo contenitore wrapper viene collocato il contenuto vero e proprio della pagina.
Nel corrispondente file CSS, il wrapper viene definito come foglio di stile:
body {
margin: 0;
padding: 0
}
.wrapper {
width: 500px;
margin: 25px auto;
}
In questo esempio, con il parametro “width:” al contenitore viene assegnata una larghezza di 500 pixel. I margini superiore e inferiore vengono definiti con il parametro “margin:” a 25 pixel. I margini sinistro e destro vengono calcolati automaticamente in base alla larghezza della finestra del browser e alla larghezza del contenitore.
È sufficiente modificare il wrapper per realizzare piccole modifiche dei margini della pagina, senza dover intervenire ulteriormente nel codice HTML o CSS.
I wrapper TCP nei sistemi Linux
Il servizio in background inetd in Linux e in altri sistemi operativi basati su UNIX viene eseguito come wrapper TCP. inetd ascolta i socket di rete e riceve le richieste di connessione. Un file di configurazione definisce quali porte devono essere considerate. Le richieste vengono analizzate e per queste porte viene avviato il servizio inetd di volta in volta indicato nel file di configurazione. Nella maggior parte dei casi questi programmi sono demoni che vengono eseguiti in background.
Quando il collegamento viene interrotto, inetd arresta automaticamente il servizio attivato. L’avvio su richiesta permette di risparmiare notevoli risorse di sistema rispetto all’avvio automatico di servizi di rete che potrebbero non essere necessari. Inetd lavora come wrapper al quale tutti i programmi inviano le proprie query di rete senza comunicare direttamente con i singoli servizi.
I wrapper TCP possono essere utilizzati anche per impedire accessi indesiderati da una rete. Il wrapper TCP viene a questo scopo interrogato da inetd o da specifici software per server. Gli host e i computer consentiti o rifiutati vengono registrati nei file /etc/hosts.allow e /etc/hosts.deny.