Tu sei qui

Ingegneria del Software

Buy me a coffeeBuy me a coffee

Ingegneria del Software: gestione della complessità

Ultimo aggiornamento: 1 Maggio 2019

Quanto segue deriva dalla mia esperienza nell'Ingegneria del Software per applicazioni mobili e dai miei tanti errori e correzioni di rotta...

Linee guida di base per la gestione della complessità in un progetto software

  1. Rapportati continuamente con gli stakeholder e con altri sviluppatori, prendi l'abitudine di usare in maniera proficua piattaforme di mutuo aiuto tra sviluppatori come StackOverflow e Github, costruisci rapporti umani di fiducia, cerca di far parte di un team in cui il tuo lavoro è apprezzato e valorizzato (cioè retribuito) e stai lontano da ambienti dove le relazioni umane invece di essere costruttive sono distruttive.
  2. Chiarisci il problema da affrontare, poi pensalo ad oggetti, lavoralo ad oggetti, struttura tutto ad oggetti. Scegli un linguaggio che ti direzioni correttamente e ordinatamente a lavorare ad oggetti (Java).
  3. Fa che i tuoi strumenti di lavoro riducano al minimo il tuo sforzo e che ti regalino la massima compatibilità multi-piafforma: un'eccellente scelta lato client è l'approccio "write once run anywhere" di Codename One, un'ottima scelta lato server è l'approccio "production-ready" di Spring Boot.
  4. Il codice deve essere organizzato secondo un approccio top-down, nella maniera più intuitiva possibile: parti da una visione globale del problema, struttura il codice in livelli diversi, in modo che ogni funzionalità complessa sia alla fine ridotta ad una sola riga di codice (o quasi), la cui implementazione sia la più generica possibile (finché ha senso generalizzare in base al contesto e finché è verosimile che sia utile). Seguire un approccio top-down significa anche fare in modo che i problemi implementativi siano il meno possibile bloccanti rispetto al progetto complessivo.
  5. Suddividi il lavoro in task programmabili: un approccio top-down rende realistica la creazione di una serie di compiti che possono essere programmati senza conoscerne ancora l’effettiva implementazione, permettendoti di avanzare con maggior sicurezza e senza perdere l’orientamento anche quando le cose da tenere a mente (ovvero le questioni aperte su cui stai lavorando) sono tante.
  6. Prima di scrivere il codice, valuta varie alternative, magari facendo grafici, disegni o procedure anche su carta, e scegli l’algoritmo meno incasinato e più vicino alla logica di funzionamento del tuo ambiente di sviluppo (ad es., il più vicino possibile alla logica delle API di Codename One).
  7. Tra le varie alternative di algoritmi, parti sempre dalla soluzione che ti pare più semplice e che “approssima” sufficientemente il problema, creando un apposito test case: l’aggiunta di dettagli o di perfezionamenti dovrebbe essere indipendente dal progetto complessivo, in modo da isolare le singole funzionalità, e dovrebbe avvenire solo quando il codice più semplice è sufficientemente collaudato.
  8. Ogni parte del codice deve essere autoesplicativa, si deve capire velocemente cosa fa: ne segue che non ci devono essere casini, cioè ogni codice che può apparire criptico va evitato, oppure, in casi particolari che proprio richiedono un codice non intuitivo, questo va isolato e adeguatamente documentato. Anche la scelta dei nomi dei package, dei nomi delle classi e della collocazione delle classi all'interno dei package dovrebbe essere autoesplicativa.
  9. L’aggiunta o la modifica di funzionalità dovrebbe essere agevole: ciò è una naturale conseguenza dei punti precedenti se applicati correttamente. Più è grande il progetto, infatti, e maggiore è il bisogno di rendere il codice manutenibile e comprensibile anche a distanza di tempo. Evitare grossi blocchi di codice, isolare i problemi e ridurre la ridondanza sono d'aiuto.
  10. In progetti complessi, i dettagli implementativi potrebbero essere inseriti in un apposito package diverso dal resto del progetto (una sorta di package che contiene solo utilities).
  11. L'esecuzione di test e lo sviluppo vanno di pari passo: fai i test di ogni pezzo di implementazione sia nel simulatore (di Codename One) sia sui target previsti dal tuo progetto (ad es. Android, iPhone, Web-App, ecc.). Soprattutto quando sviluppi multi-piattaforma, non dare per scontato che le cose funzionino sempre come previsto: per ogni modifica o aggiunta su cui hai dubbi, è sempre meglio fare verifiche su target diversi.
  12. Fai release frequenti del tuo lavoro e sottoponile agli stakeholder: ciò serve sia da testing, sia da costante verifica del corretto perseguimento degli obiettivi del progetto.
  13. Ogni volta che si verifica un imprevisto o un'anomalia non chiara, è meglio isolare il problema in un test case sufficiente a riprodurlo, usando il minimo strettamente indispensabile di righe di codice: ciò è molto utile anche per chiedere aiuto ad altri sviluppatori (anzi, di solito è l'unico modo proficuo per poter chiedere aiuto). Repetita iuvant: se qualcosa non va, ma il codice è corretto o ti sembra tale, isola il problema e chiedi ad altri sviluppatori, piuttosto che tentare di raggirare il problema inserendo ulteriore codice.
  14. Quando capitano cose che ti appaiono impossibili o insensate, è il momento di fare una pausa. Soprattutto quando sei assolutamente certo che il tuo codice deve fare una cosa e invece ne fa un'altra... spegni il computer e vai a fare altro.
  15. Quando per risolvere un problema semplice il tuo codice si fa via via sempre più complesso e ti sembra di aver perso il controllo di ciò che fa o di come interagisce con il resto dell'app, allora... calmati, accetta l'ipotesi che forse hai speso ore e ore nella direzione sbagliata e, a mente serena e riposata, affronta di nuovo il problema da capo.
  16. Usa un ambiente di sviluppo (IDE) che ti agevoli nel conservare copie del tuo lavoro risalenti a momenti diversi e che, ogni volta che sarà opportuno, ti permetta di annullare le modifiche per tornare a uno snapshot precendetemente salvato: una soluzione valida può essere Netbeans all'interno di un ambiente virtualizzato (ad es. con VirtualBox). Questo approccio dà grande libertà di sperimentare senza paura di far danni o di perdere il lavoro fatto.

Francesco Galgani,
1 maggio 2019

Codename One: eccellente per sviluppo mobile multi-piattaforma (Android, iPhone, Web-App, ecc.)

Ultimo aggiornamento: 9 Maggio 2019

In un mio precedente articolo dedicato a "Linee guida di base per la gestione della complessità in un progetto software", ho citato Codename One come un'eccellente scelta lato client per la massima compatibilità multi-piattaforma nello sviluppo di applicazioni mobili.

Per tanti motivi tecnici ed umani, considero Codename One come il migliore strumento per sviluppare per Android, per iPhone (e quindi iOS), per applicazioni web (web-app basate su javascript). Ciò non toglie che lo stesso identico codice scritto in Java con Codename One funzioni anche su altre piattaforme su cui non ho esperienza diretta (ad es. Windows Phone, applicazioni desktop per Windows e per MacOs, ecc.).

Per sviluppare con Codename One esiste un'ampia documentazione sul sito di riferimento, oltre a corsi veri propri nella Codename One Academy, che partono dalle basi sino ad arrivare allo sviluppo di applicazioni complete (lato client e lato server) tipo Facebook, Uber, Whatsapp, ecc. Tutti i corsi in questione, comunque, presumono una conoscenza di base di Java e un minimo di cognizione di come si struttura un progetto software: nulla di eccezionale, ma un po' di basi sono necessarie.

Uno di questi corsi è disponibile anche come e-book e come libro cartaceo, sul sito: https://uber.cn1.co/, in cui potete leggere anche un mio feedback nella sezione in basso "Testimonials".

Stando così le cose, mi pare superfluo aggiungere spiegazioni tecniche su qualcosa che è già abbondantemente documentato sicuramente meglio di quanto io possa fare. Ciò non toglie che in futuro, tempo permettendo, io possa realizzare dei corsi per lo sviluppo di applicazioni mobili per chi proprio parte da zero: in passato, nell'arco degli anni, ho fatto varie docenze in ambito informatico e sono state tutte esperienze positive e soddisfacenti, soprattutto in occasione dei LinuxDay.

Il motivo per cui sto scrivendo questo articolo è che Codename One, paradossalmente, nonostante le eccellenti opportunità che semplificano la vita a noi sviluppatori, offrendo una piattaforma di sviluppo molto leggera, integrata con un plugin negli IDE più comuni (Netbeans, Eclipse, IntelliJ Idea), con un tempo di sviluppo e di apprendimento significativamente inferiore rispetto a quei mattoni come Android Studio o XCode, è relativamente poco conosciuto. Il mio invito è: "Usatelo e spargete la voce!".

Dal mio punto di vista, le persone che hanno creato Codename One e che continuano a svilupparlo attivamente sono geniali e molto disponibili. In tanti anni di informatica, in cui mi sono dovuto confrontare con il supporto tecnico di varie aziende piccole e grandi (da piccole software house sino a giganti come Apple e Google, da piccoli servizi di hosting sino a grandi server farm, da piccole realtà locali sino ad aziende internazionali), non ho mai incontrato così tanta attenzione, competenza, velocità di risposta, tempestiva correzione di bugs da me segnalati (spesso il giorno stesso, specialmente quando sono riuscito a segnalarli con "test case" molto precisi) e aggiunta di nuove funzionalità da me richieste (anche obiettivamente complesse) come con Codename One. Da questo punto di vista, la qualità del supporto tecnico di Codename One è superiore ad ogni altra che io abbia sperimentato e di gran lunga migliore di ogni mia ragionevole aspettativa basata sulle mie precedenti esperienze. I principali canali di comunicazione con il supporto tecnico di Codename One sono StackOverflow (per dubbi su come scrivere il codice) e GitHub (per segnalare bug della piattaforma o per RFE, che significa "request for enhancement", cioè richieste di miglioramenti o aggiunte di funzionalità).

Il codice sorgente delle API di Codename One è open-source (licenza GPL v.2), il che costituisce un grosso vantaggio in fase di sviluppo: spesso vado a curiosare nei sorgenti per meglio rendermi conto di come il mio codice andrà a interagire con quello di Codename One. Non solo: lo sviluppo è aperto a chiunque abbia voglia e competenza per contribuire. Io stesso ho inviato alcune PR (pull request) per aggiungere alcuni importanti funzionalità (come segnalato nelle pagine qui elencate), cioè codice scritto da me che è stato prontamente analizzato e discusso prima di essere integrato in Codename One. E' possibile contribuire anche pubblicando estensioni per Codename One: se guardate nella lista, ne troverete anche una scritta da me. Le estensioni, diversamente dalle API ufficiali, non sono direttamente supportate dal team di Codename One (salvo alcune) e non necessariamente sono funzionanti con tutte le piattaforme ufficialmente supportate da Codename One, ma spesso con un sottoinsieme di esse.

In sintesi, i soldi investiti su Codename One sono soldi investiti bene. Il costo di questo tipo di piattaforma è variabile, si va da account gratuiti sino ad account enterprise: dipende dal tipo di esigenze.

Un mio speciale ringraziamento va a Shai Almog e Steve Hannah per l'eccellente supporto finora ricevuto.

Francesco Galgani,
9 maggio 2019