Agile Life

ottobre 2012 - Post

Architettura: cos’è e cosa la differenzia dal Design

 

Più volte nei post precedenti mi è capitato di sottolineare la sottile differenza tra Architettura e Design, evidenziando che si commette un errore parlando di “Design Architetturale” perché si coniugano tra loro due fasi progettuali diverse.

Cerchiamo allora di fare un po’ di chiarezza in merito.

Prima di tutto, cos’è un Architettura Software? Ebbene, forse sorprenderà sapere che ad oggi non esiste una definizione universalmente accettata di “Architettura Software”: si tratta del design del sistema o del blue print? Deve contenere dettagli relativi alla tecnologia o deve essere agnostico rispetto ad essa? E’ una visione di business del sistema o un costrutto da passare ai tecnici?

Tutte domande legittime che mettono in evidenza come un’Architettura Software abbracci diversi campi e ammetta più definizioni che enfatizzano diversi aspetti in funzione di chi è il destinatario dell’Architettura stessa.

Partiamo da due assunti:

1.      Tutti i sistemi hanno un Architettura!

Sia essa voluta (intentional) che accidentale (accidental), esplicita (explicit) che implicita (implicit), buona (good) o cattiva (poor), non esiste un software senza Architettura.

2.      Esistono diversi modi di descrivere e leggere la stessa Architettura!

Ciò è vero perché intorno ad un progetto (soprattutto enterprise) ruotano una serie disomogenea di stakeholder: dal committente, al developer, allo sponsor. Ognuno ha bisogno di una declinazione dell’Architettura in funzione delle proprie esigenze.

Bisogna evitare di sovraccaricare la descrizione architetturale (overly complex) così come bisogna essere capaci di non renderla povera (poor) e quindi inutile.

Lo scopo di una buona Architettura è quello di rendere il sistema “evolvibile”, quindi favorirne l’evoluzione in funzione di nuovi requisiti e nuove necessità, esplicite o implicite che siano:

Un Architettura è una Buona Architettura se riesce a governare la sua evoluzione e i costi che i cambiamenti comportano. Chiaramente se l’Architettura introduce elementi che semplifichino la realizzazione del sistema, di certo la cosa non dispiace, ma non è indispensabile.

Bisogna poter far evolvere (attenzione: evolvere, non stravolgere) l’Architettura, senza la paura che ciò si trasformi in un’impresa difficile da raggiugere, introducendo più problemi che vantaggi.

Questo aspetto è ben evidenziato da Martin Fowler nel suo Patterns of Enterprise Application Architecture:

“Architecture is a term that lots of people try to define, with little agreement. There are two common elements: One is the highest-level breakdown of a system into its parts; the other, decisions that are hard to change.”

Tale definizione pone l’accento sulla scomposizione del sistema e sugli elementi che ne costituiscono la struttura, principali responsabili dei costi di modifica. Con essa si evidenzia, implicitamente la differenza tra Architettura e Design di un sistema software, abilmente sintetizzata da Grady Booch

“All architecture is design but not all design is architecture. Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change.”

E’ interessante notare che in quest’ultima definizione la questione del “costo del cambiamento” è esplicitata in modo diretto (esattamente come abbiamo evidenziato ed enfatizzato nel precedente post Agile Architecture), creando uno spartiacque tra Architettura e Design.

L’Architettura infatti è assimilabile al blue print del progetto, ovvero ad una visione d’insieme sufficientemente completa da descriverlo, ma non tanto da dettagliarne i tecnicismi. Tocca al Design entrare nello specifico e descrivere come raggiungere gli obiettivi descritti dall’Architettura. Ecco il punto: l’Architettura è la STRATEGIA che adotto per raggiungere l’obiettivo mentre il Design è la TATTICA (o l’insieme di esse) che mi avvicina all’obiettivo.

Chiaramente la terminologia è preso a prestito dall’ambito militare in cui la tattica indica l'utilizzo di risorse in un ambito territoriale ristretto per limitate esigenze temporali (una singola battaglia con relativi movimenti e utilizzo di determinate tecniche). La strategia è, al contrario, l'impiego e l'organizzazione di risorse in funzione di un obiettivo di medio o lungo periodo.

Strategy vs Tactics

Modificare l’Architettura è più costoso che modificare il Design. Questo è dovuto proprio al fatto che il Design “specializza” l’Architettura, mentre quest’ultima definisce i confini in cui muoversi: si pensi all’utilizzo di un Pattern Architetturale come MVC (Model-View-Controller) e al costo di una sua sostituzione con un modello differente come PAC (Presentation-Abstraction-Controller). Dualmente la sostituzione a livello di Design di due diversi framework MVC è si costosa, ma sicuramente molto meno che nel caso precedente.

Possiamo quindi affermare che [FP]:

Da un’Architettura possono scaturire più Design, mentre un Design è identificabile da una specifica Architettura”

["From an architecture may arise more Design, while a Design is identified by a specific Architecture".

La differenza tra Architettura e Design non è però così delineata, non essendo semplice individuare il giusto grado di astrazione dell’Architettura. Un utile esercizio è quello di rispondere a tre obiettivi fondamentali che sono alla base della definizione dell’Architettura:

·         what” (cosa), indica cosa il sistema deve garantire da un punto di vista qualitativo per coprire le esigenze del relativo contesto applicativo;

o   Quali sono le esigenze qualitative (non – funzionali) del sistema?

·         why” (perché) indica perché vengono effettuate determinate scelte;

o   Perché devo garantire determinati livello qualitativi (SLA, Service Level Agreement)?

·          “how” (come)  indica come si intende rispondere alle esigenze non funzionali.

o   Quali sono gli elementi strutturali (moduli, module views and styles) del sistema?

o   Quali sono i componenti dinamici (componenti e connettori, C&C views and styles) che si sviluppano nel sistema?

o   Come si relazionano i componenti con l’ambiente di esecuzione (Allocation views and styles)?

Attenzione: non c’è traccia di scelte tecnologiche specifiche, ne Java, ne dotNet e ne altro!

Detto questo, vediamo di analizzare alcune delle definizioni più interessanti esistenti in letteratura, partendo da quella di Shaw e Garlan tratta dal testo Software Architecture: Perspective on Emerging Discipline:

The Architecture of a software system defines that system in terms of computional components and interactions among the component.

Arricchita da un'altra affermazione, sempre degli stessi autori:

In addition to specifying the structure and topology of the system, the Architecture shows the intended correspondence between the system requirements and elements of the constructed system. It can additionally address system-level properties such as capacity, throughput, consistency, and component compatibility.

La prima definizione abbraccia fortemente la relazione dinamica tra i componenti e le loro interazioni, di interesse del Component and Connection Style (C&C Styles), mentre la seconda evidenza gli aspetti relativi all’organizzazione statica (Module Styles) e l’importanza di soddisfare le proprietà non funzionali.  Manca invece un riferimento all’allocazione dei componenti nell’ambiente di esecuzione (Allocation Styles).

Una definizione più forte è quella data da Bass-Clements-Kazman in Software Architecture in Practice:

“The software architecture of a program or computing system is the structure or structures of the system, which comprise software components, the externally visible properties of those components, and the relationships among them. By -externally visible properties- we are referring to those assumptions other components can make of a component, such as its provided services, performance characteristics, fault handling, shared resource usage, and so on.”

Questa definizione, probabilmente la più completa, è più ampia, perché oltre a considerare i componenti e le relazioni richiama direttamente le “proprietà visibili dall’esterno” che, ancora una volta, non sono quelle funzionali, bensì quelle qualitative: performance, tolleranza i problemi, condivisione delle risorse, e altri SLA di rilievo. Conoscendo tali caratteristiche è possibile valutare l’efficienza dell’Architettura e la sua efficacia nel contesto in cui si intende utilizzarla, permettendo di definire appositi Hot Spot (punti) di estendibilità.

 

Agile Architecture: partizionamento (modularità)

 

Nel precedente post dedicato all’Uso e al Riuso dei moduli e di come queste due caratteristiche sono in rapporto indiretto, abbiamo lasciato in sospeso il discorso relativo a come affrontare il problema del partizionamento del sistema in moduli (modularità).

Prima di approfondire tale aspetto, è opportuno spendere qualche parola di dettaglio sulla differenza tra modulo e componente, già introdotta sempre nel post precedente. Un Modulo è un’entità statica, che serve a decomporre un sistema complesso in componenti più semplici, possibilmente afferenti ad un determinato dominio, relazionati tra loro dalle seguenti associazioni fondati:

·         Is part of: indica la relazione di appartenenza di un sotto modulo ad un modulo aggregatore;

·         Depends of: indica la dipendenza diretta tra due moduli;

·         Is a: definisce una generalizzazione/specializzazione tra moduli.

 

Figura 1: Le tre relazioni fondamentali nelle relazioni tra moduli

 

Un Componente è, invece, un entità dinamica, dotata di uno stato, le cui viste relative vengono tipicamente definite dopo quelle dei moduli, senza il vincolo che la relazione tra modulo e componente sia di 1:1.

Un’analogia abbastanza utile per comprendere la relazione tra Modulo e Componente è quella tra Classe e Oggetto nella programmazione Object Oriented: è possibile pensare al Modulo come ad una Classe e al Componente come ad un Oggetto.

Riprendiamo ora l’argomento oggetto del post, introducendo la definizione di Tensione Modulare (Modular Tension), ovvero la necessità di bilanciare opportunamente proprio Uso e Riuso.

Chiaramente il partizionamento dota il sistema di alcune caratteristiche fondamentali, che caratterizzano direttamente la tensione:

·         Cohesion (Coesioni): ogni modulo ha uno scope ben definito e concentra in esso le relative funzionalità. Ciò favorisce un disaccoppiamento (o basso accoppiamento, loose coupling) dei moduli;

·         Maintance (Manutenibilità): comunque si effettuata la scomposizione, un modulo è sicuramente meno complesso dell’intero sistema a cui afferisce. E’ quindi più semplice da manutenere;

·         Extensibility (Estensibilità): i moduli sono caratterizzati da un’interfaccia d’uso ben definita. Ciò permette di modificare internamente il modulo e addirittura di sostituirlo senza impattare sull’aspetto funzionale del sistema. Attenzione: ciò può non essere vero per gli aspetti qualitativi.

Un sistema estremamente modulare, quindi composto da molti moduli a grana fine (Fine-grained) e poco legato all’ambiente operativo (Lightweight), è sicuramente più facile da manutenere ed estendere e quindi da Riusare, ma ha complessità intrinseche come la comunicazione (orchestrazione) tra i moduli e la difficoltà di valutare l’impatto generale della una modifica di uno di essi se il numero dei moduli è relativamente alto (context dependencies).

Al contrario, un sistema poco modulare, quindi composto da moduli a grana spessa (Coarse-grained) e legati all’ambiente di esecuzione (Heavyweight), è più difficile da manutenere perché più complesso, ma è più semplice da Usare e sostituire perché la specifica macro-funzionalità è svolta interamente dal modulo stesso.

Il tutto si riassume nell’enunciato già presentato nel post precedente: Maximizing reuse complicates use, e, graficamente, nella relativa immagine dove la Tensione Modulare è rappresentata dalla line difforme di colore verde nella figura 2.

 

Figura 2 - in verde la Tensione Modulare

A questo punto una domanda è d’obbligo: come scegliere il giusto livello di modularità del sistema? Appare quantomeno scontato che non esista una formula magica che possa risolvere il problema, ma è possibile ricorrere a delle “best practice” note come module styles.

 

Figura  SEQ Figura \* ARABIC 3 - Module Styles

Si tratta di una serie di soluzioni architetturali (attenzione, Architetturali e non di Design), tra le quali troviamo:

·         Decomposition Style, focalizzato sulla relazione “is-part-of”;

·         Uses Style, focalizzato sulla relazione “depends-on”;

·         Generalization Style, focalizzato sulla relazione “is-a”;

·         Layered Style, focalizzato sulla relazione “allowed-to-use”;

·         Aspect Style, focalizzato su quelli che vengono definiti “Aspetti”, ovvero; caratteristiche/elementi trasversali che attraversano i vari moduli (esempio: il logging);

·         Data Model Style, focalizzato sulla rappresentazione delle relazioni tra i dati (entità).

Questi stili permettono di organizzare in modo efficace i moduli, preparando la relativa vista ad essere poi di supporto alla creazione della vista Component & Connector (C&C), di cui parleremo nei prossimi post.

Figura  SEQ Figura \* ARABIC 4 - Layerd Style

Agile (and Scrum) is not the Silver Bullet! by T-Rex

Agile Architecture: l’eterna lotta tra Uso vs Riuso

 

Il professionista impegnato nell’esercizio di definire l’Architettura di un nuovo sistema informatico, si trova ben presto alle prese con la definizione dei moduli che lo compongono e l’individuazione delle relative relazioni tra esse (modules style).

In questa fase progettuale, si può scegliere di privilegiare uno dei seguenti aspetti:

  • - Riuso (Reuse): ovvero rendere quanto più riutilizzabile il modulo, sia rispetto agli altri moduli sia rispetto alla piattaforma;
  • - Uso (Use): rendere quanto più semplice utilizzabile il modulo.

Se a prima vista questi due aspetti possono sembrare direttamente dipendenti tra loro, ad una più attenta analisi ci si accorge che in realtà hanno una relazione di dipendenza indiretta (figura 1), così come evidenziato da Clemens Szyperski nel suo “Component Software: Beyond Object-Oriented Programming - Maximize reuse minimizes use”:Maximizing reuse complicates use.

reuse vs use

Figura 2 - Use vs Reuse

Per ottenere la massima riusabilità, nel corso dei decenni, sono stati sviluppati paradigmi di progettazione/ programmazione (Object Oriented, Component Based Development, SOA) e framework di supporto per la comunicazione dei componenti (vi ricordo che la comunicazione avviene tra componenti e non tra i moduli che, invece, sono entità statica) come, ad esempio, gli ORM. Tutte soluzioni chiaramente orizzontali, che comunque non tengono in conto della riusabilità da un punto di vista della Business Logic, ovvero l’aspetto verticale.

Facciamo un esempio.

Prendiamo un semplice (probabilmente banale) sistema di gestione documentale basato sulle seguenti funzionalità:

  • . Step.1: carico il documento
  • . Step.2: approvo il documento
  • . Step.3: archivio il documento

Scomponendo sistema è possibile optare per una soluzione a (fig.2) :

  • . “Grana Spessa” (Coarse-grained), ovvero avere un unico modulo che preso il documento effettua le operazioni relative alle 3 micro attività;
  • . “Grana Fine” (Fine-grained), ovvero avere tre moduli che collaborano per completare la macro funzionalità;

 

grana

Figura 2 – Grana Spessa vs Grana Fine

Nonostante le due scelte siano pensate per produrre lo stesso risultato funzionale, la soluzione a “grana-spessa” è più semplice da utilizzare all’interno del sistema, in quanto è un blocco unico che non ha bisogno di gestire interazioni tra più moduli, ma più difficile da riutilizzare visto che l’intera logica di Business è intrinseca ad essa. La soluzione “grana-fine” crea elementi maggiormente riutilizzabili perché focalizzati su micro-funzionalità più facilmente riutilizzabile ma aggiunge complessità nell’uso del componente nel suo insieme (macro funzionalità) perché bisogna gestire gli aspetti di collaborazione tra i vari moduli per ottenere la funzionalità desiderata.

L’usabilità e la riusabilità dipendono, inoltre, dal legame tra i moduli e l’ambiente applicativo in cui devono essere eseguiti (environment): rendere indipendente un modulo dall’ambiente operativo (Lightweight) richiede maggiore sforzo implementativo rispetto allo sviluppo di un modulo dipendente da esso (Heavyweight). Per chiarire ciò si pensi alla necessità di portare fuori dal codice, ad esempio in un file xml, le impostazioni di configurazione, in modo da adattarle a diversi environment.

Da queste considerazioni otteniamo i seguenti postulati relativi ai due fattori evidenziati:

  • . Granularity: Coarse-grained components are easier to use, but fine-grained components are more reusable;
  • . Weight: Lightweight components are more reusable, but heavyweight components are easier to use.

che riassumo le dipendenze indirette oggetto di questo post.

 

Architecture: definition

“The software architecture of a program or computing system is the structure or structures of the system, which comprise software elements, the externally visible properties of those elements, and the relations among them. By “externally visible properties,” we are referring to those assumptions other components can make of a component, such as its provided services, performance characteristics, fault handling, shared resource usage, and so on.”

(Bass, Clements, and Kazman 2003)

Questa definizione riassume in poche righe l’essenza e il significato stesso di [Intentional] Architettura. Nessun riferimento a tecnologie specifiche o scelte di design, ma solo una vista di insieme del sistema, enfatizzando i moduli, le relazioni tra essi e verso i fruitori del sistema stesso

Agile Architect Uncertainty Principle

 

Nel post Agile Architecture [p1] abbiamo dato una definizione all’Intentional Architecture e definite i suoi quattro obiettivi portanti, mentre in Enterprise Agile Principles e Agile Software Architect [p2], che abbracciando i valori del Manifesto Agile, abbiamo definito 8 principi per lo sviluppo di soluzioni Agile Enterprise e il ruolo dell’Agile Software Architect.

Come evidenziato, l’Intentional Architecture assume un ruolo che funge da guida all’evoluzione del Sistema, un po’ come le rotaie guidano il percorso del treno. Ciò porta a definire un quinto obiettivo fondamentale, che va ad unirsi ai quattro esplicitati in [p1]:

1) Semplificazione: quanto più si riesce a semplificare il Blue Print Architetturale, tanto più semplice sarà far evolvere l’Architettura durante lo sviluppo del Sistema;

2) Minimalità: ridurre gli elementi contemplanti dall’Architettura al minio necessario per garantire gli SLA qualitativi previsti. Evitare sempre la tentazione di far diventare l’Architettura un calderone dove finiscono anche le scelte tecnologiche;

3) Modularità: suddividere l’Architettura in componenti fortemente disaccoppiati tra loro, utilizzando pattern architetturali che favoriscono tale obiettivo;

4) Estendibilità: definire sempre dei punti di estendibilità a cui ricorrere per aggiungere funzionalità inattese o non del tutto chiare;

5) Solidità: lo skeleton Architetturale deve essere robusto al fine di valutare adeguatamente le implicazioni tecnologiche del progetto e supportare adeguatamente il Planning Agile del progetto.

Tali obiettivi, implicitamente, impattano sui due aspetti fondamentali nel processo di definizione dell’Intentional Architecture:

*) Aspetto Temporale [Temporal Aspect], che definisce “quando” le scelte vanno effettuate al fine di ritardare quanto più possibile l’inserimento di vincoli che inficiano l’evoluzione dell’Architettura stessa. Questo aspetto evidenzia la sostanziale differenza con l’approccio classico (non Agile) alla definizione dell’Architettura che presuppone la definizione preventiva di tutti gli elementi dell’architettura stessa, tanto da rendere difficile e costoso effettuare modifiche successivamente. Nel caso dell’Intentional Architecture (Agile), il compito dell’architetto è quello di avere un approccio lazy, ovvero rendere l’architettura sufficientemente flessibile, ritardando scelte che scaturiranno dalla successive fase di design e di sviluppo, tipicamente intrecciate tra loro. Questo, giustifica inoltre, l’inserimento nel Team di Sviluppo dell’Agile Software Architect, con una funzione da “consulente” per le scelte che impattano sul completamento e sulla review degli elementi architetturali;

*) Aspetto Strutturale [Structural Aspect], che definisce “come” definire le componenti primarie dell’Architettura, in modo da tracciare una linea guida per la realizzazione del progetto. Questo Aspetto implica la scelta dello specifico stile architetturale, che si concretizza nella scelta di tre stili portanti:

1) module styles, ovvero il set di moduli e le relative regole di combinazione afferenti;

2) component-and-connector (C&C) styles, ovvero il set di componenti, connettori e le relative regole di comunicazione tra loro;

3) allocation styles, ovvero come il sistema viene messo in esercizio.

La definizione di un’Intentional Architecture passa attraverso una strutturazione quanto più possibile chiara e basata su pattern affidabili che garantiscano una basso accoppiamento dei moduli e dei componenti, in modo da limitare gli impatti sulle eventuali modifiche richieste.

Chiaramente l’Aspetto Temporale e l’Aspetto Strutturale sono agli antipodi tra loro. Infatti più si ritardano le scelte (aspetto temporale), al fine di aumentare la possibilità di refactoring dell’architettura, minore è l’enfasi strutturale che è possibile dare all’Intentional Architecture. Dualmente è valido anche il contrario: più ci si concentra sull’aspetto strutturale, effettuando quindi scelte in merito al “come” l’architettura è fatta, minore è la possibilità di ritardare scelte vincolanti.

Questa relazione diretta può essere riassunta in quella che andremo a definire Agile Architect Uncertainty Principle[Principio di Indeterminazione delle Architetture Agile]:

                “Più si affina un aspetto, tanto più l’altro  perde di consistenza” [F.P]

Proprio per affrontare la sfida dell’ Agile Architect Uncertainty Principle,  è indispensabile che il processo di definizione dell’Intentional Architecture sia realizzato da un Software Architect che sappia cogliere le esigenze proprie del progetto e individuare il giusto mix tra Aspetto Temporale e Aspetto Strutturale.

 

[p1] Architetture Agili: una scelta possibile

[p2] Enterprise Agile Principles e Agile Software Architect

[F.P] Felice Pescatore

 

Enterprise Agile Principles e Agile Software Architect

 

Nel precedente post abbiamo risposto affermativamente alla domanda:

                “Ha senso parlare di Architetture Agili?”

La risposta è scaturita sostituendo il concetto classico di Architettura con quello di Intentional Architecture e descrivendo i relativi obiettivi: SemplificazioneMinimalitàModularità ed Estendibilità.

Facciamo ora un passo indietro e guardiamo con attenzione il mondo Agile a partire dal suo manifesto (http://agilemanifesto.org/) composto da 4 valori e 12 principi. Da una sua lettura parsimoniosa ci si rende conto che l’approccio Agile è pensato ed incentrato sul lavoro del Team che sviluppa il software, unico detentore del know-how relativo e responsabile delle scelte di sviluppo e di design. Prima di procedere vorrei di nuovo sottolineare che il Design di un Software appartiene ad un livello di astrazione inferiore rispetto all’Architettura e che la terminologia “Design Architetturale” fonde tra loro fasi progettuali differenti.

Tornando al manifesto Agile possiamo quindi evidenziare che l’approccio è pensato per team medio-piccoli e presenta dei “lati oscuri” per quanto riguarda la sua applicazione nel mondo Enterprise. Infatti è impensabile imbarcarsi nella realizzazione di un nuovo Sistema IT senza aver fatto una serie di valutazioni preventive, tra cui:Costi/BeneficiOpportunità di BusinessRischi annessi al fallimento del progetto, ecc. Per affrontare tali interrogativi è necessario realizzare alcune ipotesi in merito al Sistema che si sta approcciando, realizzando un planning (costi, economici e temporali) e proponendo una prima Architettura (Intentional, appunto).

Per l’ambito Enterprise, Dean Leffingwell propone 7 principi Agili da applicare sia allo sviluppo che alla sua Architetture/Design:

  • Principle #1 The teams that code the system design the system;
  • Principle #2 Build the simplest architecture that can possibly work;
  • Principle #3 When in doubt, code it out;
  • Principle #4 They build it, they test it;
  • Principle #5 The bigger the system, the longer the runway;
  • Principle #6 System architecture is a role collaboration;
  • Principle #7 There is no monopoly on innovation.

In realtà Leffingwell parte dall’assunto, che qui e nel precedente post abbiamo completamente smontato, che il Design e l’Architettura siano la stessa cosa. Quindi il Principio #1, che prevede che sia il team di sviluppo a determinare l’Architettura del Sistema, va assolutamente corretto così come il principio #4, che afferma che il test sia fatto esclusivamente dal team di sviluppo, appare decisamente limitativo. Infatti il team di dev è sicuramente responsabile del test di unità (Unit Test) ma è comunque necessario prevedere un gruppo di testing per tutti quelli che sono i test che vanno al di la delle attività inerenti il singolo team e che verifichino gli SLA (Service Level Agreement) qualitativi.

In modo trasversale, inoltre, Leffingwell propone che la figura del Software Architect sia di supporto al Team di sviluppo, il quale può attingere dalla sua esperienza spunti e consigli su questioni di particolare rilievo e difficoltà.

Una strutturazione delle responsabilità di un Agile Enterprise Team può essere assimilabile a quanto proposto nella tabella seguente:

 

 

AREA Classic Agile
 
Business
  • Determines market needs and features
  • Communicates vision
  • Product managers determine requirements
  • Determines market needs and features
  • Communicates vision
  • Eliminates impediments for the team
  • Product Owner determine Business requirements and priority
Project Management
  • Architects determine architecture
  • Management determines schedule and commits on behalf of team
  • Accountable for the results
  • Agile Software Architect create Intentional Architecture
  • Product Owner create the Agile Planning
Team
  • Inherits the plan
  • Inherits the architecture
  • Left “holding the bag” and executes on a “best efforts” basis
  • Determines the requirements
  • Determines the design
  • Review Intentional Architecture and Agile Planning with Agile Software Architect and Product Owner
  • Commits on behalf of themselves
  • Accountable for the results

 


Tabella 1: Responsabilità Agile Enterprise Team

 

Come si può vedere esiste comunque una fase di Project Management nel mondo Agile, ma questa viene affiancata da una continua fase di review durante il processo di sviluppo.

Tali considerazioni, ci portano a ridefinire i principi succitati, creando quelli che definiremo “Enterprise Agile Principles”:

  • Principle #1: The Intentional Architecture are created by the Agile Software Architect;
  • Principle #2 Build the simplest Architecture that can possibly work;
  • Principle #3: The Teams that code the system Design the system;
  • Principle #4 When in doubt, code it out;
  • Principle #5 They build it, they test their own work;
  • Principle #6 The bigger the system, the longer the runway;
  • Principle #7 System architecture is a role collaboration;
  • Principle #8 There is no monopoly on innovation.

Vediamo ora di descrivere tali principi.

Principle #1: The Intentional Architecture are created by the Software Architect

L’Agile Software Architect ha un ruolo di “guida”, poiché realizza l’Intentional Architecture effettuando scelte mirate soprattutto a garantire la qualità del progetto, nel rispetto dei vincoli di business concordati con il Product Owner e gli Stakeholder.

L’Intentional Architecture dovrebbe essere sempre realizzata con in mente la seguente affermazione:

“What is the simplest thing that can possibly work?” [attribuita a Ward Cunningham]

Principle #2: Build the simplest architecture that can possibly work

L’Agile Software Architect, coadiuvato dal Team, deve sempre sforzarsi di trovare l’architettura più semplice, in modo da favorirne il refactoring e l’estendibilità.

Principle #3: The Teams that code the system Design the system

Il Design spetta al Team, tenendo ben presente la netta differenza tra Architettura e Design. Questo fa si che il Team sia responsabile di gran parte delle scelte che caratterizzano il software (dai Pattern, ai Framework, ecc.) e contribuisca a migliorarne la relativa architettura nelle specifiche fasi di review con l’Agile Software Architect.

Principle #4 When in doubt, code it out

Quando si è di fronte a dei dubbi (Architetturali, di Design, di Implementazione e persino di Business) è consigliabile realizzare la funzionalità incriminata, anche in modo dirty&fast, e poi verificarla sul campo, in modo che tutti gli stakeholder possano dare la propria opinione.

Principle #5 They build it, they test their own work

Il Team che sviluppa il Sistema ha anche il compito di testarlo. Da tale attività, però, vanno esclusi i test estesi come: raggiungimento degli SLA, verifica nell’insieme delle Funzionalità, test di integrazione con sistemi terzi, che comunque devono essere effettuati da un team dedicato e non coinvolto nello sviluppo.

Principle #6 Intentional Architecture is the rails of long projects

Quanto più il Sistema è complesso, tanto più è necessario adottare un Planning Agile che preveda una review costante dei tempi e dei costi relativi, adattandosi ai ritmi del Team ed alle sue esigenze. In tal modo è possibile aggiornare continuamente le aspettative degli stakeholder evitando di arrivare alla data di rilascio prevista e accorgersi di essere assolutamente fuori tempo. In tale scenario l’Intentional Architecture assume un ruolo decisivo perché funge da guida all’evoluzione del Sistema, un po’ come le rotaie guidano il percorso del treno.

Principle #7 Agile Software Architect is a role collaboration

Un Agile Software Architect è una figura con un ruolo estremamente collaborativo, in grado di interagire apertamente con il Team e le altre figure annesse al progetto, al fine di garantire la qualità e il successo del Sistema stesso.

Principle #8 There is no monopoly on innovation

Un progetto Agile di per se prevede lo sharing del know-how e dell’innovazione che da esso ne deriva. Ciò, nel caso di progetti Enterprise, interessa anche la figura dell’Agile Software Architect, che nei processi di sviluppo standard è tipicamente visto come un “estraneo” rispetto agli altri membri del Team.

Nel processo di sviluppo (così come consigliato da Mike Cohn e dallo stesso Dean Leffingwell) è sempre utile trovare un periodo per l’apprendimento, la condivisione e la ricerca di nuove soluzioni, innovative o meno. In particolare Cohn parla della tecnica 6x2+1, ovvero 6 iterazioni (sprint) di 2 settimane intervallate da una settimana (hackathon o spike) dedicata alla sperimentazione di nuove soluzioni. Tale settimana può essere, come indicato in figura 1, costruttivamente interposta tra la Release Candidate del Sistema e la sua data di rilascio ufficiale.

 

agile release planning

Figura 1 - Release Planning - Rally Software Development

 

Conclusioni

Le Architetture Agile (Intentional) sono fondamentali nello sviluppo di sistemi Enterprise, sia per garantire la loro qualità che per fornire una “linea guida” per lo sviluppo stesso. Altrettanto fondamentale è l’Agile Software Architect che riveste un ruolo da mentore nella scelta di soluzioni qualitative e tecnologie di alto livello volte a migliorare sia il Sistema in se che il lavoro ed il know-how del team.

 

Riferimenti bibliografici:

-          Scaling Software Agility, Dean Leffingwell

-          Agile Estimating and Planning, Mike Cohn

 

Architetture Agili: una scelta possibile

La definizione di un’Architettura Software è oggi una delle sfide più interessanti e complesse che un professionista del settore IT possa affrontare.

Tipicamente, nell’approccio classico, la definizione dell’Architettura è un processo che dovrebbe avvenire nelle fasi iniziali di valutazione e definizione di un progetto. In pratica l’Architettura permette di identificare quelli che sono i 3 pilastri di un sistema informatico:

Stile Architetturale, ovvero la tipologia di sistema che si sta realizzando (Client-Server, Web Application, Layered, ecc.);

I Componenti, gli elementi in cui è suddiviso il sistema;

I Middleware di Comunicazione, che mettono in comunicazione tra loro i vari componenti.

L’individuazione di tali componenti porta, successivamente, alla definizione del Design del Sistema, che definisce più in dettaglio le scelte tecnologiche afferenti.

Spesso si utilizza impropriamente la dicitura “Design Architetturale”, ma ciò è profondamente sbagliato. Infatti l’Architettura è a un livello di astrazione più alto del Design e dallo stesso Blue Print Architetturale possono scaturire più design: si pensi, con molta semplificazione, che a due Design che differiscono per i framework di sviluppo utilizzati.

Si intuisce, quindi, che l’Architettura influenza in modo forte le scelte che accompagneranno il Sistema e che una sua eventuale modifica durante la fase di sviluppo può essere decisamente traumatica e costosa. Si pensi, ad esempio, a cosa succederebbe se durante la fase finale di sviluppo ci si accorge della necessità di un ESB per l’integrazione con i sistemi legacy. Se l’Architettura va in una direzione completamente diversa e non contempla tale middleware di comunicazione, probabilmente, sarà molto oneroso (tempi e costi) aggiungerlo.

Ma se l’Architettura deve essere definita in modo meticoloso prima delle altre attività di progetto, come può sposare i concetti alla base delle metodologie Agile che, invece, prediligono adattamenti continui?

Ebbene bisogna spostare il focus dall’Architettura a quella che Dean Leffingwell definisce Intentional Architecture, ovvero l’Architettura verso cui puntare. L’Intentional Architecture “insegue” quattro obiettivi primari:

1. Semplificazione: quanto più si riesce a semplificare il Blue Print Architetturale, tanto più semplice sarà far evolvere l’Architettura durante lo sviluppo del Sistema;

2. Minimalità: ridurre gli elementi contemplanti dall’Architettura al minio necessario per garantire gli SLA qualitativi previsti. Evitare sempre la tentazione di far diventare l’Architettura un calderone dove finiscono anche le scelte tecnologiche;

3. Modularità: suddividere l’Architettura in componenti fortemente disaccoppiati tra loro, utilizzando pattern architetturali che favoriscono tale obiettivo;

4. Punti di Estendibilità (HotPoint): definire sempre dei punti di estendibilità a cui ricorrere per aggiungere funzionalità inattese o non del tutto chiare.

 

In sostanza l’Intentional Architecture deve essere inizialmente pronta ad accogliere i cambiamenti (flessibile), mentre diventa sempre più rigida man mano che il Sistema viene completato.

E’ chiaro che le funzione Core, ovvero quelle che soddisfano l’obiettivo di minimalità, non possono essere oggetto di grandi modifiche perché metterebbero a rischio il progetto stesso. Proprio in questo ambito il ruolo del Software Architect è essenziale, perché deve immaginare il sistema ancor prima di aver avuto tutti i relativi dettagli, guidando il resto del Team nella sua realizzazione e apprendendo da esso nuovi dettagli per affinare e stabilizzare le scelte iniziali.