I pattern architetturali
Quando si decide di sviluppare un software, occorre sempre dedicarsi ad una fase di attento design pre-sviluppo, volto a realizzare un sistema che offra le funzionalità richieste. In questa fase ciò che si fa è individuare un’architettura del sistema che sia adatta a supportare i suoi scopi e abbia determinati requisiti.
Inventarsi un’architettura potrebbe però non essere così semplice e immediato. Per questo motivo esistono dei pattern architetturali già definiti. Per sistemi di grandi dimensioni è indispensabile definire le linee guida per lo sviluppo per evitare di perdere il controllo del software e di non rispettare i requisiti richiesti.
Cos’è un pattern architetturale
Generalmente viene definito come “una soluzione generale e riutilizzabile per un problema comune presente all’interno di un particolare contesto”. In sostanza un pattern definisce lo scheletro che dovrà avere il software, quali servizi dovranno entrare in gioco, le parti coinvolte e la logica di interazione tra di esse.
Simili ai design pattern ma applicati ad un contesto più ampio, i pattern architetturali sono fondamentali per il design di un enterprise software. Svolgono innanzitutto un ruolo di comunicazione tra gli stakeholders, ovvero i protagonisti del progetto, offrendo un’astrazione comune del sistema. I pattern offrono una base per la mutua comprensione, negoziazione e consenso, senza che sia richiesta conoscenza informatica dettagliata.
Un’architettura inoltre definisce l’organizzazione strutturale che dovrà essere rispettata, e potrà essere poi utilizzata come metro di valutazione del progresso del progetto. Sapendo esattamente quale aspetto dovrà avere il prodotto finale, sarà anche più semplice capire se ci si sta allontanando dai confini prefissati, ed eventualmente aggiustare il tiro.
Essa facilita inoltre la gestione del cambiamento, quando dovesse essere necessario. Conoscendo la struttura logica del progetto, è più facile individuare i punti dove andare ad agire e prevedere in che modo le diverse parti saranno influenzate dall’evoluzione del sistema.
Ultimo, ma non per importanza, assicura una maggiore robustezza del sistema rispetto ad altre possibili scelte architetturali pensate da zero. Essendo un modello studiato e testato, infatti, fornisce la soluzione ottimale per un problema o un’intera categoria di problemi.
Alcuni dei pattern più comuni
L’articolo della dottoranda Mallawaarachchi elenca 10 pattern architetturali più comuni. Li riportiamo e analizziamo.
- Layered. Probabilmente il più conosciuto, il layered è un pattern che, come dice la parola, è organizzato a livelli. Anche se non esiste un numero predefinito di livelli, i più utilizzati sono 5:
- livello di presentazione
- livello applicativo
- livello di business o di dominio
- livello di persistenza o di accesso ai dati
- livello del database
Ogni livello fornisce un’astrazione per quello successivo, e ha una sua “responsabilità” da gestire. Generalmente viene usato per applicazioni desktop e e-commerce. La maggior parte degli sviluppatori ha familiarità con questo livello ed è quindi più immediato da mettere in pratica, ma l’applicazione risultante è monolitica e difficile da eventualmente dividere in più parti.
- Client-server. Anch’esso tra i più conosciuti, è composto da due parti: client e server. La sua logica va di pari passo con l’idea delle applicazioni online. Il server è infatti quello che fornisce i contenuti e i servizi a più client, e resta in attesa delle loro richieste. Questo tipo di architettura è un’evoluzione della condivisione semplice delle risorse: il server, infatti, è in grado di soddisfare le richieste di più client e gestisce gli accessi per evitare conflitti.
- Master-slave. Un altro pattern con due parti, ma molto diverso dal precedente. Il master-slave viene generalmente utilizzato in sistemi che richiedono delle computazioni significative. Una componente eletta master distribuisce il lavoro tra degli slave identici tra loro, ottiene i singoli risultati e li utilizza per fornire quello finale.
- Pipe-filter. Mai sentito parlare di pipeline? Dietro di essa c’è l’idea di questo pattern. I sistemi costruiti seguendo le sue specifiche producono e processano stream di dati. I dati vengono manipolati tramite degli step, che sono inclusi in dei filtri. In essi avviene la modifica e alterazione dei dati. Le pipes, invece, sono responsabili dello spostamento delle informazioni. I servizi di streaming utilizzano questo pattern, in particolare per buffering e sincronizzazione. Altri esempi? Il compilatore: il codice scritto dal programmatore deve superare l’analisi lessicale, il parsing, l’analisi semantica e infine la generazione in linguaggio macchina.
- Broker. Questo pattern è utilizzato nei sistemi distribuiti, dove le componenti sono disaccoppiate. La comunicazione tra le parti è ovviamente remota, e per gestirla c’è necessità di un’entità che coordini lo scambio di messaggi. Il broker fa proprio questo, ponendosi in mezzo alle entità. Può essere pensato come un client-server in cui però ogni entità espone dei servizi e ognuna di esse può richiederne, e la loro comunicazione è mediata da un’entità centrale. I middleware, per offrire il loro servizio, hanno al loro interno un message broker.
- Peer-to-peer. Non si può che associarlo immediatamente ai torrent, e in generale al file-sharing. Questo pattern prevede la presenza di entità considerate tutte uguali (peer), che possono agire alternativamente da client o da server, cambiando in maniera dinamica. Contrariamente al broker, in questo caso non c’è nessuna componente che si erge alla gestione della comunicazione.
- Event-source. Questo pattern viene utilizzato nei sistemi che utilizzano gli eventi. Le componenti fondamentali sono l’event source, l’event listener, il canale di comunicazione e l’event bus. I canali rappresentano il luogo in cui gli eventi, o messaggi, vengono pubblicati, e sono inseriti all’interno del bus degli eventi. Alle estremità troviamo la source, ovvero l’entità che genera gli eventi pubblicando sul canale, e il listener, che effettuano il subscribing ad un canale e vengono notificati quando c’è un nuovo messaggio sul canale. Anche in questo caso parliamo di un pattern fortemente improntato alla comunicazione tra entità loosely-coupled.
- Model-View-Controller. Conosciuto come MVC, è il pattern maggiormente utilizzato soprattutto nelle applicazioni e nei framework web. Tra i primi ad essere insegnati in ambienti accademici, è un pattern che racchiude la logica delle applicazioni interattive e consente di gestirle al meglio. Nell’MVC i protagonisti sono tre: il model, la view e il controller. Il primo contiene le funzionalità e gestisce i dati, definendo gli algoritmi e le funzioni che descrivono la logica del programma. La view rappresenta la parte visiva, ed è con essa che si interfaccia l’utente. In un buon design, essa dovrebbe essere il più possibile agnostica riguardo il model. Infine, il controller si pone tra i due, da una parte gestendo l’input dell’utente e dall’altro fornendo le informazioni necessarie al modello. Se seguito adeguatamente, permette una totale distinzione tra le parti, che possono essere riutilizzate, modificate, sostituite senza incidere sulle altre.
- Blackboard. Questo pattern viene utilizzato nel campo della speech recognition e in generale in tutti gli ambiti che utilizzano algoritmi di identificazione e interpretazione. A voler generalizzare ancora di più, è la strategia seguita per tutti i problemi che non hanno soluzioni deterministiche note. Nell’architettura troviamo una blackboard, che è una memoria globale che contiene “oggetti” del dominio della soluzione. Le control component sono le entità che hanno accesso alla blackboard e nella quale possono aggiungere nuovi oggetti, oltre che ricercare quelli di cui hanno bisogno. Per poterli identificare, utilizzano una knowledge source tramite pattern matching che fornisce una rappresentazione esistente da cui attingere.
- Interpreter. Questo pattern è usato quando si ha un programma che deve interpretare un programma scritto in un linguaggio dedicato, quale ad esempio il SQL o qualsiasi altro linguaggio di database query. Definisce le regole e le modalità per analizzare le frasi, le espressioni e i simboli e tradurle.
- Layered. Probabilmente il più conosciuto, il layered è un pattern che, come dice la parola, è organizzato a livelli. Anche se non esiste un numero predefinito di livelli, i più utilizzati sono 5: