Dipartimento di Matematica e Informatica Corso di Laurea in Informatica 28 Aprile 2015 Refactoring di un sistema EDI Refactoring of an EDI system Relatore: Chiar.mo Prof. Armando Sternieri Correlatore: Dott. Pietro Mascolo Candidato: Sefora Scozzarini Matricola: 232940 Anno accademico 2013 - 2014 "When I walk through deep waters, I know that You will be with me. When I’m standing in the fire, I will not be overcome. Through the valley of the shadow I will not fear. In the midst of deep sorrow, I see Your light is breaking through. The dark of night will not overtake me, I am pressing into You. Lord, You fight my every battle and I will not fear because I am not alone, You will go before me, You will never leave me. You amaze me, You redeem me, You call me as Your own. You’re my strength, You’re my defender, You’re my refuge in the storm. Through these trials You’ve always been faithful, You bring healing to my soul." Kari Jobe - I am not alone [10] and now I can say: "I had heard of thee by the hearing of the ear; but now mine eye seeth thee: wherefore I abhor myself, and repent in dust and ashes." Job, 42:5-6 "and he shall wipe away every tear from their eyes; and death shall be no more; neither shall there be mourning, nor crying, nor pain, any more: the first things are passed away. And he that sitteth on the throne said, Behold, I make all things new. And he saith, Write: for these words are faithful and true." Revelation, 21:4-5 Lista delle abbreviazioni Abbreviazione AJAX AMF ANA ANSI APAC API ASC AS1 AS2 AS3 ASCII BBS CGI CLEO CSS CSV DSF DWH EAN EDI EDIFACT EDIINT EDP EMEA ERP FTP HL7 HTML HTTP IBM IDE IETF IP JSON LACES MIME Descrizione Asynchronous JavaScript and XML Action Message Format Article Number Association American National Standards Institute Asia-Pacific Application Programming Interface Accredited Standards Committee Applicability Statement 1 Applicability Statement 2 Applicability Statement 3 American Standard Code for Information Interchange Bulletin Board System Common Gateway Interface Cisco router in Low Earth Orbit Cascading Style Sheets Comma-Separated Values Django Software Foundation Data WareHouse European Article Number Electronic Data Interchange Electronic Data Interchange For Administration, Commerce and Transport EDI via INTernet Electronic Data Processing Europe, the Middle East and Africa Enterprise Resource Planning File Transfer Protocol Health Level 7 HyperText Markup Language HyperText Transfer Protocol International Business Machines Integrated Development Environment Internet Engineering Task Force Internet Protocol JavaScript Object Notation London Airport Cargo EDP Scheme Multipurpose Internet Mail Extensions MSSQL MVC NIST ODETTE PDF PHP RDF REST RFC RoR RSS RTF SQL TDCC TDD UK UN URL US USA VDA-FS VAN WSGI XML XSLT YUI Microsoft Structured Query Language Model-View-Controller National Institute of Standards and Technology Organization for Data Exchange by Tele Transmission in Europe Portable Document Format PHP Hypertext Preprocessor) Resource Description Framework REpresentational State Transfer Request for Comments Ruby on Rails RDF Site Summary Rich Text Format Structured Query Language Transportation Data Coordinating Committee Test Driven Development United Kingdom United Nations Uniform Resource Locator United States United States of America Verband Der Automobilindustrie - FlächenSchnittstelle Value-Added Network Web Server Gateway Interface eXtensible Markup Language EXtensible Stylesheet Language Yahoo User Interface Indice 1 Electronic Data Interchange 1.1 Standard EDI . . . . . . . 1.2 Specifiche di EDI . . . . . 1.3 Trasmissione . . . . . . . . 1.4 Interpretazione dei dati . . 1.5 Vantaggi e svantaggi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 EDI e impresa 2.1 EDI e la società . . . . . . . . . . . . . . . 2.2 Flussi di dati . . . . . . . . . . . . . . . . 2.2.1 Invio catalogo . . . . . . . . . . . . 2.2.2 Ordini . . . . . . . . . . . . . . . . 2.2.3 Report vendite . . . . . . . . . . . 2.2.4 Conferma ordini . . . . . . . . . . . 2.2.5 DDT e fatture . . . . . . . . . . . . 2.3 Comunicazione tra l’ente intermediario e la 2.3.1 Crontab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . società . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 5 5 6 7 . . . . . . . . . 10 10 11 11 12 13 13 13 13 14 3 L’architettura dell’applicativo 16 3.1 Il god object . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.2 Il param_dict object . . . . . . . . . . . . . . . . . . . . . . . 17 3.3 Problematiche degli script . . . . . . . . . . . . . . . . . . . . 18 4 L’applicativo proposto 4.1 Pattern di sviluppo: MVC . . 4.2 L’applicativo proposto . . . . 4.3 Django VS Web2py VS Flask 4.3.1 Il framework Django . 4.3.2 Il framework Web2py . 4.3.3 Il framework Flask . . 4.3.4 Confronto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 20 21 22 22 22 23 23 5 Refactoring di un flusso EDI 5.1 Il report vendite . . . . . . . . . . . 5.2 Analisi funzionale . . . . . . . . . . 5.3 Report vendite originale . . . . . . 5.4 Gli elementi del refactoring . . . . . 5.5 Il nuovo report vendite . . . . . . . 5.5.1 Comunicazione e iterazione . 5.6 La struttura dell’applicativo . . . . 5.7 Test dell’applicativo . . . . . . . . . 5.7.1 Test Driven Development . 5.7.2 Test sul report delle vendite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 26 26 27 27 30 33 34 35 35 37 Elenco delle figure 2.1 2.2 2.3 Descrizione grafica della comunicazione tra le società . . . . . 11 Comandi di un crontab . . . . . . . . . . . . . . . . . . . . . . 15 Esempio di un crontab tratto da Wikipedia . . . . . . . . . . . 15 3.1 3.2 Comunicazione browser-driver . . . . . . . . . . . . . . . . . . 16 Curva relativa al defect rate del software (Pressman) [7] . . . . 19 4.1 Esempio di sintassi di Djando e web2py . . . . . . . . . . . . . 24 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 Funzione di importazione file generica . . . . . . . . . Esempio di funzione di importazione file per UK . . . Esempio di abuso di statement if . . . . . . . . . . . Esempio di refactoring delle funzione di importazione Esempio di refactoring sugli statement if . . . . . . . Struttura della comunicazione delle chiamate . . . . . Descrizione del flusso dei dati . . . . . . . . . . . . . Ciclo di sviluppo di TDD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 28 29 31 32 33 34 36 Elenco delle tabelle Lista delle abbreviazioni . . . . . . . . . . . . . . . . . . . . . . . . ii 1.1 8 Utilizzo mensile medio di carta . . . . . . . . . . . . . . . . . Prefazione In questo lavoro di tesi viene presentato il refactoring di un applicativo software utilizzato da imprese per lo scambio di dati e documenti digitali con interlocutori internazionali sfruttando uno standard EDI. L’obiettivo del progetto è stato, quindi, l’adeguamento di un flusso EDI, il report delle vendite, alle nuove esigenze aziendali e ai canali comunicativi verso nuovi store in modo da ridurre la complessità del codice, migliorarne il riuso e l’estendibilità. Per il raggiungimento di tale obiettivo, l’applicativo è stato riscritto avvalendoci di una struttura tale da renderlo più manutenibile, semplice ed efficiente. Il motivo del refactoring di questo flusso EDI va ricercato nel fatto che durante gli anni, l’adattamento del software alle nuove esigenze, ha generato difetti nel software, facendolo diventare illeggibile e difficile da modificare a fronte di ulteriori nuovi adattamenti. L’espansione di un’azienda verso nuovi mercati, rende necessario l’utilizzo di uno standard per le comunicazioni elettroniche al fine di ridurre le problematiche relative alle differenze di formati, alle modalità di trasmissione, di interpretazione e alla modalità di utilizzo dei dati. La comunicazione tra la società e gli store è gestita grazie all’intermediazione di una società intermediaria che si occupa di traduzioni tra diversi standard EDI. Detta società si occupa di transcodificare i dati in un formato concordato con gli store, facendo sì che la società non debba implementare uno standard di comunicazione diverso per ciascuno dei suoi store. Inoltre, abbiamo analizzato più da vicino l’utilizzo di EDI all’interno dell’azienda e descritto l’architettura dell’applicativo in esercizio, focalizzando l’attenzione sugli oggetti e sulle funzioni da ricostruire e le problematiche che queste causavano al sistema. Questa analisi ci ha condotto verso la sostituzione dell’architettura dell’applicativo originale con uno nuovo. Per l’implementazione della nostra proposta, relativa alla nuova architettura dell’applicativo, ci siamo avvalsi dell’utilizzo del pattern di sviluppo MVC. 1 Dall’analisi degli script originali sono state identificate le peculiarità negative del sistema utilizzato; in seguito sono state indagate diverse possibilità di miglioramento del sistema. I nuovi script sono stati riscritti con l’intenzione di mantenere le funzionalità del codice coerente con quello precedente al fine di non introdurre errori di logica di business. Capitolo 1 Electronic Data Interchange Electronic Data Interchange (EDI) è un metodo di comunicazione elettronica che fornisce gli standard per lo scambio di dati tramite mezzi elettronici. Aderendo allo stesso standard, due diverse società, anche in due paesi diversi, possono scambiare elettronicamente documenti come ordini di acquisto, fatture, avvisi di spedizione e molti altri. EDI può essere formalmente definito come il trasferimento di dati strutturati da norme di messaggio riconosciute da un sistema di computer all’altro, senza intervento umano. Esistono diversi standard EDI consolidatisi nel tempo, alcuni di questi rispondono alle esigenze di industrie o regioni specifiche. Nel 1996, il National Institute of Standards and Technology ha definito EDI come "lo scambio computer-to-computer di messaggi strettamente formattati che rappresentano documenti diversi" [1]. I dati formattati, che rappresentano i documenti, possono essere trasmessi telematicamente dal mittente al destinatario o fisicamente attraverso supporti di memorizzazione elettronica. L’intervento umano nella trasformazione di un messaggio ricevuto è destinato per le condizioni di errore, per la revisione della qualità e per situazioni speciali. EDI costituisce l’intero paradigma di scambio elettronico di dati, compresa la trasmissione, flusso dei messaggi, formato del documento e il software utilizzato per interpretare i documenti. 1.1 Standard EDI Come molte altre tecnologie, EDI è stato ispirato dagli sviluppi di logistica militare. Nel 1948, la complessità del ponte aereo di Berlino ha richiesto lo sviluppo di concetti e metodi per lo scambio di grandi quantità di dati e informazioni relative alla merce trasportata. Da qui nascono i primi standard come il TDCC (Transportation Data Coordinating Committee) negli Stati 3 1.1 Standard EDI Uniti [2]. I primi sistemi integrati che utilizzavano EDI erano i sistemi di controllo merci. Tra questi ricordiamo il London Airport Cargo EDP Scheme (LACES) presso l’aeroporto di Heathrow, Londra, nel 1971. Gli standard EDI descrivono il formato dei documenti elettronici. Questi standard sono stati progettati inizialmente nel settore automobilistico per rendere indipendente il software dalle tecnologie di comunicazione. EDI fornisce una tecnica base per la comunicazione tra due entità commerciali. I documenti possono essere trasmessi utilizzando qualsiasi metodo di trasmissione. Ciò include una varietà di tecnologie, tra cui modem (asincroni e sincroni), FTP, e-mail, HTTP, AS1, AS2, ecc. Quando sono stati confrontati dispositivi CLEO e reti a value-added VAN utilizzate per trasmettere i documenti EDI per la trasmissione via Internet, alcune persone equiparavano le tecnologie non-Internet, per la trasmissione di dati, con EDI. Fu quindi predetto erroneamente che EDI si sarebbe sostituito alle tecnologie non-Internet. Infatti, questi metodi di trasmissione non-Internet vengono sostituiti da protocolli di rete come FTP, telnet e e-mail, ma gli stessi documenti EDI ancora rimangono. Sempre più partner commerciali utilizzano Internet per la trasmissione di dati e documenti. Questo ha favorito la nascita di nuovi standard: • Nel 2002, l’IETF ha pubblicato RFC 3335 che offre un metodo standardizzato sicuro di trasferimento dei dati EDI via e-mail. • Il 12 luglio del 2005, un gruppo di lavoro IETF ha ratificato RFC 4130 per trasferimenti MIME-based, HTTP, EDIINT (anche conosciuto come AS2) e stava preparando un simile RFC per i trasferimenti FTP (anche conosciuto come AS3). Nonostante alcune trasmissioni EDI siano state trasferite con trasmissioni più recenti, i fornitori delle reti a value-added rimangono ancora attive. I documenti EDI contengono le stesse informazioni che normalmente si trovano in un documento cartaceo utilizzato per la stessa funzione organizzativa. Alcuni grandi insiemi di standard EDI: • UN/EDIFACT, unico standard internazionale predominante al di fuori del Nord America. • US standard ANSI ASC X12 (X12), predominante in Nord America. • Tradacoms standard, sviluppato dalla ANA (adesso conosciuta come GS1 UK), che è predominante nel Regno Unito nel settore retail. 4 1.2 Specifiche di EDI • ODETTE, utilizzato nell’industria automobilistica europea. • VDA-FS, utilizzato nell’industria automobilistica europea soprattutto in Germania. • HL7, uno standard di interoperabilità semantica utilizzata per dati amministrativi in ambito sanitario. Molti di questi standard sono apparsi nella prima metà degli anni ’80. Gli standard prescrivono i formati, i set di caratteri, le forme e gli elementi dei dati utilizzati nello scambio di documenti aziendali. Il documento "X12 Document List" include tutti i principali documenti aziendali, compresi gli ordini di acquisto e le fatture. Due documenti EDI possono seguire lo stesso standard ma contenere informazioni diverse. Ad esempio, una azienda alimentare può indicare la data di scadenza di un prodotto, laddove un produttore di abbigliamento potrebbe scegliere di inviare informazioni colore e taglia. 1.2 Specifiche di EDI Nella terminologia EDI, le organizzazioni che inviano o ricevono documenti tra loro sono indicati come "partner commerciali". Questi concordano le informazioni specifiche da trasmettere, come devono essere utilizzate e come devono essere trasmesse. Tra le specifiche di EDI, le norme sono analoghe ai codici di costruzione e le specifiche sono analoghe alle blueprint. 1.3 Trasmissione I partner commerciali sono liberi di utilizzare qualsiasi metodo per la trasmissione di documenti. Inoltre, essi possono sia interagire direttamente sia per interposta persona. Esistono diversi metodi per la comunicazione di dati in un sistema EDI: • Comunicazioni seriali: un tempo era un metodo comune per la trasmissione di messaggi EDI. Si utilizzava un Bisync modem (ossia un modem che sfruttava il protocollo di comunicazione dati sincrona), attraverso il quale un partner poteva avere uno o più modem impostati per ricevere le chiamate in arrivo. In questo modo era possibile comunicare attraverso il modem. Era inoltre possibile utilizzare una linea dedicata o una rete come Telex. Alcune organizzazioni invece, trasmettevano i file EDI via BBS (ossia 5 1.4 Interpretazione dei dati un computer che utilizza un software per permettere a utenti esterni di connettersi a esso attraverso la linea telefonica), dando la possibilità di utilizzare funzioni di messaggistica e file sharing centralizzato. • Internet: con l’accesso ad Internet il numero di aziende che scambiava dati elettronici subì un incremento. Questo avveniva attraverso convenzioni ad hoc, come, ad esempio, FTP non cifrata dei file di testo ASCII. Questi file venivano memorizzati in una cartella specifica, su un determinato host e con accesso consentito solo da alcuni indirizzi IP. • Peer-to-Peer: Gli standard EDI sono scritti in modo tale che lo scambio di dati, utilizzando interfacce utente, possa collegare direttamente il mittente e il destinatario. Ad esempio, un produttore di automobili potrebbe mantenere un modem attivo al quale tutti i suoi fornitori devono collegarsi per poter inviare documenti in uno dei formati EDI. Tuttavia, se un fornitore fa affari con diversi produttori, potrebbe essere necessario acquistare un modem diverso (o dispositivo VPN, ecc) e un software diverso per ognuno. • Reti value-added: Per affrontare le limitazioni dell’adozione del sistema di comunicazione peer-to-peer di EDI, sono state utilizzate le reti VAN. Queste ricevono le operazioni che vengono esaminate fino ad arrivare al destinatario finale. Le comunicazioni VAN possono fornire una serie di servizi aggiuntivi, ad esempio ritrasmettere i documenti, fornire informazioni di controllo di terze parti, agire come un gateway per i diversi metodi di trasporto, o gestire il supporto delle telecomunicazioni. Le reti VAN sono spesso utilizzate delle aziende, soprattutto quando mittente e destinatario utilizzano protocolli Internet. Le reti VAN possono essere gestite da diverse entità: – società di telecomunicazioni; – consorzi di gruppi industriali; – una grande azienda che interagisce con i suoi fornitori/produttori. 1.4 Interpretazione dei dati I software di traduzione EDI costituiscono l’interfaccia tra i sistemi interni e il formato EDI inviato/ricevuto. Per un documento "in entrata" la soluzione EDI riceverà il file e verificherà che: • il partner commerciale che sta inviando il file sia un partner commerciale valido; 6 1.5 Vantaggi e svantaggi • la struttura del file soddisfi gli standard EDI; • i singoli campi di informazioni siano conformi allo standard concordato. In genere il traduttore crea un file di una lunghezza fissa o variabile, oppure un file in formato XML e stampa il documento EDI ricevuto. Il passo successivo è quello di convertire/trasformare il file creato dal traduttore in un formato che può essere importato nel sistema di back-end dell’azienda o nell’ERP della società. Questo può essere realizzato utilizzando un programma personalizzato, un mapper integrato, di proprietà, che utilizza un linguaggio di trasformazione di dati standard, come XSLT. Il passo finale è quello di importare il file trasformato (o database) nel sistema di back-end dell’ERP dell’azienda. In EDI la terminologia "entrata" e "uscita" si riferisce alla direzione di trasmissione di un documento EDI in relazione ad un particolare sistema, non la direzione di merci, denaro o altri elementi rappresentati dal documento. Ad esempio, un documento EDI che indica che un magazzino deve effettuare una spedizione in uscita è un documento in ingresso in relazione al sistema informatico del magazzino ed è un documento in uscita rispetto al produttore o commerciante che ha trasmesso il documento. Per un documento "in uscita" il processo per EDI integrato è quello di esportare un file (o leggere un database) dal backend dell’ERP di un’azienda, di trasformare il file nel formato appropriato per il traduttore. Il software di traduzione deve poi validare il file EDI inviato per garantire che risponda allo standard concordato, convertire il file in formato EDI (aggiungendo gli identificatori appropriati e strutture di controllo) e inviare il file al partner commerciale (utilizzando il protocollo di comunicazione appropriati). Un altro componente critico di qualsiasi software di traduzione EDI è un audit completo di tutti i passaggi per spostare documenti aziendali tra i partner commerciali. L’audit assicura che tutte le transazioni possano essere monitorate, per evitare un’eventuale perdita di dati e controlla che il formato stabilito sia rispettato. Nel caso in cui un rivenditore faccia un invio di un ordine di acquisto ad un fornitore, se l’ordine di acquisto fosse smarrito durante il processo di business, l’effetto sarebbe deleterio sia per il fornitore, che non effettua l’ordine, sia per il rivenditore, che ha un’interruzione delle vendite. 1.5 Vantaggi e svantaggi EDI e altre tecnologie consentono un risparmio economico alla società fornendo un’alternativa o sostituzione ai flussi di informazioni che richiedono 7 1.5 Vantaggi e svantaggi una grande quantità di documenti cartacei e di interazione umana. Anche quando i documenti cartacei sono mantenuti in parallelo con lo scambio EDI, come nel caso della stampa documenti di trasporto, lo scambio elettronico e l’utilizzo dei dati, permette di ridurre i costi di gestione, di smistamento, di distribuzione, di organizzazione e di ricerca di documenti cartacei. EDI e le tecnologie similari consentono ad una società di sfruttare i vantaggi di conservazione e manipolazione dei dati per via elettronica senza il costo di inserimento manuale. Un altro vantaggio di EDI è l’opportunità di ridurre gli errori di immissione manuale dei dati, come ad esempio gli errori di spedizione e fatturazione, perché EDI elimina la necessità di ridigitare documenti sul lato di destinazione. Un importante vantaggio di EDI su documenti cartacei è la velocità in cui le aziende ricevono e incorporano le informazioni nel loro sistema riducendo notevolmente i tempi ricezione dei documenti. Per questo motivo, EDI può essere un componente importante dei sistemi produttivi just in time [3] che cercano di minimizzare gli sprechi di: • tempo, lungo il ciclo di lavorazione; • oneri aggiuntivi di produzione, connessi alle strutture, alle attrezzature, al personale occorrente per gestire le scorte; • materiali e i componenti, che devono pervenire al momento opportuno sulla linea di produzione limitando i tempi di attesa. Secondo la relazione del 2008 di Aberdeen [4] l’utilizzo di EDI ha portato ad un notevole risparmio di costi d’acquisto di carta mensile. Nella tabella 1.1 è possibile vedere le percentuali di acquisto di carta ordinaria relativa soltanto agli ordini di acquisto merci: Area Nord America EMEA APAC % Ordini 34% 36% 41% Costo 37,45$ 42,90$ 23,90$ Costo con EDI 23,83$ 34,05$ 14,78$ % Risparmio 36,37% 20,63% 38,16% Tabella 1.1: Utilizzo mensile medio di carta Ci sono alcuni ostacoli all’adozione di EDI. Uno degli ostacoli più significativi è il cambiamento dei processi di business di accompagnamento. Questi ultimi, infatti, essendo costruiti intorno alla gestione della carta non possono 8 1.5 Vantaggi e svantaggi essere adatti per EDI e richiederebbero modifiche per ospitare l’elaborazione automatica di documenti aziendali. Altro ostacolo importante è il costo in tempo e denaro del primo set-up, ossia delle spese preliminari e del tempo necessario all’implementazione. Un ostacolo per una corretta attuazione di EDI è la percezione che molte aziende hanno della sua natura. Sarebbe più corretto considerare che EDI è un sistema per lo scambio di documenti aziendali con enti esterni e integrare i dati provenienti da tali documenti nei sistemi interni della società. Implementazioni di successo di EDI tengono conto dell’effetto che le informazioni generate esternamente avranno sui loro sistemi interni e convalidano le informazioni di business ricevute. 9 Capitolo 2 EDI e impresa Esistono diverse società referenti in EDI e fatturazione elettronica, che progettano modelli di trasmissione e integrazione di dati tra aziende. Queste società adattano soluzioni tecnologiche alle necessità del cliente, superando frontiere, sistemi normativi e complessità tecniche, effettuando uno scambio efficiente delle transazioni elettroniche ponendosi tra produttore e cliente. Analizziamo in dettaglio una struttura organizzativa d’esempio per identificare quali sono alcuni dei flussi di dati presenti nella maggior parte delle aziende di grandi dimensioni. 2.1 EDI e la società Lo scambio di dati tra la società e l’ente intermediario avviene utilizzando uno degli standard EDI concordati tra le parti. La figura 2.1 illustra graficamente dove si colloca EDI nello scambio di dati tra le società coinvolte. 10 2.2 Flussi di dati Figura 2.1: Descrizione grafica della comunicazione tra le società 2.2 Flussi di dati All’interno del progetto di questa tesi, i flussi previsti sono: • invio catalogo, dalla società agli store; • ricezione ordini, dagli store alla società; • report vendite, dagli store alla società; • conferma ordini, dalla società agli store; • documenti di trasporto e fatture, dalla società agli store; 2.2.1 Invio catalogo I cataloghi, di solito, sono costruiti in base allo store e alla società ai quali si riferiscono. Al codice EAN del prodotto sono associati altri dati quali prezzo, casa produttrice, società di riferimento, società cliente, ecc. Queste informazioni sono raccolte diversificate per ogni società a cui devono essere inviate. I dati vengono raccolti in un file testuale con uno specifico formato EDI che deve essere inviato all’ente intermediario. Per evitare l’invio multiplo di cataloghi ad un store, si effettua un controllo sui cataloghi già inviati in precedenza e si inviano quelli che non sono presenti nell’archivio dello store. Abbiamo anche implementato la possibilità di forzare l’invio. Potrebbe capitare, infatti, che alcuni cataloghi non siano stati correttamente inviati o che lo store decida di riscaricarli. I dati sono recuperati da varie sorgenti: 11 2.2 Flussi di dati • delle tabelle del database locale, che contengono tutte le informazioni relative ai singoli punti vendita per gli store e i dati dei parametri delle connessioni; • dai DWH aziendali; • dai gestionali delle singole società, che gestiscono la parte interna del business; • dal database del gruppo, ossia un database che racchiude il coordinamento dei database delle singole società. Questi dati vengono presi, ed integrati nel catalogo che sarà poi inviato all’ente intermediario attraverso una connessione FTP. La struttura dei file è costituita dall’invio di 4 file: • un file di header in cui viene specificato il tipo di trasmissione, lo store destinatario, per che tipo di catalogo si stanno inviando i file e altri dati di testata della comunicazione; • un file body in cui sono presenti tutti i dati relativi ai prodotti; • un file di footer in cui sono presenti alcuni dati relativi allo scambio comunicativo tra la società e gli store; • un file vuoto (opzionale), che indica la fine della trasmissione. 2.2.2 Ordini Gli ordini sono un flusso opposto ai cataloghi, ovvero l’origine del flusso è l’ente intermediario e il destinatario è la società. I dati vengono raccolti via FTP dall’ente intermediario, scaricati in locale ed elaborati dagli script. Sono suddivisi in base al tipo di store che li ha inviati: • store europei, non hanno delle suddivisioni tali per cui è importante tenere separato il singolo store. Quindi tutti gli ordini sono salvati nello stesso file con il riferimento allo store che ha effettuato l’ordine. • store americani, suddivisi in file riferiti ai singoli store. Gli ordini sono analizzati nelle quantità, negli EAN previsti, e poi smistati a seconda dello store destinatario dell’ordine. 12 2.3 Comunicazione tra l’ente intermediario e la società 2.2.3 Report vendite I report delle vendite sono dei rapporti che vengono inviati dagli store alla società di riferimento in merito al venduto della giornata. In particolare, i report delle vendite contengono i dati relativi al: • venduto; • stornato; • scarico; • rientro. Anche in questo caso, i file vengono salvati in locale. Vengono scaricati mediante connessione FTP dall’ente intermediario per poi essere elaborati dallo script. Sono dei file composti, come nel caso dei cataloghi, da un file di testata, un file luogo e un file vendita. 2.2.4 Conferma ordini La conferma ordini prende dati (relativi agli ordini effettuati dai clienti) dalla società e li invia agli store. È un flusso che, in seguito alla conferma dell’ordine da parte del cliente, invia il documento allo store in cui si conferma l’ordine effettuato e dove vengono specificati i prodotti che sono stati ordinati e le quantità. Potrebbe essere considerato un’evoluzione del catalogo, con la differenza che viene data la conferma che è stato fatto un ordine. 2.2.5 DDT e fatture I documenti di trasporto e le fatture sono documenti presi dalla società e poi inviati agli store. Sono i flussi più critici in quanto dai documenti di trasporto e dalle relative fatture dipende il prezzo di vendita che viene imputato agli store. 2.3 Comunicazione tra l’ente intermediario e la società La comunicazione dei documenti e dei dati avviene tramite FTP. La gestione e l’invio delle comunicazioni sono gestiti da processi schedulati utilizzando un file crontab. La presenza dell’ente intermediario evita la necessità di comunicazioni dirette tra cliente e fornitore oltre a rendere non necessario un processo di adattamento dei formati di comunicazione per ogni diverso store. 13 2.3 Comunicazione tra l’ente intermediario e la società 2.3.1 Crontab Crontab è un comando che permette di fare una pianificazione di comandi, cioè consente di memorizzare questi comandi nel sistema in modo che possano essere utilizzati periodicamente e automaticamente dal sistema stesso. Crontab è utilizzato nei sistemi operativi Unix da un demone, chiamato crond, che una volta al minuto, legge i contenuti del registro dei comandi pianificati ed esegue quelli per cui si è esaurito il periodo di attesa. Di solito un comando mandato in esecuzione da crontab viene chiamato cronjob. I file crontab contengono la lista dei job e altre istruzioni per il demone di cron. Gli utenti possono avere dei file crontab individuali e spesso ci sono dei file crontab a livello di sistema che possono essere utilizzati, ma modificati solo dagli amministratori di sistema. Ogni linea di un file crontab segue un formato particolare, composta da una serie di campi separati da spazi o tabulazioni. I campi possono avere un solo valore o una serie di valori [5]. Gli operatori di crontab Esistono diversi modi per specificare valori multipli in un campo: • l’operatore virgola (ossia il simbolo ",") che specifica una lista di valori; • l’operatore trattino (ossia il simbolo "-") che specifica un intervallo di valori; • l’operatore asterisco (ossia il simbolo "*") che specifica tutti i possibili valori di un campo. Esiste anche un operatore supportato da alcune versioni estese del cron, l’operatore slash ("/"), che può essere usato per saltare un certo numero di valori. I campi di crontab I primi cinque campi su ogni riga specificano con che frequenza e quando eseguire un comando. 14 2.3 Comunicazione tra l’ente intermediario e la società Figura 2.2: Comandi di un crontab Esempio di utilizzo di crontab Vogliamo riprodurre la generazione automatica dei report delle attività di sistema. Questo job deve essere eseguito in modo che: • tra le 8 e le 17 generi un report ogni 20 minuti nei giorni feriali; • generi un report ogni ora nei giorni di sabato e domenica; • tra le 18 e le 7 generi un report ogni ora nei giorni feriali; • generi un riassunto alle 18:05 di ogni giorno feriale. L’aspetto che ha il nostro job così configurato, è il seguente: Figura 2.3: Esempio di un crontab tratto da Wikipedia 15 Capitolo 3 L’architettura dell’applicativo L’architettura dell’applicativo non utilizza un framework, ma si basa su script scritti in Python. L’interfaccia tra gli script python e il web server è costituita da un modulo, detto driver, che gestisce le richieste e le risposte da e per il web server tramite un dizionario di parametri chiamato param_dict. Figura 3.1: Comunicazione browser-driver 3.1 Il god object Un god object è un oggetto che contiene tutte le costanti e le variabili necessarie all’esecuzione del programma, ed è coinvolto nell’esecuzione della maggior parte delle funzioni [6]. In un programma che si avvale di un god object la maggior parte delle funzionalità del programma sono codificate in un singolo oggetto "onnisciente", che mantiene la maggior parte delle informazioni riguardo l’intero programma e fornisce la maggior parte dei metodi necessari per manipolare questi dati. Poiché questo oggetto contiene così tanti dati e richiede tanti metodi, il suo ruolo nel programma diviene insostituibile. Invece di avere oggetti nel programma che comunicano direttamente tra di loro, gli altri oggetti all’interno del programma si basano su questa entità per la maggior parte della loro interazione. Poiché il god object è legato strettamente a tanto codice, la manutenzione diventa molto più difficile di quanto lo sarebbe in un programma strutturato equamente, in quanto risulta difficile fare dei test per la 16 3.2 Il param_dict object risoluzione dei problemi e l’aggiunta o la rimozione di nuovi metodi richiede l’aggiornamento di questo oggetto in ogni parte del programma. La creazione di un god object è in genere considerata una cattiva pratica di programmazione. Questa tecnica è talvolta usata per gli ambienti di programmazione ristretti (ad esempio microcontrollori), dove il leggero aumento delle prestazioni e la centralizzazione di controlli è più importante della manutenzione e dell’eleganza di programmazione. 3.2 Il param_dict object Il param_dict è un oggetto, usato da alcune società, che presenta le caratteristiche di un god object; in quanto tale, il param_dict ha dei lati positivi ma tantissimi lati negativi. Tra i lati positivi abbiamo la semplicità di utilizzo, in quanto una volta scritto lo script, non è necessario configurare le entità o i modelli. L’utilizzo del param_dict presenta molti lati negativi: • è la figura di riferimento per tutte le altre funzioni; • è quello che si occupa di trasportare i dati da un punto all’altro dell’applicativo; • è il contenitore di tutti i dati, sensibili e non; • è onnipresente, per sfruttarne i vantaggi ce lo si porta dietro in maniera esplicita, occupando memoria ovunque, sia a livello globale sia a livello locale, essendo un parametro che è passato alle funzioni; • è modificabile, essendo un dizionario è possibile accedere alle chiavi e modificarne i relativi valori, cancellarne chiavi, aggiungerne di nuove, ecc.; • non sfrutta il paradigma di programmazione object oriented, ovvero viene sfruttata a livello molto basico; • rende difficile la creazione di strutture complesse poiché ogni struttura deve mantenere param_dict come punto di riferimento; • non è particolarmente potente, poiché bisogna scrivere tutte le strutture a mano se e quando servono (ed esempio i template HTML). Questo vale anche per i framework poiché con param_dict il codice HTML e SQL sono direttamente contenuti nel codice. 17 3.3 Problematiche degli script 3.3 Problematiche degli script Adattare un software in base alle esigenze di un’azienda porta gli sviluppatori a scegliere soluzioni o tecnologie e determinate risorse informatiche adatte alla situazione e alle richieste dell’azienda. Questo procedimento è iterato nell’arco degli anni, portando non pochi problemi: • Le modifiche apportate al codice sono effettuate da diversi programmatori. Questo implica, in base alla preparazione dello sviluppatore e alle scelte tecnologiche, un diverso approccio tecnico. • L’evoluzione di linguaggi di programmazione e delle tecnologie di sviluppo creano dei disagi nel momento in cui i nuovi servizi vengono implementati in versioni del linguaggio diverse. • La prassi di utilizzo degli script EDI in azienda li ha resi un elemento critico: sono seguiti e conosciuti da un unico programmatore. L’ultimo punto è riconosciuto come particolarmente critico in quanto, il fatto che un programmatore sia depositario unico della conoscenza funzionale e di business dell’applicativo rende l’intervento di altri sviluppatori sul suo codice estremamente complicato se non, in certi casi, impossibile. Le esigenze di business sorte nel corso degli anni hanno reso necessarie diverse modifiche alla base del codice esistente, ciò ha contribuito alla produzione di codice inefficiente, ridondante e illeggibile. La molteplicità dei controlli ha generato un codice pieno di controlli gestiti da statement if, ripetuti e, in alcuni casi, obsoleti. Questa tecnica di programmazione tende a far diventare il codice anche molto lungo e poco leggibile. 18 3.3 Problematiche degli script Figura 3.2: Curva relativa al defect rate del software (Pressman) [7] In figura 3.2 si nota come, all’inizio dello sviluppo di un software, il livello di difetti presenti nel software sia elevato. Man mano che passa il tempo, gli errori presenti nel sistema software diminuiscono fino a raggiungere una quota costante. L’aggiunta di una nuova funzionalità, con esigenze di programmazione diverse, fa decollare la curva relativa al defect rate del software relativamente ai difetti che questo presenta quando viene aggiunta una nuova funzionalità. Man mano che i difetti vengono corretti si cerca anche di mantenere il sistema compatibile alle nuove esigenze. Questo ciclo si ripete ogni volta che il sistema deve subire una modifica sostanziale, per cui, ad un certo punto, il livello di difetti sul software diventa molto alto, tanto da richiedere una riscrittura dello stesso sistema sulla base delle esigenze accumulatesi nel corso degli anni. 19 Capitolo 4 L’applicativo proposto 4.1 Pattern di sviluppo: MVC Il Model-View-Controller è un pattern architetturale molto diffuso nello sviluppo di sistemi software lato web in grado di separare la logica di presentazione dei dati dalla logica di business. Questo pattern si può posizionare nel livello di presentazione in una Architettura multi-tier, ossia su più livelli. Sul lato server il pattern è stato esplicitamente o implicitamente sposato da numerose tecnologie moderne, come framework basati su PHP (Symfony, Laravel, Zend Framework CakePHP, Yii framework, CodeIgniter), su Ruby (Ruby on Rails), su Python (Django, TurboGears, Pylons, Web2py, Zope, Flask), su Java (Swing, JSF e Struts), su Objective C o su .NET. Sul lato client, la crescita del codice JavaScript ha fatto sentire l’esigenza di creare i primi framework che implementino MVC in puro JavaScript. Uno dei primi è stato Backbone.js, seguito da altri, tra cui JavascriptMVC ed AngularJS. Il pattern è basato sulla separazione dei compiti fra i componenti software che interpretano tre ruoli principali: • il model fornisce i metodi per accedere ai dati utili all’applicazione; • la view visualizza i dati contenuti nel model e si occupa dell’interazione con utenti e agenti; • il controller riceve i comandi dell’utente tramite il view e li attua modificando lo stato degli altri due componenti. Questo schema implica anche la tradizionale separazione fra la logica applicativa (in questo contesto spesso chiamata "logica di business"), a carico del controller e del model, e l’interfaccia utente a carico della view. I dettagli 20 4.2 L’applicativo proposto delle interazioni fra questi tre oggetti software dipendono molto dalle tecnologie usate (linguaggio di programmazione, eventuali librerie, middleware, ecc.) e dal tipo di applicazione (per esempio se si tratta di un’applicazione web, o di un’applicazione desktop, applicazione di back-and, ecc.). 4.2 L’applicativo proposto L’applicativo proposto è costruito sul paradigma MVC quindi, rispetto all’architettura dell’applicativo originale è strutturalmente più complesso in quanto dal singolo script si passa ad avere una o più classi suddivise su diversi file. All’aumento della complessità corrisponde, però, un considerevole aumento di flessibilità e potenza. Per evitare problemi di formato viene reintrodotta una tipizzazione statica per le entità. I singoli oggetti sono raggruppati per funzionalità e l’interazione con l’utente è gestita da una singolo nodo d’ingresso. I singoli componenti sono: • il controller, che gestisce l’input e l’interazione con l’utente; • l’entity, che costituisce la mappatura dei dati nel database; • il source, che collegato all’entity stabilisce il collegamento univoco tra entity e tabella di riferimento e può implementare nuovi metodi di raccolta dati del database; • il locator, che è il nodo centrale di comunicazione tra i pezzi del framework. Contiene la localizzazione delle singole classi e metodi e dei loro contenuti all’interno dei package e dei moduli. Inoltre, definisce i metodi pubblici; • il service, che è il contenitore dei metodi generici dell’applicazione; • la view: è quella che si occupa della gestione dell’output verso l’utente e contiene anche i template estendibili. A livello di tecnologia, il framework viene gestito da un driver che interagisce con il server Apache. I linguaggi utilizzati sono Python 2.7, Javascript con le estensioni di YUI 3 e a livello web con HTML 5 e CSS 3. Gli sviluppi vengono effettuati in locale su macchine virtuali e poi messi sotto controllo versione in un repository Git remoto. In seguito, abbiamo spostato l’architettura su un sistema a due livelli: back-end e front-end. 21 4.3 Django VS Web2py VS Flask 4.3 4.3.1 Django VS Web2py VS Flask Il framework Django Django è un web framework open source utilizzato per lo sviluppo di applicazioni web e scritto in linguaggio Python seguendo il pattern MVC. Django è un progetto sviluppato dalla "Django Software Foundation" (DSF), un’organizzazione indipendente senza scopo di lucro. Django fornisce un certo numero di funzionalità che facilitano lo sviluppo rapido di applicazioni per la gestione di contenuti Web. Django fornisce una soluzione integrata di amministrazione dei contenuti che può essere inclusa come parte di ogni sito basato su Django e che può gestire molti siti Django da un’unica installazione. L’applicazione per l’amministrazione permette di creare, aggiornare e eliminare contenuti rappresentati da oggetti tenendo traccia di tutte le operazioni effettuate e fornisce un’interfaccia per la gestione di utenti e gruppi di utenti (inclusa la gestione dei permessi). La distribuzione principale di Django viene fornita con applicazioni che forniscono un sistema di commenti, funzionalità per la creazione di feed RSS e/o Atom, "pagine semplici" che permettono di essere gestite senza dover scrivere un controller o una view appositi, e funzionalità di redirezione di URL. 4.3.2 Il framework Web2py Web2py è un framework open source di applicazioni web-based scritto e programmabile in Python. Ispirato da Ruby on Rails (RoR) e Django, Web2py segue il pattern architetturale Model-View-Controller (MVC). Web2py è stato creato da una comunità di professionisti e docenti universitari della facoltà di Informatica e Ingegneria del Software. È uno strumento compatibile e retrocompatibile con le versioni più vecchie e molto facile da usare. Non richiede nessuna installazione e nessuna configurazione. Funziona su sistemi Windows, Mac, Unix/Linux, Google App Engine, Amazon EC2, e quasi tutti i web hosting tramite Python 2.5/2.6/2.7/PyPy, o Java con Jython. Funziona con Apache, Lighttpd, Cherokee e quasi tutti gli altri web server tramite CGI, FastCGI, WSGI, mod_proxy, e/o mod_python. Può incorporare apps WSGI di terze parti e middleware. Comunica con diversi database tra i quali: SQLite, PostgreSQL, MySQL, MSSQL, Firebird, Oracle, IBM DB2, Informix, Ingres, e Google App Engine. Previene i più comuni tipi di vulnerabilità , tra cui Cross Site Scripting, Injection Flaws e l’esecuzione di file dannosi. Applica le buone pratiche di ingegneria del software sfruttando la progettazione Model-View-Controller, la validazione dei form lato server e i postback, che rendono il codice più leggibile, scalabile e gestibile. 22 4.3 Django VS Web2py VS Flask Parla con molti protocolli tra cui: HTML/XML, RSS/ATOM, RTF, PDF, JSON, AJAX, XML-RPC, CSV, REST, WIKI, Flash/AMF, e Linked Data (RDF). Include un server SSL-enabled e web server streaming-capable, un database relazionale, un ambiente di sviluppo integrato web-based e interfaccia di gestione web-based, un database Abstraction Layer che scrive SQL in tempo reale, il supporto all’internazionalizzazione, metodi di autenticazione multipli, controllo di accesso basato sul ruolo, di un sistema di registrazione degli errori e di ticketing, diversi metodi di caching per la scalabilità e la libreria jQuery per AJAX. 4.3.3 Il framework Flask Flask è un framework web leggero scritto in Python distribuito con licenza Berkeley Software Distribution. Flask ha un nucleo semplice ma estensibile. Non c’è uno strato di astrazione per la base di dati, validazione della forma, o qualsiasi altra componente dove esistono già librerie di terze parti per fornire funzionalità comuni. Esistono estensioni per mappatori ad oggettirelazionali, gestione del caricamento e varie tecnologie di autenticazione che possono aggiungere funzionalità ad un’applicazione. Flask contiene server e debugger per lo sviluppo, un supporto integrato per il test d’unità. Supporta cookie di sicurezza (sessioni lato client) è basato su Unicode ed è dato di una documentazione estensiva [9]. 4.3.4 Confronto Secondo gli utilizzatori di queste due piattaforme, Django e Web2py sono considerate entrambi due piattaforme abbastanza solide e con piccole differenze. Django è considerato come il padre di Web2py. A livello funzionale le due piattaforme sono abbastanza simili. Le differenza che creano divisioni tra la comunità sono poche e dipendenti dal giusto e dalle esigenze dello sviluppatore. Django è stato sviluppato ispirato dalla citazione "esplicito è meglio di implicito" invece Web2py è stato sviluppato ispirato dalla citazione "tutto deve avere un comportamento di default". Partendo da queste ispirazioni si hanno le divergenza tra le due piattaforme. Django è stato sviluppato senza pensare alla retrocompatibilità delle versioni, cosa che invece Web2py tiene in considerazione sin da quando è iniziato il suo sviluppo. A livello di sicurezza dei dati sono entrambi abbastanza affidabili e sicuri dagli attacchi di vario genere. Web2py è molto più compatto, ha molte funzionalità e supporta molti database, IDE web-based, il sistema di ticketing, la connessione multipla di database, ha tanti metodi di login e regole di ac23 4.3 Django VS Web2py VS Flask cesso, ecc. A livello sintattico per molti sviluppatori, la sintassi di Web2py risulta essere più naturale di quella di Django. Figura 4.1: Esempio di sintassi di Djando e web2py La community di Web2py risulta essere molto più amichevole di quella di Django invece la community di Django viene considerata molto veloce. Django è considerato il più grande framework web basato su Python. Esso è supportato da una comunità grande e attiva. Viene fornito con una potente interfaccia di amministrazione, così come molte altre caratteristiche. Django offre moduli basati su modello, ha un proprio linguaggio di template, e ha un’ottima documentazione disponibile. Django è consigliato per gli sviluppatori che vogliono condividere idee tramite forum online e a quelli che vogliono costruire qualcosa rapidamente con potenti strumenti integrati. Flask è un "microframework" rivolto soprattutto alle applicazioni con requisiti semplici. La sua caratteristica è quella di mantenersi semplice e piccolo. È costituito da una manciata di moduli ma non esiste uno scheletro dal quale partire. Flask lascia scegliere allo sviluppatore come memorizzare i propri dati ed è consigliato per: • apprendere la programmazione; • gli sviluppatori che hanno a cuore le migliori pratiche di programmazione; • gli sviluppatori che vogliono qualcosa da prototipare rapidamente; • gli sviluppatori che hanno bisogno di una applicazione standalone. Web2py e Django sono entrambi rivolti ad applicazioni di grandi dimensioni, ma hanno diversi approcci all’estensibilità e alla flessibilità. Django si propone di includere tutto quello che un’applicazione web avrà bisogno, per cui gli sviluppatori hanno bisogno di aprirne il funzionamento e iniziare a lavorare. Il premio per le comunità più attive va a Django e Web2py. Flask è riconosciuto per gli sviluppatori che lavorano su progetti di piccole dimensioni che hanno bisogno di un modo rapido per fare un semplice sito 24 4.3 Django VS Web2py VS Flask web Python-powered. Possiede tantissime semplici interfacce web costruite sfruttando le API esistenti. 25 Capitolo 5 Refactoring di un flusso EDI 5.1 Il report vendite Un rapporto di vendita contiene i dati relativi al venduto e allo stornato suddiviso per store. I dati contenuti in questo rapporto sono utilizzati per effettuare delle statistiche sul venduto e per verificare l’allineamento dei sistemi informatici rispetto ai dati registrati dai singoli punti vendita. Lo script che gestisce il rapporto di vendita si interfaccia con il database per reperire dati di anagrafica dei prodotti, anagrafica fornitori e società, dati contabili e i dati di giacenza dei resi. 5.2 Analisi funzionale Lo script inizialmente in esercizio era costituito da un file monolitico contenente tutte le funzioni e le costanti necessarie per le operazioni sul rapporto delle vendite. Il param_dict giocava un ruolo centrale nel flusso del programma, essendo argomento di input della maggior parte delle funzioni ed essendo manipolato o utilizzato in quasi tutti i suoi processi. Lo script comprendeva tre principali tipi di funzioni: • esportazione dei dati rielaborati; • importazione dei rapporti di vendita; • funzioni di supporto. A causa del diverso contenuto informativo riferito da differenti store e di una struttura di controlli specifica per cliente, si era reso necessario lo sviluppo di più funzioni specializzate all’interno di ognuno dei raggruppamenti sopra 26 5.3 Report vendite originale elencati. Ciò ha portato alla presenza di frammenti di codice duplicato su varie funzioni. Per ottimizzare questa struttura abbiamo deciso di effettuare un’analisi approfondita della logica seguita dalle funzioni al fine di ridurre le ripetizioni di codice, limitare le dimensioni delle funzioni, ridurre il numero di variabili globali e di rifattorizzare il flusso di esecuzione scorporando il file monolitico in più moduli. 5.3 Report vendite originale Il report delle vendite originale era caratterizzato dalla presenza del param_dict object e, di conseguenza, dagli aspetti negativi illustrati nella sezione 3.2. La presenza di funzioni molto lunghe, inoltre, rende difficile la lettura, la comprensione e la manutenibilità del codice; la presenza di ripetizioni di blocchi di codice rende anche complicate eventuali modifiche necessarie per evolutive o correzione di bug. I dati che risiedono sui database sono acceduti tramite query inserite direttamente all’interno delle funzioni, pratica scoraggiata nello sviluppo in ambito web, in cui è preferibile un’interazione con i dati mediata da un’entità specializzata. A fronte di queste problematiche e della necessità di adattare l’applicativo alle nuove tecnologie utilizzate internamente, la società ha deciso di effettuare un refactoring del proprio sistema EDI. 5.4 Gli elementi del refactoring Gli elementi di cui alla sezione 5.3 sono stati affrontati come descritto di seguito. Aggiornamento codice Per risolvere questo problema sono state analizzate tutte le funzioni di importazione e di esportazione al fine di considerare con quale frequenza fossero applicate in maniera simile. Buona parte delle funzioni utilizzate sono risultate essere ripetute con differenze minime in diverse porzioni di codice. 27 5.4 Gli elementi del refactoring Figura 5.1: Funzione di importazione file generica Negli esempi in figura 5.1 e figura 5.2, si può notare come due funzioni differenti espletino il medesimo compito, se non per un controllo effettuato sulla nazionalità dello store. Figura 5.2: Esempio di funzione di importazione file per UK 28 5.4 Gli elementi del refactoring Statement if L’abuso di statement if è un elemento di elevata complessità logica, per cui è stata necessaria particolare attenzione. Il report vendite originale conteneva dei controlli, implementati nel corso degli anni, basati sulle esigenze dei clienti. L’inserimento di questi controlli era stato effettuato senza porre particolare attenzione alla base di codice nella sua interezza e in assenza di una contestuale rifattorizzazione del resto del codice esistente. La mancanza di attenzione posta nei confronti dell’evoluzione della base di codice ha contribuito a produrre un applicativo la cui esecuzione è rallentata dalla presenza di un numero elevato di controlli puntuali, e la cui manutenibilità è compromessa dalla facilità con cui ogni modifica a detti controlli può provocare errori a cascata. Figura 5.3: Esempio di abuso di statement if 29 5.5 Il nuovo report vendite Per risolvere questo tipo di problema inizialmente è stata effettuata un’analisi macroscopica del modulo EDI, identificando i punti in cui era possibile effettuare trasformazioni che non modificassero la semantica del codice. In secondo luogo è stata portata a termine un’analisi più dettagliata, identificando i pezzi di codice che potevano essere ottimizzati. Gestione delle eccezioni La gestione delle eccezioni dello script originale non prevede la gestione della classe puntale di eccezione, secondo la vecchia sintassi di Python. Tutte le eccezioni sono catturate in modo generico, non prevedendo una loro gestione precisa sul tipo di errore. Ciò non permette, in fase di test, di capire facilmente quale istruzione abbia causato il sollevamento dell’eccezione, né la ragione per cui l’eccezione sia stata sollevata. Un esempio di questa bad practice è visibile nella figura 5.1. Nomi variabili Ci siamo trovati spesso di fronte a variabili i cui nomi esprimevano le iniziali di quello che il programmatore pensasse essere il nome più adeguato da attribuire alla variabile. La difficoltà più grande incontrata in questo contesto è stata la comprensione di quanto l’autore originale intendesse ottenere, in maniera tale da poter modificare il nome della variabile con uno più appropriato. Mancanza di commenti e documentazione Altro problema affrontato è stato la mancanza pressochè totale di commenti e documentazione del codice, cui abbiamo dovuto provvedere, in fase di riscrittura. 5.5 Il nuovo report vendite Nel nuovo report delle vendite sono state apportate delle modifiche che hanno migliorato la resa e la lettura del codice. In questa sezione riportiamo alcuni esempi di refactoring dei problemi precedentemente illustrati nella sez. 5.3. In merito alle funzioni di importazione che abbiamo illustrato nelle figure 5.1 e 5.2, evidenziamo un riutilizzo del codice. Le due funzioni sono state unificate ed è stato inserito un flag in ingresso che separa i due casi inizialmente suddivisi nelle due funzioni originali. Nella figura 5.4 è possibile osservare il risultato del refactoring di queste due funzioni. 30 5.5 Il nuovo report vendite Figura 5.4: Esempio di refactoring delle funzione di importazione Per quanto riguarda il problema relativo dell’abuso degli statement if, illustrati della figura 5.3, l’azione di refactoring si è mossa verso la costruzione di un dizionario di che contenesse come chiave la condizione dello statement if e come valore il valore che sarebbe stato assunto nel caso in cui il controllo if avesse avuto esito positivo. In questo modo, se in futuro dovesse essere necessario aggiungere una condizione, sarà sufficiente aggiungere l’elemento al dizionario. Così facendo il codice dovrebbe rimanere leggibile anche successivamente a modifiche. In figura 5.5 è possibile osservare la riscrittura di questo codice. 31 5.5 Il nuovo report vendite Figura 5.5: Esempio di refactoring sugli statement if Il problema relativo alle eccezioni non gestite è stato risolto specificando le classi di eccezioni che dovrebbero essere catturate (sintassi disponibile da versioni di Python). Questo ci ha permesso di migliorare la fase di test e di ridurre il tempo di debugging del report delle vendite. Un esempio di questo tipo di modifiche è visibile dalla figura 5.4. In diverse sezioni di codice abbiamo introdotto le comprensioni, una routine presente dalle ultime versioni di Python. Esse permettono di riprodurre un ciclo for in maniera semi-implicita tramite una singola istruzione. 32 5.5 Il nuovo report vendite 5.5.1 Comunicazione e iterazione Figura 5.6: Struttura della comunicazione delle chiamate Chiamate ai metodi L’utente effettua una chiamata al service da un entry point che può essere una richiesta diretta effettuata ad uno script o una richiesta indiretta effettuata tramite un browser (e Apache + CGI). L’entry point istanzia il controller richiesto e comunica con il locator per la richiesta del service. Nel caso l’applicativo richiesto fosse costruito su un’architettura 2-tier, nel caso in cui la chiamata al service avvenisse dal frontend, il locator effettuerebbe una chiamata ad un service remoto; nel caso in cui la chiamata fosse effettuata nello strato di backend, il locator indirizzerebbe la richiesta verso un service locale. Nella figura 5.7 possiamo osservare un diagramma di flusso che riprende la struttura descritta. 33 5.6 La struttura dell’applicativo Figura 5.7: Descrizione del flusso dei dati 5.6 La struttura dell’applicativo La struttura dell’applicativo di EDI è suddivisa su due livelli: frontend e backend. Entrambe le parti sono costruite sulla stessa struttura ad albero composta da: • un package che contiene le variabili e le funzioni comuni; • un package che contiene i dati di configurazione dell’applicativo; • un package per ogni funzionalità dell’applicativo. Ognuno di questi package è costruito sulla stessa struttura interna, composta da moduli che seguono il pattern MVC (che tipicamente rispecchiano la struttura descritta alla sezione 4.2). Frontend Si interfaccia con l’utente mediante una view, rappresentata da una pagina sul browser che comunica, tramite chiamate Javascript con il 34 5.7 Test dell’applicativo controller. È costituito di un database che contiene i dati relativi alla sessione e alle richieste che vengono fatte. Condivide con il backend una cache di memoria utilizzata per lo scambio di dati. Backend Si interfaccia con l’utente mediante uno script, un programma scritto in Python. L’interazione con lo script avviene lanciando lo script dal terminale oppure tramite un crontab configurato per il lancio automatico del programma. È costituito da un database che contiene i dati di sistema e i dati utili per il corretto funzionamento dell’applicazione. 5.7 5.7.1 Test dell’applicativo Test Driven Development Il test driven development (TDD) è un modello di sviluppo del software che prevede che la stesura dei test automatici avvenga prima di quella delle funzionalità, e che lo sviluppo del software applicativo sia orientato all’obiettivo di superare i test automatici precedentemente predisposti. Il TDD si articola in brevi cicli che constano di tre fasi principali, come mostrato nella figura 5.8 35 5.7 Test dell’applicativo Figura 5.8: Ciclo di sviluppo di TDD I cicli TDD Fase rossa Lo sviluppo di una nuova funzionalità comincia con la stesura di un test automatico volto a validarla. Poiché l’implementazione non esiste ancora, la stesura del test è un’attività creativa, in quanto il programmatore deve stabilire in quale forma la funzionalità verrà esibita dal software e comprenderne e definirne i dettagli. Perché la funzione di test sia completa, deve essere eseguibile e, quando eseguita, in questa fase, produrre un esito negativo (la funzione non è ancora stata implementata). 36 5.7 Test dell’applicativo Fase verde Il programmatore scrive la quantità minima di codice necessaria perché il test abbia esito positivo. Quando il codice è pronto, il programmatore lancia nuovamente tutti i test disponibili sul software modificato (non solo quello relativo alla funzionalità in corso di sviluppo). In questo modo, lo sviliuppatore ha modo di rendersi conto immediatamente di eventuali problemi causati nel resto del codice dalla nuova implementazione. La fase verde termina quando tutti i test sono superati con successo. Refactoring Quando il software supera tutti i test, il programmatore dedica una certa quantità di tempo alla rifattorizzazione, ovvero a migliorare la struttura della funzionalità implementata attraverso un procedimento basato su piccole modifiche controllate, volte a eliminare o ridurre difetti oggettivamente riconoscibili nella struttura interna del codice. Dopo ciascuna azione di refactoring, i test automatici sono ripetuti per accertarsi che le modifiche eseguite non abbiano introdotto errori. 5.7.2 Test sul report delle vendite Il report delle vendite, di cui abbiamo fatto il refactoring, è testato tutti i giorni attraverso l’utilizzo di dati reali sul venduto degli store. I dati ottenuti dallo script riscritto sono confrontati con i dati reali per determinarne eventuali discrepanze. Una discrepanza tra gli output dei due script può essere ricondotta a una di queste casistiche: • discrepanza di dati, dovuti al fatto che il nuovo script interroga fonti di dati diverse rispetto allo script originale (che utilizza sistemi societari legacy in via di dismissione); • disallinemanto dei dati tra ambiente di test e ambiente di produzione; • errori sul codice, dovuto al refactoring delle funzioni. La prima e la seconda situazione non rappresentano un errore, ma devono essere confermate per evitare potenziali errori logici del programma. L’ultimo caso, prevede l’indagine dell’errore e la sua risoluzione all’interno del codice. 37 Conclusioni Dall’analisi effettuata post implementazione è emerso che, a livello funzionale, l’intervento di refactoring ha generato ottimizzazioni in termini di: • riduzione dei tempi di esecuzione; • riduzione dell’utilizzo di risorse di sistema; • riduzione del carico sul database; • manutenibilità e leggibilità. Tempi di esecuzione Il report delle vendite originale utilizzava diversi cicli for, anche annidati su più livelli. Dalle ultime versioni di Python, sono state introdotte le comprensioni e i generatori. Le comprensioni sono un sistema per costruire iterabili a partire da un iterabile esistente; si comportano come un for, ma sono implementate, come il resto delle componenti base di Python, in C. L’utilizzo delle comprensioni permette di evitare l’utilizzo di un ciclo for esplicito in Python che dovrebbe essere interpretato. I generatori, invece, sono delle routine che si comportano come una funzione che ritorna un valore ogni volta che è chiamata. Questo consente di ridurre l’allocazione della memoria rispetto ad oggetti come le liste. Utilizzo di risorse di sistema L’utilizzo di web service, l’ottimizzazione delle chiamate ai metodi dell’applicativo e l’utilizzo delle strutture dati disponibili nelle nuove versioni di Python (molte delle quali scritte nativamente in C) ci ha consentito di ottenere un notevole risparmio sulle risorse utilizzate. Le query vengono demandate a database delocalizzati limitando il carico delle macchine locali. Nel nuovo report vendite abbiamo introdotto l’utilizzo della programmazione ad oggetti, non sfruttata nello script originale. Anche l’introduzione dello 38 5.7 Test dell’applicativo sviluppo object oriented del codice favorisce il risparmio di memoria utilizzata. Inoltre, con questo metodo non interpretiamo l’intero modulo ad ogni chiamata, ma rendiamo disponibili diversi moduli tramite l’importazione dei relativi file compilati, in formato .pyc Carico sul database Nello script originale, le query erano inserite all’interno delle singole funzioni, ogni volta che si doveva effettuare un’operazione sul database. Nel nuovo report vendite abbiamo creato un file che gestisce tutte le query al database. Questo ci ha permesso di creare delle funzioni "standard" che esprimono le query generiche alle quali noi possiamo inviare i parametri senza la necessità di inserire la query esplicitamente nella funzione. Questa strategia, oltre a rendere il codice più leggibile, ci ha consentito di ridurre gli errori che affliggevano diverse funzioni a causa del codice ripetuto. Manutenibilità Uno dei vantaggi principali ottenuti dal refatoring di questo sistema riguarda la leggibilità del codice, rendendo più agevoli le future modifiche. Nello script originale, infatti, le ripetizioni di blocchi di codice, l’abuso degli statement if, l’impropria gestione delle eccezioni e l’utilizzo di nomi di variabili e funzioni che non esprimono il reale contenuto, rendeva complicate le modifiche, favoriva la propagazione di errori e rendeva difficile la comprensione del flusso del codice. Sviluppi futuri Trattandosi di un progetto per un’azienda, tra gli sviluppi futuri dell’applicazione si possono identificare: • refactoring migliorativo delle funzioni atto a minimizzare gli errori; • risolvere il disallinemento tra i database utilizzati dagli applicativi in produzione e quelli utilizzati per i test; • ridurre i colli di bottiglia identificando ed agendo sulle funzioni critiche; • effettuare il passaggio in produzione e presa in carico di nuovi clienti. 39 Ringraziamenti Desidero porgere i miei ringraziamenti al mio relatore Armando Sternieri, che con il progetto EDI ha reso possibile la realizzazione di questo sogno, e al mio correlatore, Pietro Mascolo, che mi ha guidato durante la realizzazione di questo progetto. Un ringraziamento va anche al corpo docenti che ha contribuito ad accrescere le mie conoscenze e ad avere una visione chiara delle tecnologie e degli strumenti informatici. Desidero inoltre ringraziare la mia famiglia e i miei genitori che mi hanno sostenuto in ogni modo. Non dimentico di ringraziare Ioji che mi è stato accanto, che mi ha aiutato e che mi ha sostenuto con ogni mezzo. Lo ringrazio soprattutto perché ha creduto in me prima ancora che io stessa potessi solamente pensare di crederci. Un ulteriore ringraziamento va a Tuno che mi ha aiutato e mi ha insegnato che un esame è solo un test di conoscenza e non una modalità di tortura riconosciuta dallo stato italiano. Ancora, ringrazio PN che nei momenti più difficili non mi ha lasciato sola, proponendo il suo aiuto anche in ambiti a lui ignoti e illuminandomi attraverso l’uso degli elementi della sua "P-list". Ringrazio La banda dei Nerd che mi ha accompagnato e sopportato durante tutti i pasti in mensa e che mi ha allietato i pomeriggi giocando a UT. Dedico un grazie ai miei fratelli e alle mie sorelle che mi hanno incoraggiato durante questo cammino e alle mie counselors, July e Paola, che sono state distanti con il corpo ma vicine con il cuore. Grazie a tutta la gente che ho conosciuto in questi anni che mi ha donato sorrisi, affetto, comprensione e aiuto, ai quei matematici che mi hanno saziato di partite a Briscola e a coloro che mi hanno permesso di dare vita alla mia fantasia giocando a Lupus. Ringrazio i miei colleghi che mi hanno accolto in azienda e in particolare sul 40 5.7 Test dell’applicativo progetto EDI. Un ulteriore ringraziamento va anche a tutti quelli che non sono stati citati esplicitamente ma che hanno contribuito alla mia crescita facendo sì che io diventassi ciò che sono. In ultimo, ma non per poca importanza, ringrazio Colui che mi ha pensato prima ancora che il mondo fosse, che ha scritto la mia storia, che ha creduto in me, che ha combattuto con me, che mi ha insegnato a combattere guardando la meta senza voltarmi né a destra né a sinistra. Colui che mi è stato accanto in ogni istante, che ha asciugato ogni mia lacrima e contato ogni mio sospiro. Colui che ha cambiato la mia tristezza in danza. Colui che ha dato vita ad un sogno da me archiviato perché ritenuto irrealizzabile. Colui che mi ha stupito con il tuo grande e immenso amore. A Lui dedico tutto questo! Infinitamente grazie, Papà! 41 Bibliografia [1] Kantor, Michael; James H. Burrows, Electronic Data Interchange (EDI), National Institute of Standards and Technology. Retrieved 2008-05-13. [2] Gifkins, Mike; Hitchcock, David, The EDI handbook, 1988, London: Blenheim Online [3] Ecommerce advantages of EDI format, http://ecommerce.hostip.info/pages/384/Electronic-Data-InterchangeEDI.html [4] Dwyer, Christopher, A Comparison of Supplier Enablement Around the World, 2008 [5] Wikipedia, http://it.wikipedia.org/wiki/Crontab [6] AntiPatterns, https://www.ics.com/designpatterns/book/antipatterns.html [7] Software Engineering, Roger S. Pressman, 2001, McGraw-Hill [8] Wikipedia, http://it.wikipedia.org/wiki/Model-View-Controller [9] Flask: web development, one drop at a time, http://flask.pocoo.org/ [10] Majestic Kari Jobe, I Am https://www.youtube.com/watch?v=I2oel0_Xa54 42 Not Alone,