01 - Architetture Software
Processo
1. Capire il contesto
Requisiti funzionali
Per requisiti funzionali si intende l'insieme di:
- scopo generale dell'applicazione
- tutte le interazioni tra l'utente e il software
- eventuali processi che il software deve eseguire in background
- eventuali interazioni con altri sistemi
Esempi
Alcuni esempi di queste specifiche sono:
- l'utente deve poter aggiungere articoli a un carrello
- l'utente deve poter completare l'acquisto con carta di credito
- l'utente viene notificato quando l'articolo viene spedito
- il sistema deve processare il pagamento e confermare l'ordine
- il sistema deve comunicare col software del magazzino per far partire la spedizione
- ecc
Requisiti non funzionali
Queste sono generalmente le caratteristiche che rispondono alla domanda "Come si dovrebbe comportare il sistema?".
Vengono anche chiamate "ilities", il perché si può capire dalla lista dei termini inglesi che le definiscono:
- Reliability (affidabilità): capacità di funzionare senza fallire
- Usability (usabilità): capacità fornire una buona esperienza per l'utente
- Accessibility (accessibilità): possibilità di essere usato anche da persone affette da diverse disabilità
- Availability (disponibilità): la capacità di un sistema di essere pronto a svolgere il proprio compito
- Configurability (configurabilità): la predisposizione ad essere configurato per esigenze diverse
- Scalability (scalabilità): la capacità di gestire un carico di lavoro crescente
- Maintainability (mantenibilità): capacità di essere modificato a distanza di tempo
- altri: wiki
Alcuni requisiti, come ad esempio scalabilità, affidabilità e disponibilità, vengono solitamente accompagnati da metriche. Per la scalabilità di potrebbe dire ad esempio che si prevedono 50k utenti giornalieri, per availability di solito si esprime l'uptime in forma di "9" (99.9% di uptime).
Alcuni questi valori sono suddivisi per requisito funzionale se è utile a descrivere un caso particolare da gestire. Ad esempio sempre per la scalabilità si potrebbe dire che ogni utente ascolta 2h di musica al giorno a un bitrate di 320kb/s.
Esempi
- è un sistema cruciale per l'operatività del cliente -> particolarmente importante che torni sempre risultati corretti (reliability)
- è un'applicazione che deve raccogliere i dati dei punti vendita di diversi clienti -> è importante che possa gestire un alto numero di traffico (scalability)
- opera in un settore dove i clienti hanno esigenze leggermente diverse l'uno dall'altro -> deve essere configurabile (configurability)
- raccoglie i dati dai macchinari e coordina le operazioni -> un downtime causa perdite economiche non accettabili quindi deve essere sempre funzionante (availability)
- è il primo passo di un progetto a lungo termine per il cliente -> devo assicurarmi di tenere la struttura abbastanza flessibile da accogliere modifiche e nuove funzionalità (maintainability)
Requisiti esterni
In questa categoria ricadono tutte le valutazioni/richieste/limitazioni che non riguardano direttamente le caratteristiche della soluzione ma possono avere un impatto nelle scelte da fare.
Esempi
- budget: mantenere servizi replicati e distribuiti supera i guadagni previsti per la soluzione, serve un compromesso
- time to market: è stata promessa una demo al cliente entro 3 mesi e non c'è tempo per implementare la soluzione ideale dal punto di vista tecnico
- aspetti legali: GDPR, devo assicurarmi che i servizi usati siano compliant e di gestire i dati nel modo corretto
- competenze: il team non ha le competenze necessarie ed è difficile trovare abbastanza persone competenti sul mercato
- ecc
2. Dare una priorità
Prima di elaborare una soluzione è utile assegnare una priorità ai requisiti raccolti.
Tendenzialmente i Requisiti funzionali sono quelli che si cerca di mantenere a tutti i costi, in quanto descrivono il valore offerto dall'applicazione.
I Requisiti non funzionali sono in genere caratteristiche importanti ma che non è detto siano assolutamente necessarie, soprattutto in una fase iniziale.
I Requisiti esterni di solito (ma non necessariamente) rappresentano dei limiti per i quali bisogna rivedere le altre due categorie e fare dei compromessi.
L'obiettivo di questa fase è individuare possibili requisiti in conflitto tra loro e stabilire quali compromessi considerare accettabili in fase di progettazione.
Siamo ancora nella fase di raccolta e preparazione, è probabile che emergano nuovi problemi durante la progettazione.
(ad esempio si può avere un'idea di costi e tempi ma la stima precisa è ancora da fare)
E' quindi normale tornare a questa fase e ridefinire la priorità se emergono nuovi fattori.
Quando si progetta una soluzione viene naturale immaginarla nel futuro già completa con tutte le sue funzionalità e magari con un grosso volume di utenti, e questo fattore umano torna utile per identificare la lista del punto 1.
La valutazione delle priorità deve però tenere conto del fattore tempo. Bisogna stare attenti a non ostacolare una caratteristica che sarà importante in futuro ma dare più importanza a quelle che hanno un impatto immediato.
Esempi:
Se il budget per l'hosting è limitato si può ragionare su availability e scalability per ridurre il costo dei server finché non diventa necessario.
Se il time to market è molto stretto si può valutare se ridurre i tempo di sviluppo ridimensionando un po' la configurabilità o facendo dei compromessi sulla mantenibilità. Oppure si può rivedere le caratteristiche funzionali e concordare un set ridotto che permetta di stare nei tempi.
3. Progettare una soluzione
A partire dalle valutazioni dei punti precedenti vengono identificati i componenti necessari a soddisfare i requisiti.
Questo passaggio richiede ragionamenti e attività diversi a seconda dei requisiti raccolti e delle problematiche che presentato. Non esistono regole fisse né soluzioni perfette, una buona traccia di ragionamento però potrebbe essere:
- Partire con la rappresentazione più semplice possibile. La maggior parte dei software può essere rappresentato a layer (frontend, logica backend, database) e pensato come una soluzione monolitica.
- Identificare i punti che sono più critici se implementati in una soluzione di questo tipo. Sempre tenendo presente le priorità assegnate. E' anche possibile raggruppare i requisiti per aree funzionali o caratteristiche comuni.
- Espandere la soluzione in modo da risolvere i problemi del punto precedente. A seconda del problema potrebbe bastare aggiungere un layer o essere necessario dividere la soluzione in servizi diversi, o ancora introdurre nuovi componenti (database, cache, ecc)
- Verificare che la soluzione proposta non sia in conflitto con altre caratteristiche importanti.
- Ripetere dal punto 2 fino a raggiungere una soluzione compatibile con la lista di priorità
A noi sviluppatori piace farci prendere la mano e arrivare a una architettura più complessa del necessario (overengineer).
Bisogna però tenere presente che nella lista delle priorità ci sono anche voci come budget, time to market e maintainability. Una soluzione che non ne tiene conto non si può definire ottimale.
Tipologie di infrastruttura
Monolitica (Layered)
La soluzione finale si presenta come un unico blocco che contiene tutte le funzionalità richieste. Nel mondo web un'applicazione viene definita monolitica anche se è divisa tra frontend, backend e database. Questo perché comunque tutta la business logic è contenuta un unico applicativo lato backend.
Per Layered si intende un'applicazione il cui codice è suddiviso a strati e blocchi per aree funzionali, seguendo il principio di separation of concern. C'è un po' di dibattito sul fatto che una infrastruttura layered sia per forza monolitica o meno. Tecnicamente ogni layer potrebbe vivere in un processo diverso e quindi la soluzione non sarebbe più monolitica. La realtà dei fatti però è che tendenzialmente questo tipo di suddivisione esiste solo a livello di codice (controller, services, models) e quindi la soluzione è comunque monolitica con un unico processo.
A mio avviso quindi è più utile parlare di Monolita quando si fa una analisi architetturale e di Layer quando studia la struttura del progetto, ma è importante sapere che Layered è spesso listato come pattern architetturale.
Pro
- è meno complessa da progettare
- il deploy è più semplice
- se sviluppata bene è più semplice seguire il flusso della logica
- è tendenzialmente più veloce da realizzare
- per applicazioni "semplici" è meno costosa in termini di costi infrastruttura
Contro
- può scalare solo l'intera applicazione (anche se alcune funzionalità sono poco utilizzate)
- per applicazioni complesse è difficile mantenere una suddivisione ordinata del codice
- tutto il team lavora sullo stesso codice sorgente
- è solitamente basata su un unico stack tecnologico
- un eventuale crash interrompe tutte le funzionalità del processo
Microservizi
La soluzione è composta da una suite di piccoli servizi divisi per funzionalità, ognuno con il proprio processo. Ogni servizio svolge il minor numero possibile di attività ed è sviluppato ad hoc per il suo scopo.
E' importante prestare attenzione ad alcuni punti quando si progetta una soluzione a microservizi:
- applicare il principio di separation of concern per suddividere la logica tra i servizi
- minimizzare la dipendenza tra i servizi stessi
- evitare di introdurre single point of failures
- i dati dovrebbero essere decentralizzati (ogni servizio gestisce i suoi)
- ogni servizio dovrebbe essere aggiornabile separatamente
- scegliere le modalità di comunicazioni migliori a seconda dei casi
Pro
- scalabilità indipendente per area funzionale
- possibilità di lavorare su singole parti in modo indipendente
- velocità di startup e deploy perché applicazioni più piccole
- possibilità di scegliere tecnologie diverse a seconda della necessità
- codice indipendente per ogni servizio
- se sviluppata bene un crash di un servizio non impedisce al resto dell'app di funzionare
- per applicazioni con grosse moli di traffico la scalabilità indipendente permette di ridurre i costi
Contro
- più difficile da progettare
- più lunga da sviluppare
- più difficile da testare
- la comunicazione tra microservizi tendenzialmente rende le operazioni più lente
- ha più parti che se progettate erroneamente possono causare problemi di performance, disservizi o aumento dei costi (vedi lista sopra)
Microkernel
Anche se principalmente legata allo sviluppo di sistemi operativi (linux kernel) viene spesso nominata come tipologia di architettura anche per altri software, a volte è anche chiamata Plugin Architecture.
Prevede che l'applicativo abbia il minimo indispensabile di funzionalità necessarie alle operazioni base e deleghi il resto delle operazioni a plugin che possono essere attivati o meno a seconda dell'installazione.
In questo caso la soluzione finale prevede comunque un unico processo, e vengono sviluppati e installati una serie di plugin che tutti assieme compongono il funzionamento finale dell'applicazione.
Decisamente meno utilizzata in ambito di sviluppo web, può comunque essere utile per gestire alcuni casi particolari.
Prendiamo ad esempio un'applicazione per gestire l'avanzamento della produzione nelle aziende. Ogni azienda ha chiaramente esigenze diverse: produce articoli diversi, ha reparti diversi, macchinari diversi, ecc.
In questo casi sviluppare un'applicazione con codice uguale per tutti e abbastanza configurabile sarebbe quasi impossibile. La strategia potrebbe essere quindi quella di sviluppare un'applicazione standard con le funzionalità minime (utenti, analisi report, strumento creazione flussi, monitoraggio, ecc) ma delegare le logiche specifiche (reparti, linee produzione) a dei plugin che vengono sviluppati su misura per ogni cliente.
Componenti
Technical breadth
Nello studio di una architettura spesso non basta decidere se usare un monolita o dei microservizi. Alcuni problemi sono più semplici da risolvere se si adottano componenti software specializzati o prodotti specifici:
- Database adatti al tipo di dato e di utilizzo
- Storage specializzati per i tipi di dato da salvare
- Protocolli di comunicazione
- Events o Queue managers
- Load Balancer, CDN, cache, API Gateway
- Linguaggi o framework particolari
- ecc
Viene spontaneo domandarsi come una persona possa conoscere tutte queste possibili soluzioni, in particolare se si trova davanti a un problema per la prima volta.
La risposta è che non può e non è necessario, basta che le abbia almeno sentite nominare.
In un settore così vasto è utile suddividere gli argomenti in 3 categorie:
- le cose che si conoscono: quelle con cui si ha già lavorato o sperimentato
- le cose che si sa di non sapere: quelle che si sono sentite nominare collegate a un concetto, ma su cui non si hanno altre esperienze
- le cose che non si sa neppure che esistano: tecnologie o concetti mai neanche sentiti
La combinazione delle prime due categorie è chiamata technical breadth e cresce entrando in contatto anche marginalmente con più informazioni possibile del settore.
Non è necessario approfondire ogni argomento, basta avere le informazioni minime utili ad associare il nome alla soluzione che offre.
C'è una distinzione netta tra le prime due categorie. Se una tecnologia so che esiste ma non la conosco significa che devo studiarla più a fondo prima di capire se usarla.
L'obiettivo principale è quindi quello di ridurre le cose che non sai nemmeno esistano, il modo più semplice è tenere monitorate diverse fonti del settore: topic su medium, canali youtube, reddit, personaggi di spicco, ecc. Non serve approfondire la questione, anche il titolo o l'introduzione può bastare.
Service
Blocco generico che rappresenta un pezzo di logica con funzionalità distinte. Una soluzione può essere composta da uno o più di questi blocchi a seconda della complessità e dello stile architetturale scelto (monolitico o a microservizi).
Nello studio della soluzione è utile ragionare sui seguenti punti:
- eventuale replicazione a seconda del carico e dell'availability
- relazione tra servizi, quali scambiano informazioni e in che modalità
Database
Se una soluzione richiede di salvare dati è utile ragionare sulla tipologia di dati e i database più opportuni per gestirli:
- relazionale (MySql, PostgreSQL, MsSQL)
- nosql (Mongodb, DocumentDb, Cassandra)
- grafo (Neo4j)
- time series (InfluxDB, Prometheus)
- chiave valore (Redis, DynamoDb)
Altre valutazioni riguardano:
- replica
- sharding
- vertical scalability
- ecc
Storage
Utilizzato in caso l'applicazione preveda il salvataggio di file, solitamente quando si parla di soluzioni in cloud si sceglie tra i servizi offerti dal cloud provider.
Le valutazioni in questo caso riguardano:
- spazio necessario
- numero di operazioni di scrittura/lettura
- velocità del disco
- posizione geografica
- tipo di file
Load Balancer
E' una component software o hardware che appare all'esterno come un unico punto di accesso per il servizio ma smista il traffico tra più istanze a seconda di regole definite. Permettendo al servizio di scalare orizzontalmente senza effettuare modifiche al resto dell'applicativo.
Generalmente la configurazione prevede un meccanismo per monitorare i servizi attivi e diverse strategie per smistare il traffico.
Il load balancer può agire su diversi livelli (L4-transport, L5-session, L6-presentation, L7-application). Generalmente si usano L4 o L7:
- Layer 4: indirizza il traffico in base a informazioni relative al protocollo di trasporto (IP, TCP, UDP, FTP, ecc)
- Layer 7: indirizza il traffico a seconda di informazioni legate all'applicazione (header http, url della chiamata, cookies, session id, ecc)
API Gateway
Fornisce un unico punto di accesso per le API in una architettura a microservizi.
Al suo interno contiene logica e configurazione per eseguire task comuni e chiamare il microservizio interessato.
Le operazioni che normalmente può svolgere sono:
- Centralizza le regole di routing
- Implementa sicurezza e autenticazione
- Applica trasformazioni sulle richieste per adattarle al servizio di destinazione
- Può integrare sistemi di cache
CDN
Una Content Delivery Network è un software che permette di distribuire contenuti al client in modo rapido. Nella sua forma più comune è la combinazione di:
- replicazione geografica
- cache
- storage
Configurando una CDN per essere geograficamente vicino all'utente finale e prepopolandola con i contenuti di più probabile interesse si garantisce un tempo di accesso e download molto breve.
Event Queue
Si tratta di software specializzati nella gestione di code di eventi. Se la soluzione lo richiede possono essere utilizzati per gestire delle code alle quali i vari servizi si iscrivono per ricevere notifiche (eventi) e eseguire le azioni che ne derivano.
Esistono diversi software con caratteristiche diverse in questa categoria, tra i più usati abbiamo:
- RabbitMQ
- Kafka
- Google Cloud Pub/Sub
- ecc
Altri
Altre possibili componenti possono essere:
- message brokers per lo scambio di messaggi
- serverless functions
- componenti network necessarie al funzionamento (VPN, ecc)
- altri software di terze parti con i quali la soluzione deve comunicare
Esempio (spotify)
Esercizio
Contesto
Un azienda di produzione vuole poter configurare e monitorare l'avanzamento degli ordini e della produzione tramite un sistema automatizzato comune ai diversi reparti coinvolti.
L'azienda gestisce diversi tipi di prodotti, ognuno ha un ordine di operazioni diverse da svolgere:
prodotto industrializzato
Sono articoli a catalogo che l'azienda produce internamente tramite le sue linee di produzione. Il prezzo è già fissato a listino e i materiali necessari sono già definiti.
Flusso:
- la richiesta d'ordine arriva all'ufficio commerciale
- il commerciale la valida e manda il preventivo al cliente
- ricevuta la conferma da parte del cliente avvia l'ordine di produzione
- le materie prime necessarie sono presenti a magazzino?
- no
- viene popolato un ordine di acquisto nel software del magazzino
- quando le merci vengono registrate in ingresso il processo viene mandato avanti automaticamente
- si
- va al punto successivo
- no
- viene popolato automaticamente un ordine di produzione nel software di gestione del reparto produzione
- quando la produzione parte viene inviata una notifica al commerciale
- quando la produzione finisce il software manda avanti automaticamente il processo
- viene popolato automaticamente l'ordine di spedizione nel software del magazzino
- quando la spedizione parte viene inviata una notifica sia al commerciale che al cliente
prodotto commercializzato
Sono articoli sempre a catalogo ma che l'azienda acquista e rivende, non sono quindi prodotti internamente. Il prezzo è già fissato a listino e il costo è già conosciuto.
Flusso:
- la richiesta d'ordine arriva all'ufficio commerciale
- il commerciale la valida e manda il preventivo al cliente
- ricevuta la conferma da parte del cliente manda avanti il processo
- ci sono già gli articoli richiesti a magazzino?
- no
- viene popolato un ordine di acquisto nel software del magazzino
- quando le merci vengono registrate in ingresso il processo viene mandato avanti automaticamente
- si
- va al punto successivo
- no
- viene popolato automaticamente l'ordine di spedizione nel software del magazzino
- quando la spedizione parte viene inviata una notifica sia al commerciale che al cliente
prodotti customizzati
Sono prodotti che non esistono a listino. Il cliente sceglie un prodotto industrializzato o commercializzato da cui partire e chiede che vengano fatte una serie di modifiche. In questo caso costo di produzione, materie prime e prezzo finale devono essere calcolati su misura.
Flusso:
- la richiesta d'ordine arriva all'ufficio commerciale
- viene generato un task per l'ufficio tecnico, che esegue la progettazione
- quando l'ufficio tecnico segna il task come completato ne viene creato uno per l'ufficio costi, che valuta il costo
- quando l'ufficio costi completa il task viene inviato un task al commerciale che calcola il prezzo finale e manda il preventivo al cliente
- ricevuta la conferma da parte del cliente avvia l'ordine di produzione
- le materie prime necessarie sono presenti a magazzino?
- no
- viene popolato un ordine di acquisto nel software del magazzino
- quando le merci vengono registrate in ingresso il processo viene mandato avanti automaticamente
- si
- va al punto successivo
- no
- viene popolato automaticamente un ordine di produzione nel software di gestione del reparto produzione
- quando la produzione parte viene inviata una notifica al commerciale
- quando la produzione finisce il software manda avanti automaticamente il processo
- viene popolato automaticamente l'ordine di spedizione nel software del magazzino
- quando la spedizione parte viene inviata una notifica sia al commerciale che al cliente
Altre caratteristiche generali:
- il flusso può avviare task (che vengono completati manualmente dall'utente) o integrarsi direttamente con sistemi esterni
- task, notifiche e flusso sono concetti generali, stiamo analizzando solo una parte del software ma le notifiche potrebbero essere usate anche per altro
- ogni volta che un utente riceve un task riceve anche una notifica che lo avvisa
- esiste il concetto di utente e di reparto, i task vengono assegnati all'intero reparto, con la possibilità poi di essere presi in carico da un utente specifico
- per semplicità un ordine può comprendere solo un articolo e quindi essere associato a un singolo flusso
- è possibile consultare in ogni momento tramite le api dell'ordine lo stato di avanzamento e la storia delle operazioni svolte, comprese di utente (o servizio) che le ha completate e timestamp
Sistema di gestione del flusso
L'idea è quella di creare il prototipo di un sistema di flusso flessibile e configurabile. L'azienda in futuro potrebbe voler cambiare un flusso esistente o aggiungerne di nuovi.
Per il momento è sufficiente sviluppare un prototipo che soddisfi le caratteristiche base, possibilmente creando già un sistema che elabori il flusso a partire da una configurazione (anche un file hardcoded per il momento, basta che ragioniate su come rappresentare le istruzioni).
Caratteristiche
- di base il servizio che gestisce il flusso comunica con l'esterno tramite eventi (sia per comunicare l'avanzamento sia per ricevere il completamento di un passaggio)
- per mantenere la compatibilità anche con sistemi forniti da terzi (produzione e magazzino ad esempio) sono disponibili altre due modalità di integrazione
- un webhook tramite cui è possibile configurare una api da chiamare quando il flusso arriva ad un punto specifico
- due api, una per ottenere la lista di flussi che è arrivata a un certo punto e una per avanzare una attività
- al momento esistono solo due tipologie di nodi nei flussi:
- azione richiesta (quello che genera task o invia gli ordini a magazzino)
- nodo condizionale, che sceglie strade diverse a seconda che la condizione sia vera o false
- per tenere il nodo condizionale generico renderlo configurabile in modo che chiami una api con eventuali parametri e riceva in risposta un json
{response: true}o false - ogni nodo del flusso ha un identificativo univoco, che servirà sia per aggiornarne lo stato (completamento) sia per richiamare i suoi dati
- in alcuni casi è necessario che un nodo del flusso contenga dei dati (ad esempio messagio del task) e ne riceva alcuni indietro al momento del completamento (ad esempio ufficio tecnico da la lista dei pezzi necessari). Utilizzando quanto detto al punto precedente possiamo immaginare che un nodo completato sia salvato nella forma:
{
"uid": "valuta_prodotti",
"kind": "step",
"status": "completed",
"config": {
"to": "ufficio_tecnico"
},
"request": {
"orderId": "1234"
},
"response": {
"items": [
{"id": 1, "qty": 5}
]
}
}
E nel nodo condizionale potrei richiamare i dati usando una forma simile a:
{
"uid": "in_warehous",
"kind": "condition",
"config": {
"url": "http://warehouse:8080/api/check-items",
"method": "GET",
"queryParams": {
"items": "$valuta_prodotti.response.items"
}
},
"request": {
}
}
In questo modo è possibile da ogni nodo richiamare o mandare informazioni proveniente da altri nodi precedenti. (La rappresentazione sopra è solo una ipotesi, e il formato dei dati non è completo)
Taks
Il sistema dei task è generico, tramite api o eventi altre parti del software possono creare task e ricevere notifiche sul completamento.
Per lo scopo dell'esercizio è sufficiente progettare il servizio in modo che comunichi con la logica del flusso descritta sopra. Vale la pena però progettare struttura dati e comunicazioni in modo che siano generici e non legati al caso specifico.
Caratteristiche
- un task nella sua forma base contiene un testo descrittivo dell'attività.
- esistono alcune tipologie di task particolari che richiedono l'inserimento di dati come risposta, in questo caso le informazioni aggiuntive sono passate come json (come gestire l'interfaccia grafica sarà un problema per qualcun altro)
- il client comunica con i task tramite api, richiede la lista e chiama le api per completarli
- per il momento non è necessario gestire l'eliminazione dei task
- un task deve essere assegnato o a un gruppo o a un utente specifico, se assegnato a un gruppo gli utenti di quel gruppo devono avere la possibilità di scegliere chi lo prende in carico
- ogni utente tra i suoi task vede quelli assegnati a lui e quelli assegnati al gruppo a cui appartiene ma non a una persona specifica
Notifiche
Anche il sistema delle notifiche è generico, sempre tramite api o eventi è possibile per le altre parti del software inviare notifiche.
A differenza dei task le notifiche sono individuali, se inviata a un gruppo viene automaticamente generata una notifica separata per ogni utente di quel gruppo. In questo modo è possibile tracciare individualmente quali notifiche ha letto ogni singolo utente (funzionalità non richiesta in questa fase).
Caratteristiche
- una notifica è semplicemente composta da un testo e una data
Svolgimento dell'esercizio
- Dividetevi in gruppi da 4
- Iniziate con una pre-analisi dei requisiti, preparate domande, considerazioni, idee, ecc
- le parti da sviluppare sono solamente notifiche, task e flow. Siete in 4 ma non voglio vedere nessuno inattivo, si può collaborare in due a una parte o sviluppare degli strumenti accessori per testare la soluzione.
- Io faccio il cliente, quando avete finito la prima fase venite da me per risposte e valutazioni
- Preparate la proposta dell'infrastruttura, in questa fase vorrei che faceste un po' di ricerca per capire:
- se ci sono software con caratteristiche simili, se si possono usare o se si può prendere spunto
- se ci sono dei software (db, broker, notification system) che potrebbero essere utili per realizzare la soluzione o ridurre il lavoro
- anche se decidete di non usare qualcosa di pronto (per costo o incompatibilità) vedete che formato dati usano, che tipo di comunicazione prevedono, ecc
- venite a discutere con me della soluzione proposta
- dividete il progetto in aree funzionali e assegnate a ognuno una parte da sviluppare
- ognuno prepara la lista delle attività e tempi e compilate il foglio come quello dell'altra volta
Il tempo non è tanto, dovete sviluppare un prototipo non un software da vendere. Lo scopo in questa fase è validare il minimo necessario per poi proseguire con lo sviluppo. Assegnate con cura le priorità ai requisiti in modo da riuscire a fare il più possibile della parte core.

