Il termine inglese “wrapper” indica let­te­ral­men­te un im­bal­lag­gio, qualcosa che si avvolge intorno a qual­co­s'al­tro come copertura o pro­te­zio­ne: un involucro. In ri­fe­ri­men­to ai software, il termine indica un programma o un codice che riveste altri com­po­nen­ti del programma.

I wrapper vengono uti­liz­za­ti per vari motivi: spesso ai fini della com­pa­ti­bi­li­tà o dell’in­te­ro­pe­ra­bi­li­tà tra diverse strutture software o anche per motivi di rap­pre­sen­ta­zio­ne grafica, come nel caso dei wrapper HTML o CSS. Un wrapper può essere un singolo com­po­nen­te software, un prodotto software in­di­pen­den­te, un’ar­chi­tet­tu­ra software, una classe nella pro­gram­ma­zio­ne orientata agli oggetti o un framework.

Se, all’interno di un programma, è ne­ces­sa­rio uti­liz­za­re funzioni o blocchi di programma di un altro lin­guag­gio di pro­gram­ma­zio­ne, è possibile “avvolgere” questi elementi con un wrapper. Il programma prin­ci­pa­le comunica esclu­si­va­men­te con il wrapper, il quale inoltra i comandi al programma in­cor­ni­cia­to e, viceversa, re­sti­tui­sce i risultati. Il wrapper è di fatto l’unico com­po­nen­te che comunica di­ret­ta­men­te con le due parti del programma.

I wrapper possono essere uti­liz­za­ti in diversi modi nell’ambito della pro­gram­ma­zio­ne e dello sviluppo di software. At­tra­ver­so i seguenti esempi ap­pli­ca­ti­vi vi spie­ghia­mo come funziona esat­ta­men­te un wrapper e quali compiti svolge.

I wrapper come tra­dut­to­ri degli input dell’utente

I moduli all’interno dei programmi o le ap­pli­ca­zio­ni web sono pre­di­spo­sti per ricevere dati che il programma possa elaborare. Nel caso dei programmi pro­ve­nien­ti dall’area an­glo­sas­so­ne, 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 uti­liz­za­no questi com­po­nen­ti di programma nelle proprie ap­pli­ca­zio­ni, c’è la pos­si­bi­li­tà di adeguarli ai formati di dati co­mu­ne­men­te uti­liz­za­ti nel proprio paese, cosa che ov­via­men­te determina risultati errati o persino errori del programma.

In questi casi è utile ricorrere a un wrapper. Il modulo di in­se­ri­men­to dei dati non inoltra le in­for­ma­zio­ni di­ret­ta­men­te 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 mo­di­fi­ca­to.

I wrapper per l’accesso alle banche dati

È piuttosto in­fre­quen­te che banche dati di autori diversi possano essere uti­liz­za­te insieme, in quanto le tabelle dei dati, le query o i linguaggi di in­ter­ro­ga­zio­ne non sono com­pa­ti­bi­li gli uni con gli altri. Anche in questo caso, la soluzione può essere un wrapper. Tutti i tipi di wrapper hanno lo scopo di in­di­vi­dua­re le in­coe­ren­ze tra diverse in­ter­fac­ce software e per­met­ter­ne il su­pe­ra­men­to.

La Java Database Con­nec­ti­vi­ty (JDBC), un’in­ter­fac­cia per banche dati della piat­ta­for­ma Java di Oracle, è un tipico esempio di wrapper. JDBC permette, nella sua funzione di wrapper, di accedere alle banche dati re­la­zio­na­li di diversi fornitori di software.

JDBC crea il col­le­ga­men­to alle singole banche dati tramite speciali driver. Le query SQL dei programmi vengono rivolte esclu­si­va­men­te a JDBC e non alle banche dati. JDBC converte le query nel lin­guag­gio di in­ter­ro­ga­zio­ne uti­liz­za­to dalla ri­spet­ti­va banca dati e re­sti­tui­sce il risultato in una forma com­pa­ti­bi­le con Java. Il programma ri­chie­den­te riceve così i dati sempre nello stesso formato, in­di­pen­den­te­men­te dalla banca dati uti­liz­za­ta.

I wrapper nella pro­gram­ma­zio­ne orientata agli oggetti

Nella pro­gram­ma­zio­ne orientata agli oggetti si uti­liz­za­no diversi pattern strut­tu­ra­li che, in linea di principio, fun­zio­na­no sempre allo stesso modo in­di­pen­den­te­men­te dal lin­guag­gio di pro­gram­ma­zio­ne uti­liz­za­to. I design pattern Adapter e Decorator ap­par­ten­go­no alla categoria dei pattern strut­tu­ra­li e vengono de­no­mi­na­ti wrapper.

Un adapter avvolge in­ter­fac­ce in­com­pa­ti­bi­li tra di loro tra le singole classi. Grazie alla tra­du­zio­ne di un’in­ter­fac­cia in un’altra, le classi possono nuo­va­men­te co­mu­ni­ca­re. Questo è par­ti­co­lar­men­te im­por­tan­te nel caso in cui le classi o intere librerie di classi debbano essere riu­ti­liz­za­te in nuovi progetti. Queste librerie uti­liz­za­no in­ter­fac­ce univoche e stan­dar­diz­za­te che non possono essere mo­di­fi­ca­te, in quanto devono essere valide per diversi programmi. Il wrapper, in questo caso l’adapter, rap­pre­sen­ta l’anello in­ter­me­dio fon­da­men­ta­le per la co­mu­ni­ca­zio­ne.

Un decorator permette di ampliare una classe con funzioni ag­giun­ti­ve senza doverla mo­di­fi­ca­re. Nei confronti dell’oggetto di programma chiamante, il decorator ha la stessa in­ter­fac­cia 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 di­ret­ta­men­te dal decorator. Quest’ultimo re­sti­tui­sce i risultati in modo tale che, sull’oggetto chiamante, vengono vi­sua­liz­za­ti come risultati della classe decorata.

I wrapper per la rea­liz­za­zio­ne di documenti HTML

Per la rea­liz­za­zio­ne o la rie­la­bo­ra­zio­ne di siti web con HTML e CSS vengono spesso uti­liz­za­ti wrapper. In caso contrario, anche solo per modifiche di piccola entità come ad esempio la modifica delle distanze sul margine della finestra del browser, bi­so­gne­reb­be mo­di­fi­ca­re vari fogli di stile e ve­ri­fi­ca­re che alla fine siano nuo­va­men­te com­pa­ti­bi­li.

Molto più semplice è, in questo caso, uti­liz­za­re un wrapper sotto forma di con­te­ni­to­re DIV per or­ga­niz­za­re tutto il contenuto della pagina come nell’esempio seguente:

<html>
    <head>
    ...
    </head>
    <body>
        <div class="wrapper">
        …
        </div>
        </body>
</html>

All’interno dei questo con­te­ni­to­re wrapper viene collocato il contenuto vero e proprio della pagina.

Nel cor­ri­spon­den­te 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 con­te­ni­to­re 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 au­to­ma­ti­ca­men­te in base alla larghezza della finestra del browser e alla larghezza del con­te­ni­to­re.

È suf­fi­cien­te mo­di­fi­ca­re il wrapper per rea­liz­za­re piccole modifiche dei margini della pagina, senza dover in­ter­ve­ni­re ul­te­rior­men­te nel codice HTML o CSS.

I wrapper TCP nei sistemi Linux

Il servizio in back­ground 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 con­nes­sio­ne. Un file di con­fi­gu­ra­zio­ne definisce quali porte devono essere con­si­de­ra­te. Le richieste vengono ana­liz­za­te e per queste porte viene avviato il servizio inetd di volta in volta indicato nel file di con­fi­gu­ra­zio­ne. Nella maggior parte dei casi questi programmi sono demoni che vengono eseguiti in back­ground.

Quando il col­le­ga­men­to viene in­ter­rot­to, inetd arresta au­to­ma­ti­ca­men­te il servizio attivato. L’avvio su richiesta permette di ri­spar­mia­re notevoli risorse di sistema rispetto all’avvio au­to­ma­ti­co di servizi di rete che po­treb­be­ro non essere necessari. Inetd lavora come wrapper al quale tutti i programmi inviano le proprie query di rete senza co­mu­ni­ca­re di­ret­ta­men­te con i singoli servizi.

I wrapper TCP possono essere uti­liz­za­ti anche per impedire accessi in­de­si­de­ra­ti da una rete. Il wrapper TCP viene a questo scopo in­ter­ro­ga­to da inetd o da specifici software per server. Gli host e i computer con­sen­ti­ti o rifiutati vengono re­gi­stra­ti nei file /etc/hosts.allow e /etc/hosts.deny.

Vai al menu prin­ci­pa­le