diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 00000000..cc7a8fbe
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,62 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# Sample workflow for building and deploying a Jekyll site to GitHub Pages
+name: Deploy Jekyll site to Pages
+
+on:
+ push:
+ branches: ["main"]
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow one concurrent deployment
+concurrency:
+ group: "pages"
+ cancel-in-progress: true
+
+jobs:
+ # Build job
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Setup Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: "3.2"
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
+ cache-version: 0 # Increment this number if you need to re-download cached gems
+ - name: Setup Pages
+ id: pages
+ uses: actions/configure-pages@v3
+ - name: Build with Jekyll
+ # Outputs to the './_site' directory by default
+ run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"
+ env:
+ JEKYLL_ENV: production
+ - name: Upload artifact
+ # Automatically uploads an artifact from the './_site' directory by default
+ uses: actions/upload-pages-artifact@v2
+
+ # Deployment job
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v2
diff --git a/.github/workflows/formatting-validation.yml b/.github/workflows/formatting-validation.yml
index e7125723..f2fd0820 100644
--- a/.github/workflows/formatting-validation.yml
+++ b/.github/workflows/formatting-validation.yml
@@ -8,9 +8,9 @@ jobs:
format:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-node@v3
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
with:
node-version: 18
- name: Prettier Check
- run: npm run format:check
\ No newline at end of file
+ run: npm run format:check
diff --git a/.gitignore b/.gitignore
index 65ff902c..63bbf0d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,6 @@ dist/
.env
.env.*
!.env.example
+
+# Site
+_site
diff --git a/.prettierrc b/.prettierrc
index 6e59ae61..a61d7fb5 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,4 +1,5 @@
{
"singleAttributePerLine": true,
- "trailingComma": "es5"
+ "trailingComma": "es5",
+ "endOfLine": "lf"
}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 593fc24b..1782aec5 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,20 +1,59 @@
# Come contribuire al repository
-## Prima installazione
+## Benvenuto!
-Dopo aver clonato il progetto:
+Grazie per aver deciso di contribuire al progetto!
+In questa pagina troverai tutte le informazioni necessarie per poter contribuire al progetto in varie forme.
-```bash
-npm i
-```
+## In che modo posso contribuire?
+
+Per contribuire nella stesura del libro puoi fare una qualsiasi delle seguenti attività.
+
+### Proporre un nuovo capitolo
+
+Se hai un'idea per un capitolo, puoi proporla aprendo una nuova issue.
+Github ti proporrà un template per la creazione della issue, che ti suggeriamo di utilizzare.
+Inserisci quante più informazioni possibili e specifica se vorresti occuparti interamente della prima stesura o se invece vorresti produrre il contenuto in collaborazione con altri contributori.
+
+Una volta aperta la issue, verrà automaticamente assegnata una label `nuovo-capitolo`.
+A questo punto, un qualsiasi Ambassador potrebbe decidere di _assegnare_ a se stesso la issue. Ti consigliamo di pubblicizzare la tua idea in ogni modalità a te possibile e/o contattare eventuali Ambassador di tua conoscenza per chiedere loro di dare un'occhiata alla tua proposta e valutare la possibilità di _assegnare_ la issue a se stessi.
+
+Nel momento in cui un Ambassador deciderà di _assegnare_ la issue a se stesso, un branch verrà creato in maniera automatica e il lavoro di stesura potrà cominciare.
+
+Prosegui nella lettura di questa pagina alla voce [Modalità di stesura di un capitolo](#modalità-di-stesura-di-un-capitolo) per capire come procedere da qui.
+
+### Proporre una modifica ad un capitolo esistente
+
+Se hai un'idea per migliorare un capitolo esistente, puoi proporla aprendo una nuova issue.
+Github ti proporrà un template per la creazione della issue, che ti suggeriamo di utilizzare.
+In alternativa, potresti aprire direttamente una Pull Request, ma ti consigliamo di aprire una issue per discutere prima della modifica da apportare e capire se la tua idea è condivisa dalla community.
+
+### Modalità di stesura di un capitolo
+
+Bene, hai individuato un capitolo a cui contribuire / da modificare e vuoi cominciare a scrivere dei contenuti. Ma come?
+
+Le modalità di stesura del capitolo sono principalmente due:
-per installare le librerie
+- In accordo con la persona del team Ambassador assegnataria del capitolo di interesse, potrete decidere di mettervi in contatto per lavorare insieme alla stesura del capitolo. In questo caso, potrete decidere di utilizzare un qualsiasi strumento di scrittura collaborativa (Google Docs, Office 365, ecc.) e di caricare il contenuto nel branch una volta terminato. Per comodità, si suggerisce di lasciare alla figura di Ambassador il compito di caricare il contenuto nel repository rimuovendo la necessità di una ulteriore Pull Request.
-## Formattazione
+- In accordo con la persona del team Ambassador assegnataria del capitolo, potrai stendere in prima battuta il contenuto del capitolo e far sì che la persona assegnataria ti faccia da revisore e guida. In questo caso, sarà necessario fare un fork del branch relativo al capitolo e aprire una Pull Request che dovrà puntare a quello stesso branch come destinazione.
+ Una volta aperta la Pull Request, la persona assegnataria del capitolo potrà iniziare a revisionare il contenuto e a suggerire modifiche.
+ Una volta terminato il lavoro, la persona assegnataria del capitolo aprirà una Pull Request (o modificherà quella già presente da `draft` a `ready for review`) e chiederà una revisione al resto della community. Le regole di approvazione dei contenuti sono regolate dal Governance Group del progetto e sono disponibili [qui](https://github.com/Il-Libro-Open-Source/book/blob/main/GUIDELINES-CONTENUTI.md).
+
+## Scrivere i contenuti
+
+I contenuti del libro sono scritti in formato markdown e sono organizzati in cartelle e file.
+Sarà sufficiente avere una qualsiasi versione di Node.js installata sul proprio computer per poter formattare i file markdown in maniera automatica e un qualsiasi IDE per la stesura.
+
+### Prima installazione
+
+Dopo aver clonato il progetto ed essendosi spostati sul branch relativo al capitolo di interesse, eseguire il comando `npm i` per installare le librerie.
+
+### Formattazione
Tutti i file markdown devono essere formattati con [Prettier](https://prettier.io/) per una miglior leggibilità e per evitare inutili merge conflict se più persone lavorano allo stesso file.
-Per formattare da linea di comando tutti i file è necessario avere [Node](https://nodejs.org/it) installato sul proprio computer e lanciare il seguente comando nella cartella del repository:
+Per formattare da linea di comando tutti i file è sufficiente lanciare il seguente comando nella cartella del repository:
```bash
npm run format:write
@@ -22,13 +61,29 @@ npm run format:write
Fortunatamente i principali IDE supportano Prettier tramite delle estensioni, di seguito alcuni esempi:
-### Visual Studio Code
+#### Visual Studio Code
Per formattare i file markdown con Visual Studio Code è necessario installare l'estensione [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode).
Un buon consiglio è tenere attivo il flag `Format On Save` direttamente nelle impostazioni di vscode per evitare di dover formattare ogni volta a mano.
-## Conventional commits
+#### JetBrains IDE (WebStorm, IntelliJ, ecc.)
+
+Per formattare i file markdown con IDE JetBrains è necessario installare l'estensione [Prettier](https://plugins.jetbrains.com/plugin/10456-prettier), tranne per WebStorm che include già Prettier di default.
+
+Alcuni suggerimenti di configurazione si possono trovare [qui](https://prettier.io/docs/en/webstorm).
+
+#### Vim
+
+Per formattare i file markdown con Vim è necessario installare il plugin [vim-prettier](https://github.com/prettier/vim-prettier).
+
+Alcuni suggerimenti di configurazione si possono trovare [qui](https://prettier.io/docs/en/vim).
+
+#### Altri IDE
+
+Nella documentazione di Prettier sono presenti le istruzioni per configurare il tool nel proprio IDE preferito: [Editor Integration](https://prettier.io/docs/en/editors).
+
+### Conventional commits
Per mantenere uno storico e poter costruire dei changelog è richiesto a tutti i contributori del progetto di utilizzare i [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
In pratica è necessario utilizzare dei prefissi per i commit che indicano il tipo di commit e il contesto, ad esempio:
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 00000000..9c084501
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,3 @@
+source "https://rubygems.org"
+
+gem "just-the-docs"
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 00000000..f50ae961
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,84 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ addressable (2.8.6)
+ public_suffix (>= 2.0.2, < 6.0)
+ colorator (1.1.0)
+ concurrent-ruby (1.2.3)
+ em-websocket (0.5.3)
+ eventmachine (>= 0.12.9)
+ http_parser.rb (~> 0)
+ eventmachine (1.2.7)
+ ffi (1.16.3)
+ forwardable-extended (2.6.0)
+ google-protobuf (3.25.2-x86_64-darwin)
+ google-protobuf (3.25.2-x86_64-linux)
+ http_parser.rb (0.8.0)
+ i18n (1.14.1)
+ concurrent-ruby (~> 1.0)
+ jekyll (4.3.3)
+ addressable (~> 2.4)
+ colorator (~> 1.0)
+ em-websocket (~> 0.5)
+ i18n (~> 1.0)
+ jekyll-sass-converter (>= 2.0, < 4.0)
+ jekyll-watch (~> 2.0)
+ kramdown (~> 2.3, >= 2.3.1)
+ kramdown-parser-gfm (~> 1.0)
+ liquid (~> 4.0)
+ mercenary (>= 0.3.6, < 0.5)
+ pathutil (~> 0.9)
+ rouge (>= 3.0, < 5.0)
+ safe_yaml (~> 1.0)
+ terminal-table (>= 1.8, < 4.0)
+ webrick (~> 1.7)
+ jekyll-include-cache (0.2.1)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-sass-converter (3.0.0)
+ sass-embedded (~> 1.54)
+ jekyll-seo-tag (2.8.0)
+ jekyll (>= 3.8, < 5.0)
+ jekyll-watch (2.2.1)
+ listen (~> 3.0)
+ just-the-docs (0.7.0)
+ jekyll (>= 3.8.5)
+ jekyll-include-cache
+ jekyll-seo-tag (>= 2.0)
+ rake (>= 12.3.1)
+ kramdown (2.4.0)
+ rexml
+ kramdown-parser-gfm (1.1.0)
+ kramdown (~> 2.0)
+ liquid (4.0.4)
+ listen (3.8.0)
+ rb-fsevent (~> 0.10, >= 0.10.3)
+ rb-inotify (~> 0.9, >= 0.9.10)
+ mercenary (0.4.0)
+ pathutil (0.16.2)
+ forwardable-extended (~> 2.6)
+ public_suffix (5.0.4)
+ rake (13.1.0)
+ rb-fsevent (0.11.2)
+ rb-inotify (0.10.1)
+ ffi (~> 1.0)
+ rexml (3.2.6)
+ rouge (4.2.0)
+ safe_yaml (1.0.5)
+ sass-embedded (1.70.0-x86_64-darwin)
+ google-protobuf (~> 3.25)
+ sass-embedded (1.70.0-x86_64-linux-gnu)
+ google-protobuf (~> 3.25)
+ terminal-table (3.0.2)
+ unicode-display_width (>= 1.1.1, < 3)
+ unicode-display_width (2.5.0)
+ webrick (1.8.1)
+
+PLATFORMS
+ x86_64-darwin-22
+ x86_64-linux
+
+DEPENDENCIES
+ just-the-docs
+
+BUNDLED WITH
+ 2.3.26
diff --git a/README.md b/README.md
index 88a2d1da..e500b209 100644
--- a/README.md
+++ b/README.md
@@ -3,14 +3,30 @@
Questo progetto nasce da un post su LinkedIn che ha raccolto decine di persone attorno all'obiettivo di realizzare un libro completamente Open Source.
Dalla scelta del tema alla stesura del contenuto, il tutto verrà gestito e condiviso con la community e con chiunque voglia contribuire al progetto.
+## Vuoi leggerlo?
+
+Il libro è e sarà sempre disponibile online in maniera Open Source. Vuoi leggerlo? [Clicca qui!](https://il-libro-open-source.github.io/book/)
+
## Come contribuire
Puoi contribuire al progetto in moltissimi modi.
Il primo è certamente quello di mettere una stella e di condividere il progetto con chiunque tu conosca.
Il secondo è quello di contribuire attivamente al progetto, scrivendo, traducendo, revisionando, disegnando, ecc.
Durante la vita del progetto saranno aperte discussioni, sondaggi, pull requests e issue per permettere a chiunque di contribuire in maniera attiva al progetto.
-Inoltre, puoi diventare un Ambassador del progetto, che ti permetterà di avere un ruolo attivo nella gestione del progetto stesso. Vedi la sezione [Ambassadors](#ambassadors) per maggiori informazioni.
-Maggiori dettagli [qui](CONTRIBUTING.md).
+Trovi maggiori informazioni nella sezione [Come contribuire](CONTRIBUTING.md).
+
+### Contributor
+
+Puoi anche diventare un Contributor del progetto, che ti permetterà di avere un ruolo attivo nella gestione del progetto stesso.
+
+Visita la sezione [Membership](https://github.com/Il-Libro-Open-Source/governance/blob/main/MEMBERSHIP.md) per maggiori informazioni.
+
+### Ambassador
+
+Chi ricopre il ruolo di Ambassador?
+Coloro che hanno deciso di contribuire al progetto in maniera diretta, prendendosi la responsabilità di uno o più capitoli, oppure di altre aree come la grafica, la traduzione, la revisione, ecc.
+
+Visita la sezione [Membership](https://github.com/Il-Libro-Open-Source/governance/blob/main/MEMBERSHIP.md) per maggiori informazioni.
## Codice di condotta
@@ -22,15 +38,9 @@ Il tema del libro è: "Il Manuale Del Buon Dev", un compendio di buone pratiche
## Quali sono i capitoli del libro?
-I capitoli del libro sono ancora in fase di definizione e puoi dire la tua a riguardo [qui](https://github.com/Il-Libro-Open-Source/book/discussions/3).
+I capitoli del libro sono costantemente in fase di definizione.
+Trovi i capitoli già presi in considerazione o già in fase di stesura [qui](https://github.com/Il-Libro-Open-Source/book/labels/nuovo-capitolo), proporne uno nuovo aprendo una nuova isse o puoi trarre ispirazione nella [discussione apposita](https://github.com/Il-Libro-Open-Source/book/discussions/3).
## Dove posso scrivere le mie idee?
-Nella discussione [Idee sparse](https://github.com/Il-Libro-Open-Source/book/discussions/27) o nella discussione [Brainstorming](https://github.com/Il-Libro-Open-Source/book/discussions/1).
-
-## Ambassadors
-
-Chi sono gli Ambassador?
-Sono coloro che hanno deciso di contribuire al progetto in maniera diretta, prendendosi la responsabilità di uno o più capitoli, oppure di altre aree come la grafica, la traduzione, la revisione, ecc.
-Ad Agosto sono partite le prime votazioni per il ruolo di Ambassador.
-Per saperne di più, visita la pagina dedicata: [Ambassadors](AMBASSADORS.md).
+Nella discussione [Idee sparse](https://github.com/Il-Libro-Open-Source/book/discussions/27) o aprendo una issue senza template.
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 00000000..7f10857b
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1,20 @@
+title: Il Libro Open Source
+
+theme: just-the-docs
+baseUrl: "/book"
+url: "https://il-libro-open-source.github.io"
+
+permalink: pretty
+
+search_enabled: true
+
+back_to_top: true
+back_to_top_text: "Torna all'inizio"
+
+footer_content: "Copyright © 2023-2024 Il Libro Open Source"
+
+gh_edit_link: true
+gh_edit_link_text: "Contribuisci a questo contenuto su GitHub."
+gh_edit_repository: "https://github.com/Il-Libro-Open-Source/book"
+gh_edit_branch: "main"
+gh_edit_view_mode: "tree"
\ No newline at end of file
diff --git a/_includes/head_custom.html b/_includes/head_custom.html
new file mode 100644
index 00000000..416bbdd6
--- /dev/null
+++ b/_includes/head_custom.html
@@ -0,0 +1,17 @@
+
diff --git a/assets/images/piramide.svg b/assets/images/piramide.svg
new file mode 100644
index 00000000..2658d4f4
--- /dev/null
+++ b/assets/images/piramide.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/docs/_config.yml b/docs/_config.yml
deleted file mode 100644
index e71fb657..00000000
--- a/docs/_config.yml
+++ /dev/null
@@ -1 +0,0 @@
-title: Il Libro Open Source
diff --git a/docs/index.md b/docs/index.md
deleted file mode 100644
index 3a6544d2..00000000
--- a/docs/index.md
+++ /dev/null
@@ -1,4 +0,0 @@
-## Indice del libro
-
-- [Introduzione](./it/introduzione.md)
-- [Cosa significa essere Dev](./it/cosa-significa-essere-dev.md)
diff --git a/docs/it/architetture-software.md b/docs/it/architetture-software.md
new file mode 100644
index 00000000..2579778d
--- /dev/null
+++ b/docs/it/architetture-software.md
@@ -0,0 +1,266 @@
+---
+layout: default
+title: Architettura software
+nav_order: 3
+---
+
+
+# Architetture Software
+{: .no_toc }
+
+- TOC
+{:toc}
+
+
+
+Il termine "architettura software" viene spesso utilizzato in maniera molto generica e impropria. In questo documento cercheremo di dare una definizione e di descriverne le principali.
+
+Inoltre, cercheremo di dare un'idea di "chi si occupa di architetture software" e di descrivere il suo ruolo all'interno di un team di sviluppo.
+
+L'argomento è molto vasto e complesso, per cui proveremo a dare una visione generale, senza entrare troppo nel dettaglio, in quanto ogni singola sezione di questo capitolo potrebbe concretizzarsi in un libro a sé stante.
+
+## Cos'è l'architettura software?
+
+Wikipedia ci dà uno spunto di partenza:
+
+> L'architettura software è l'insieme delle strutture necessarie per ragionare su un sistema software e la disciplina per creare tali strutture e sistemi. Ogni struttura comprende elementi software, relazioni tra loro e proprietà di entrambi gli elementi e delle relazioni.
+
+In altre parole, l'architettura software è l'insieme di tutte le decisioni prese durante la progettazione di un sistema software.
+
+## I diversi aspetti dell'architettura software
+
+L'architettura software è un argomento molto vasto e complesso, ma possiamo identificare alcuni punti chiave che si applicano nella maggior parte dei casi:
+
+- **Componenti e moduli**: identificano i principali componenti o moduli del software e descrivono le loro responsabilità. Questi componenti possono essere funzioni, classi o persino interi microservizi in un sistema distribuito.
+- **Flusso e comunicazione dei dati**: descrive il modo in cui i dati attraversano le diverse parti del sistema, inclusi meccanismi di input e output, database e servizi esterni. Comprendere il flusso di dati è fondamentale per garantire una comunicazione e un'elaborazione efficiente dei dati.
+- **Comportamento del sistema**: definisce il comportamento previsto del software in varie condizioni, incluso il modo in cui vengono gestiti gli errori, ripristinati i guasti e organizzati gli adattamenti per far fronte all'aumento del carico.
+- **Attributi di qualità**: soddisfano i requisiti non funzionali, come prestazioni, sicurezza, scalabilità e manutenibilità. Le decisioni di progettazione per ottimizzare il software vengono prese in funzione di queste qualità.
+- **Vincoli e modelli**: l'architettura software spesso opera entro determinati vincoli, come budget, stack tecnologico o standard di conformità. Chi si occupa dell'architettura sfrutta i modelli di progettazione e le migliori pratiche per soddisfare questi vincoli, ottenendo al tempo stesso la funzionalità desiderata.
+
+In sostanza, l'architettura software fornisce un approccio strutturato alla costruzione di sistemi software complessi, garantendo che siano scalabili, manutenibili e in grado di soddisfare i requisiti e gli standard di qualità previsti. È una disciplina cruciale nell'ingegneria del software che aiuta chi sviluppa a prendere decisioni informate e a creare software che resistano alla prova del tempo.
+
+## Il contesto aziendale
+
+Chi si occupa di architetture software non può vivere in una bolla e non può esulare dal contesto aziendale nel quale si trova: ogni progetto va contestualizzato tenendo conto di queste caratteristiche durante la fase di progettazione per rendere l'implementazione più semplice.
+
+Essere quindi in grado di ascoltare e recepire le richieste e i cambiamenti del business e saper rispecchiare il tutto nel proprio lavoro quotidiano è fondamentale per prendere decisioni coerenti e creare architetture efficaci.
+
+L'architettura software gioca un ruolo fondamentale nel plasmare non solo gli aspetti tecnici di un sistema software ma anche l'organizzazione e la cultura più ampia all'interno della quale viene sviluppato e mantenuto. Un'architettura software ben progettata può favorire una cultura organizzativa positiva in diversi modi. In primo luogo, può promuovere la collaborazione e la comunicazione tra i team di sviluppo fornendo un modello chiaro della struttura e dei componenti del sistema. Quando i membri del team hanno una comprensione condivisa dell'architettura, diventa più facile per loro lavorare insieme in modo efficace, allineare i propri sforzi e prendere decisioni informate, promuovendo una cultura del lavoro di squadra e della cooperazione.
+
+Inoltre, l'architettura del software può seguire la strategia e gli obiettivi generali dell'organizzazione. Un'architettura ben ponderata può garantire che il sistema software sia allineato con gli obiettivi aziendali, rendendo più facile per l'organizzazione adattarsi alle mutevoli condizioni del mercato e alle esigenze dei clienti. Questo allineamento tra software e obiettivi aziendali può aiutare a promuovere una cultura agile e reattiva, in cui l'organizzazione è più propensa ad abbracciare il cambiamento e l'innovazione.
+
+In sintesi, l'architettura software non rappresenta solo un aspetto tecnico ma è un potente strumento in grado di plasmare la cultura dell'organizzazione. Quando si progetta tenendo conto della collaborazione, della comunicazione e in funzione degli obiettivi aziendali, si può promuovere una cultura del lavoro di squadra, dell'adattabilità e dell'innovazione all'interno dell'organizzazione, contribuendo in definitiva al successo dei progetti di sviluppo software e dell'azienda nel suo insieme.
+
+## Chi si occupa di architetture software?
+
+Chi si occupa di architettura del software è di solito una persona con una certa esperienza nel campo dell'ingegneria del software, ed è responsabile della progettazione e della supervisione della struttura di alto livello e della visione tecnica di un progetto o sistema software. Queste figure sono fondamentali per colmare il divario tra i requisiti concettuali di una soluzione software e la sua diretta implementazione. Il ruolo va oltre il codice: implica prendere decisioni strategiche sulla progettazione del sistema, garantire che sia in linea con gli obiettivi dell'organizzazione e ottimizzarlo in base ai vincoli prestabiliti.
+
+Di seguito le caratteristiche chiave che chi ricopre questo ruolo dovrebbe avere:
+
+- **Competenza tecnica**: questa figura dovrebbe avere una profonda conoscenza di vari linguaggi di programmazione, metodologie di sviluppo software e modelli architetturali. Deve rimanere aggiornata con le tecnologie emergenti e le tendenze nell'ingegneria del software. Seppure ci siano varie opinioni sulla necessità di conoscere più di un linguaggio di programmazione, è indubbio che conoscerne più di uno possa aiutare a trovare soluzioni più efficaci in modo particolare se aiuta la comprensione dei limiti che i vari contesti pongono.
+- **Attitudine al problem-solving**: sono essenziali forti capacità analitiche e di risoluzione dei problemi. Questa figura deve analizzare problemi complessi, identificare soluzioni e prendere decisioni che incidono sulla progettazione complessiva del sistema.
+- **Capacità di comunicazione**: una comunicazione efficace è fondamentale poiché le persone che ricoprono questo ruolo devono collaborare con team interfunzionali, parti interessate e con il team di sviluppo. Devono articolare la propria visione, le scelte progettuali e i concetti tecnici alle parti interessate non tecniche, facendo da ponte tra i due mondi.
+- **Leadership**: Queste figure spesso assumono ruoli di leadership, guidando i team di sviluppo, facendo da mentor a figure junior e garantendo che la visione architetturale venga seguita durante tutto il ciclo di vita del progetto.
+- **Design Thinking**: Le persone che ricoprono questo ruolo dovrebbero possedere una mentalità orientata al design, concentrandosi sulla creazione di soluzioni eleganti ed efficienti. Ciò include la progettazione per scalabilità, prestazioni, sicurezza ed esperienza utente.
+- **Business thinking**: comprendere il contesto di business aziendale e gli obiettivi che l'azienda si è posta di raggiungere. Queste figure devono allineare le loro decisioni tecniche con gli obiettivi strategici dell'organizzazione.
+- **Adattabilità**: il panorama del software è in continua evoluzione. La figura dovrebbe essere aperta e adattarsi a nuove tecnologie e metodologie e capace di rivalutare e riadattare l'architettura quando necessario, non solo per necessità tecniche, ma anche per rispondere ai cambiamenti del mercato e per soddisfare le esigenze dei clienti.
+
+Sebbene sia vero che il ruolo viene ricoperto da persone con una certa esperienza, non è detto che una figura junior non possa occuparsi di architetture software. Anzi, è molto importante che lo faccia, in quanto è un ottimo modo per imparare e crescere, ma il consiglio è di iniziare in un contesto controllato, più piccolo in modo da poter sperimentare meglio. L'affiancamento di una figura senior che possa guidare è sicuramente di aiuto per una persona junior.
+
+## Misurare la bontà di un'architettura
+
+Il termine _fitness function_ viene spesso adottato quando si parla di architetture evolutive, ovvero architetture software il cui scopo è quello di evolvere nel tempo, adattandosi ai cambiamenti del business e del mercato. Possono essere assimilabili a delle metriche che permettono di valutare quanto un'architettura software sia adatta a raggiungere gli obiettivi prefissati o ad eventuali obiettivi futuri del business.
+
+Apiumhub nel 2020 ha pubblicato un [post](https://apiumhub.com/tech-blog-barcelona/architectural-fitness-function) sul proprio blog in cui definisce questo concetto in maniera molto chiara:
+
+> La _fitness function_ è un tipo di funzione obiettivo utilizzata per riassumere quanto una determinata soluzione di architettura software sia vicina al raggiungimento degli obiettivi prefissati. Nel definire un'architettura evolutiva, l'architetto del software cerca un algoritmo "migliore"; la funzione fitness definisce cosa significa "migliore" in questo contesto.
+
+Esempi di fitness function possono essere: punteggio di scalabilità, percentuale di errori, tempo medio di risposta, quantità di messaggi persi dal broker, ecc.
+
+Poiché gli obiettivi prefissati di un'architettura variano da progetto a progetto, non esiste una _fitness function_ che è possibile usare ovunque. Di seguito diamo alcune idee di implementazione.
+
+### Triggered Fitness function
+
+Le _triggered fitness function_ (funzioni di fitness _attivate_ o _triggerate_) vengono eseguite in base a un evento particolare, ad esempio il team di sviluppo che esegue un test unitario, una pipeline di distribuzione che esegue una serie di operazioni o una persona del QA che esegue determinate attività stabilite.
+
+Questo tipo di funzioni ha da un lato il vantaggio di poter essere eseguito in maniera molto rapida, ma dall'altro lato ha il difetto di non essere rappresentativo di una situazione reale. Infatti, questo tipo di fitness function non tiene in considerazione il carico di lavoro che il sistema deve gestire durante il _day-by-day_, ma solo situazioni isolate e controllate.
+
+Queste funzioni di fitness vengono spesso lanciate durante una _pipeline_ di distribuzione, in modo da intercettare eventuali variazioni prima che il software venga rilasciato in produzione.
+
+Questo tipo di _fitness function_ richiede solitamente più manutenzione rispetto alle _continuous fitness function_, poiché deve essere adattato durante la vita del software, in base alle modifiche che vengono apportate.
+
+Alcuni esempi sono i test unitari, i test di integrazione, ecc.
+
+### Continuous Fitness function
+
+Le _continuous fitness function_ (funzioni di fitness _continue_) vengono eseguite in modo continuo sull'ambiente in analisi, tramite raccolta di metriche in tempo reale o comunque a cadenze rapide. Questo tipo di funzioni di fitness sono utili per monitorare il sistema e rilevare eventuali problemi prima che si verifichino, o analizzare dei trend.
+
+Questo tipo di funzioni ha da un lato il vantaggio di rappresentare la situazione reale, dall'altro lato ha il difetto di non essere replicabile, in quanto si basa su dati presi dall'ambiente che si sta analizzando (solitamente quello di produzione).
+
+Queste funzioni di fitness vengono spesso lanciate in un ambiente di produzione, in modo da avere contezza del reale contesto nel quale vengono eseguite.
+
+Alcuni esempi sono il monitoraggio dei tempi medi di risposta, il monitoraggio dei messaggi inviati e ricevuti in una coda, ecc.
+
+## Quali sono le principali architetture software?
+
+Esistono diverse architetture software, ognuna con i suoi pro e i suoi contro. In questa parte del libro, descriviamo le principali architetture software che, nel corso dei decenni, sono diventate uno standard de facto grazie alle loro molteplici implementazioni e casi di successo.
+
+Per scegliere quale architettura usare in diversi contesti, possiamo fare riferimenti alle seguenti caratteristiche:
+
+- **Start-up**: Il tempo necessario per definire l'architettura software e cominciare a sviluppare funzionalità. Tale tempo non è da sottovalutare poiché potrebbe richiede, in base al contesto aziendale, una serie di procedure che possono essere automatizzate da tools come le `platform engineering tools`.
+- **Costi**: Il costo che si affronta nell'arco della vita di un progetto o un prodotto che implementi questa architettura. Da considerare che nell'effettiva valutazione dei costi bisogna differenziare eventuali costi di avvio, da pagare una tantum, da costi ricorrenti, da pagare periodicamente per la manutenzione.
+- **Sviluppo e manutenzione**: La facilità con il quale è possibile effettuare modifiche e manutenzione al software. Per semplicità, anche l'aspetto del testing viene incluso in questo punto.
+- **Tracciabilità**: La facilità con la quale è possibile individuare problemi o bug all'interno del software.
+- **Scalabilità**: La facilità con la quale è possibile scalare il software, ovvero la capacità di gestire un carico di lavoro maggiore. Questo punto non fa riferimento alla scalabilità orizzontale o a quella verticale e non tiene conto dei costi, ma dell'impegno tecnico necessario per scalare il software.
+- **Performance**: La velocità con la quale il software è in grado di elaborare i dati per rispondere ad un'esigenza di business.
+
+Questi punti chiave sono da intendersi come una valutazione soggettiva, in quanto ogni architettura software può essere implementata in modi diversi, con conseguenze diverse, valutando criteri e parametri differenti in base alle proprie necessità e, pur essendo un elenco piuttosto esaustivo, mix di queste architetture hanno dimostrato di essere vincenti in molti casi, anche a discapito di quanto riportato qui sopra.
+
+I punti chiave sono espressi con dei voti che vanno da 1 a 5, dove 1 è il voto più basso e 5 il voto più alto. Per _alto_ si intende il valore migliore per il punto chiave in questione, mentre per _basso_ si intende il valore peggiore per il punto chiave in questione, ovvero il valore che si vorrebbe evitare. Nel caso di _costi_, ad esempio, un voto alto significa che i costi sono bassi, mentre un voto basso significa che i costi sono alti.
+
+Segue una tabella riepilogativa dei punti di forza e di debolezza di ogni architettura.
+
+| | **Monolite** | **Monolite modulare** | **Microkernel** | **Microservizi** | **Service-based** |
+| --------------------------- | --------------- | --------------------- | --------------- | ---------------- | ----------------- |
+| **Start-up** | ⭐️⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ | ⭐️⭐️ | ⭐️⭐️⭐️ |
+| **Costi** | ⭐️⭐️⭐️ | ⭐️⭐️⭐️ | ⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ |
+| **Sviluppo e manutenzione** | ⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ | ⭐️⭐️ | ⭐️⭐️⭐️ |
+| **Tracciabilità** | ⭐️⭐️⭐️⭐️ | ⭐️⭐️ | ⭐️⭐️⭐️ | ⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ |
+| **Scalabilità** | ⭐️ | ⭐️ | ⭐️⭐️ | ⭐️⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ |
+| **Performance** | ⭐️⭐️ | ⭐️ | ⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ |
+
+Nelle sezioni che seguono verranno indicati alcuni termini che possono non essere familiari a tutti. Per questo motivo, quanto segue è un glossario dei termini più utilizzati.
+
+Quando parliamo di _scalabilità verticale_ ci riferiamo all'incremento delle risorse hardware a disposizione del sistema (CPU, RAM, storage, ecc.) quando queste non sono più sufficienti per gestire il carico di lavoro.
+
+Quando parliamo di _scalabilità orizzontale_ ci riferiamo alla replicazione dei componenti del sistema, in modo da poter gestire un carico di lavoro maggiore. Le tecniche di scalabilità orizzontale sono varie e possono essere implementate in modi diversi, in base alle esigenze del sistema.
+
+Quando parliamo di _layer applicativi_ ci riferiamo a un livello di astrazione del software. Il database, le API, il front-end, ecc. sono tutti layer del software.
+
+### Monolite
+
+Il monolite è un'architettura software in cui tutte le funzionalità sono sviluppate e distribuite come un singolo pacchetto. È il tipo di architettura più semplice da implementare, in quanto non richiede particolari accorgimenti per la comunicazione tra i vari componenti, dal momento che questi ultimi risiedono all'interno dello stesso applicativo.
+
+Trattasi dell'architettura software più semplice da implementare e più diffusa, ma anche la più difficile da scalare, in quanto non è possibile replicare i singoli componenti, ma è necessario scalare l'intero sistema. In questi casi, infatti, al monolite viene affiancato il concetto di _scalabilità verticale_.
+
+Solitamente questa architettura viene identificata anche come _Layered Architecture_.
+
+In questa architettura i layer applicativi sono tutti parte dello stesso applicativo.
+
+È importante notare che storicamente questa architettura è spesso risultata la più sensibile al concetto di _stratificazione del codice_, ovvero il continuo sviluppo di funzionalità una sopra l'altra in sostituzione o sovrapposizione di precedenti, rendendo il codice sempre più complesso e difficile da mantenere. Questo fenomeno è stato spesso chiamato _Big Ball of Mud_.
+
+- **Start-up**: 5. Il monolite è l'architettura software più semplice da implementare, in quanto non richiede particolari accorgimenti per la comunicazione tra i vari componenti o una necessità di valutazioni iniziali elevate. Molti linguaggi di programmazione, inoltre, offrono dei framework che permettono di implementare un monolite in pochi minuti. Fra i principali framework troviamo Ruby on Rails, Django, Spring Boot, Laravel, ecc.
+- **Costi**: 3. Pur essendo un'architettura _a basso costo_ in termini di start-up, il costo cresce esponenzialmente per via della necessità di _scalare orizzontalmente_.
+- **Sviluppo e manutenzione**: 4. Il monolite è tra le architetture software più semplici da sviluppare e mantenere, per gli stessi motivi espressi nella voce _start-up_. I framework sono ormai molto maturi e permettono di sviluppare e mantenere un monolite in maniera molto semplice.
+- **Tracciabilità**: 4. Poiché tutti i componenti fanno parte dello stesso processo o blocco, è facile individuare la porzione di codice che ha generato un problema o un bug.
+- **Scalabilità**: 1. Il monolite è tra le architetture software più difficili da scalare, in quanto non è possibile replicare i singoli componenti, ma è necessario scalare l'intero sistema. In questi casi, infatti, al monolite viene affiancato il concetto di _scalabilità verticale_. La valutazione è dovuta alla necessità, nella maggior parte delle implementazioni di questo tipo, di dover riavviare il sistema per scalare le risorse hardware.
+- **Performance**: 2. La performance del monolite è legata alla capacità di scalare le risorse hardware a disposizione del sistema. Di conseguenza, la curva di crescita dei tempi di risposta tende a crescere sempre di più. Solitamente le performance, seppur buone nelle prime fasi di vita del software, tendono a degradare nel tempo.
+
+### Monolite Modulare
+
+Il monolite modulare è un'architettura software in cui tutte le funzionalità sono sviluppate e distribuite come un singolo pacchetto, ma con la differenza che il codice è organizzato in moduli. Questi moduli possono essere sviluppati e distribuiti in maniera indipendente, ma sono comunque parte dello stesso _blocco_, inteso che l'applicativo online è unico, come nel caso del monolite _classico_.
+
+I moduli devono essere quanto possibile indipendenti tra di loro in modo da avere una suddivisione delle funzionalità segregata. La forza di questa architettura è comunque la possibilità, seppur da tenere sotto controllo, di far comunicare tra di loro i moduli tramite delle interfacce pubbliche.
+
+Da non confondersi con altre architetture, in questo caso i moduli sono parte dello stesso processo o applicativo, rendendo necessaria la _scalabilità verticale_.
+
+In questa architettura i layer applicativi sono tutti parte dello stesso applicativo.
+
+- **Start-up**: 4. Essendo una variante del monolite, lo start-up è molto semplice, ma la necessità di organizzare il codice in moduli può richiedere un po' di tempo.
+- **Costi**: 3. Pur essendo un'architettura _a basso costo_ in termini di start-up, il costo cresce esponenzialmente per via della necessità di _scalare orizzontalmente_.
+- **Sviluppo e manutenzione**: 5. Rispetto a un monolite _classico_, il monolite modulare è più semplice da sviluppare e mantenere, in quanto i moduli hanno un compito ben definito e sono quanto più possibile indipendenti tra di loro.
+- **Tracciabilità**: 2. Compattando i moduli in un unico blocco, è più difficile individuare la porzione di codice che ha generato un problema o un bug in quanto solitamente il codice dei singoli moduli viene minificato o comunque ottimizzato per la produzione.
+- **Scalabilità**: 1. Il monolite, anche in forma modulare, è l'architettura software più difficile da scalare, in quanto non è possibile scalare i singoli componenti, ma è necessario scalare l'intero sistema. In questi casi, infatti, al monolite viene affiancato il concetto di _scalabilità verticale_. La valutazione è dovuta alla necessità, nella maggior parte delle implementazioni di questo tipo, di dover riavviare il sistema per scalare le risorse hardware.
+- **Performance**: 1. La performance del monolite modulare presenta le stesse problematiche del monolite _classico_, con l'aggiunta che per far funzionare questa architettura è necessario un ulteriore livello di astrazione, ovvero il modulo, che può portare ad un degrado delle performance.
+
+## Microkernel
+
+Chiamata anche _architettura a plugin_, si compone essenzialmente di un nucleo centrale che si occupa di gestire le comunicazioni tra i vari componenti, che sono sviluppati e distribuiti come plugin.
+Questi plugin possono essere sviluppati e distribuiti in maniera indipendente, ma funzionando attorno ad un nucleo centrale, faranno sempre parte dello stesso _blocco_, inteso che l'applicativo online è unico, come nel caso del monolite _classico_.
+
+Il concetto principale attorno a questa architettura è l'indipendenza totale tra i plugin. Per definizione, nessun plugin dovrebbe avere come dipendenza un altro plugin.
+
+In questa architettura i layer applicativi sono tutti parte dello stesso applicativo.
+
+- **Start-up**: 4. Essendo una variante del monolite, lo start-up è molto semplice, ma la necessità di organizzare il codice in un nucleo centrale e implementare un sistema di plugin può richiedere più tempo.
+- **Costi**: 3. Pur essendo un'architettura _a basso costo_ in termini di start-up, il costo cresce esponenzialmente per via della necessità di _scalare orizzontalmente_.
+- **Sviluppo e manutenzione**: 4. Trattasi di un'architettura semplice da mantenere e sulla quale aggiungere funzionalità, ma la necessità di non far comunicare i plugin tra di loro può aggiungere una lieve complessità.
+- **Tracciabilità**: 3. Testare e tracciare eventuali bug in questa architettura è mediamente complesso. L'isolamento dei plugin aiuta con il testing, ma la correlazione col nucleo centrale a volte può rallentare il processo di tracciamento.
+- **Scalabilità**: 2. Le difficoltà di scalabilità sono anche in questo caso dovute alla _singola unità di rilascio_ o _single deployment unit_, ovvero trattandosi di un unico applicativo, è necessario scalare l'intero sistema, dovendo quindi ricorrere alla _scalabilità verticale_.
+- **Performance**: 4. Processi di comunicazione semplici e isolabilità rendono questa architettura molto performante.
+
+## Microservizi
+
+La _buzzword_ per eccellenza degli ultimi anni.
+
+Questa architettura software si compone di un insieme di servizi indipendenti tra di loro, ognuno con un compito ben definito, che comunicano tra di loro attraverso un meccanismo di comunicazione _solitamente_ asincrono.
+
+A differenza delle architetture _a singolo blocco_ viste sopra, questa architettura permette di scalare i singoli componenti, in quanto ogni componente è un applicativo separato (servizio) e viene rilasciato in maniera indipendente.
+
+In questa architettura ogni microservizio solitamente ha il proprio database e il proprio back-end (basato su API), mentre il front-end è solitamente un'interfaccia grafica che comunica con i microservizi attraverso le API, a prescindere da dove risieda o da come sia implementato. I database sono solitamente piccoli e si occupano di gestire solo i dati necessari al microservizio in questione.
+
+A differenza delle altre architetture citate, la condivisione del database è da considerarsi un _anti-pattern_, ovvero una pratica da non adottare, in quanto può portare a problemi di _coupling_ tra i microservizi, esattamente l'opposto di quanto si vuole ottenere con questa architettura.
+
+Per definizione i microservizi non dovrebbero comporsi di più di una manciata di endpoint e relative funzioni, in quanto altrimenti si parla più di _service-based architecture_.
+
+Da notare che il _decoupling_ creato da questa architettura può portare ad un notevole aumento della complessità.
+
+- **Start-up**: 2. Lo start-up di un'architettura di questo tipo è complessa, in quanto è necessario stabilire sistemi di _orchestrazione_ o di _coreografia_ dei microservizi. Inoltre, il tipo di comunicazione (sincrono o asincrono) e il protocollo adottato (HTTP, AMQP, ecc.) devono essere valutati con attenzione.
+- **Costi**: 4. Potendo scalare indipendentemente i singoli microservizi, i costi sono contenuti, in quanto è possibile scalare solo i microservizi che ne hanno bisogno, e solo nei momenti in cui si ritiene necessario.
+- **Sviluppo e manutenzione**: 2. Il sistema di orchestrazione o coreografia dei microservizi può aggiungere una complessità non indifferente, soprattutto se non si ha esperienza in questo campo. Inoltre, la necessità di comunicare tra i microservizi può aggiungere un ulteriore livello di complessità.
+- **Tracciabilità**: 3. Testare e tracciare eventuali bug in questa architettura è complesso. L'isolamento dei microservizi aiuta in questo caso, ma la tracciabilità è piuttosto complessa e richiede integrazione di _distributed tracing_ o _open telemetry_.
+- **Scalabilità**: 5. La scalabilità è il punto di forza di questa architettura, in quanto ogni microservizio può essere replicato indipendentemente dagli altri.
+- **Performance**: 4. La performance di questa architettura è legata alla capacità di scalare i singoli microservizi. Con una buona configurazione di auto-scaling si possono raggiungere eccellenti risultati, anche se la necessità di mettere in comunicazione, via HTTP, socket o qualsiasi altra forma, una quantità elevata di sistemi può impattare sulle performance.
+
+## Service-based
+
+Il _service-based è un'architettura software in cui l'applicativo viene suddiviso in una manciata di servizi (Solitamente da 3 a 12) che comunicano tra di loro attraverso un meccanismo di comunicazione \_solitamente_ asincrono.
+
+Ci si aspetta che i servizi siano in costante comunicazione tra di loro e che rispettino dei contratti (interfacce) precedentemente stabiliti. Questo tipo di architettura è molto simile a quella dei microservizi, ma con la differenza che i servizi sono solitamente più grandi e con un compito ben definito.
+
+In questa architettura ogni servizio solitamente ha il proprio database, il proprio back-end e il proprio front-end, anche se ci sono casi in cui il database possa essere condiviso tra i servizi (in questo caso si suggerisce di utilizzare un utente dedicato per l'accesso alle singole tabelle o agli schemi di pertinenza), altri in cui il front-end vive in un applicativo separato o, ancora, altri in cui il front-end è unico per tutti i servizi.
+
+Questa architettura viene spesso indicata come "l'anello mancante" tra il monolite e i microservizi, anche se la dimensione dei servizi e il successivo _decoupling_ sono temi piuttosto complessi da gestire.
+
+- **Start-up**: 3. Lo start-up di un'architettura di questo tipo è complessa, ma non quanto quella a microservizi, anche se molte delle problematiche sono simili.
+- **Costi**: 4. Potendo scalare indipendentemente i singoli servizi, i costi sono contenuti, in quanto è possibile scalare solo i servizi che ne hanno bisogno, e solo nei momenti in cui lo si ritiene necessario.
+- **Sviluppo e manutenzione**: 3. Come per lo start-up, le sfide e le necessità sono simili a quelle dei microservizi, ma trattandosi di entità più grandi, la complessità diminuisce.
+- **Tracciabilità**: 4. Testare e tracciare eventuali bug in questa architettura è piuttosto semplice vista la normale dimensione dei servizi. L'isolamento aiuta, e anche qui si suggerisce l'integrazione di _distributed tracing_ o _open telemetry_.
+- **Scalabilità**: 4. La scalabilità è il punto di forza di questa architettura, in quanto ogni servizio può essere replicato indipendentemente dagli altri, ma la dimensione degli stessi può rendere più complicato del previsto il processo.
+- **Performance**: 4. La performance di questa architettura è legata alla capacità di scalare i singoli servizi. Con una buona configurazione di auto-scaling si possono raggiungere eccellenti risultati, anche se la necessità di mettere in comunicazione, via HTTP, socket o qualsiasi altra forma, una quantità elevata di sistemi può impattare sulle performance.
+
+## Altre architetture e pattern
+
+Architetture come la _space-based architecture_ o la _service-oriented architecture_ vengono utilizzate in contesti specifici e non sono solitamente utilizzate come architetture software di riferimento, di conseguenza vengono citate solo per completezza d'informazione.
+
+Una nota importante riguarda la _cell-based architecture_ che si pone come punto di incontro tra i microservizi e la _service-based architecture_. Partendo dal concetto di microservizi, potremmo identificare una _cell_ come un conglomerato di microservizi che rispondono a una necessità di business con una interfaccia unificata. Se si parte invece dal concetto di _service-based_, potremmo identificare una _cell_ come ulteriore scomposizione per facilitarne la manutenzione e la scalabilità.
+
+Altri termini, come la _event-driven architecture_ o la _event-sourcing architecture_ in realtà spesso si riferiscono ad un pattern di progettazione, ovvero un modo di progettare un sistema software, e non un'architettura software a tutti gli effetti. Il concetto di _event-driven_ viene infatti _affiancato_ più che _sostituito_ ad un'architettura software, come nel caso dei microservizi o del _service-based_.
+
+## Documentazione
+
+### Architecture Decision Records
+
+Gli _Architecture Decision Records_ (ADR) sono un modo per documentare le decisioni prese durante la progettazione di un sistema software. Questo tipo di documentazione è molto utile per capire il perché di determinate scelte e per capire come il sistema è stato progettato.
+
+A differenza di una classica documentazione tecnica o di un diagramma, gli ADR sono molto più semplici da scrivere e da leggere, in quanto sono composte da pochi elementi:
+
+- **Titolo**: il titolo della decisione presa.
+- **Stato**: lo stato della decisione presa. Solitamente può essere _Proposta_, _Accettata_, _Completata_, _Rifiutata_ o _Sostituita_.
+- **Contesto**: il contesto in cui è stata presa la decisione.
+- **Decisione**: la decisione presa.
+- **Conseguenze**: le conseguenze della decisione presa.
+
+Gli ADR vengono spesso utilizzate nelle aziende in cui si fa leva sul _BDD_ (Behavior Driven Development) per la stesura dei ticket nel proprio sistema di ticketing, puntando ad uno specifico ADR per dare informazioni aggiuntive e contesto a chi legge il ticket.
+
+## Conclusioni
+
+L'architettura software è un argomento molto vasto e complesso, materia che ognuno di noi dovrebbe conoscere e comprendere, in quanto influenza ogni aspetto dello sviluppo software.
+
+Un'architettura scelta in maniera frettolosa o senza una valutazione attenta può portare a conseguenze disastrose, come ad esempio un sistema che non riesce a gestire il carico di lavoro o che non riesce a soddisfare i requisiti di qualità e scalabilità richiesti.
+
+D'altro canto, si consiglia a chiunque legga questi contenuti di non basarsi sulle mere valutazioni fatte, che sono generaliste e non applicabili a tutti i contesti, ma di approfondire l'argomento e di valutare con attenzione ogni aspetto, in quanto ogni architettura software ha i suoi pro e i suoi contro, e ogni progetto ha le sue esigenze, e spesso la verità sta nel mezzo o, come piace dire a noi dev: _dipende_.
+
+## Riferimenti
+
+La lista di architetture software è ispirata e rivisitata a partire dal materiale prodotto e distribuito da [Mark Richards](https://www.developertoarchitect.com/), autore di molti libri sull'architettura software, video e webinar pubblicati su varie piattaforme, tra cui O'Reilly e YouTube.
diff --git a/docs/it/aziende-di-consulenza-vs-prodotto.md b/docs/it/aziende-di-consulenza-vs-prodotto.md
new file mode 100644
index 00000000..9e6562e9
--- /dev/null
+++ b/docs/it/aziende-di-consulenza-vs-prodotto.md
@@ -0,0 +1,112 @@
+---
+layout: default
+title: Aziende di consulenza vs prodotto
+nav_order: 7
+---
+
+
+# Aziende di consulenza vs prodotto
+{: .no_toc }
+
+- TOC
+{:toc}
+
+
+
+## Obiettivo del capitolo
+
+In questo capitolo esploreremo i differenti modelli di business che un'azienda software può adottare. Non entreremo nel dettaglio di un intero modello di business, altrimenti diventerebbe un capitolo di economia e marketing, ma solo del modo in cui l'azienda riesce a mantenersi attiva sul mercato, creando e distribuendo valore ai clienti finali, attraverso i propri prodotti o servizi.
+
+In parole povere: come l'azienda riesce ad ottenere introiti e retribuire i dipendenti.
+
+Chi è agli inizi potrebbe pensare che le aziende informatiche siano essenzialmente tutte uguali.
+
+In realtà, il modello di business adottato dall'azienda influenza non solo il processo di sviluppo del software, ma potenzialmente anche la carriera stessa di chi lavora nello sviluppo, oltre che il suo modo di percepire e vivere l'azienda.
+
+Per questo motivo, conoscere le differenze tra le 2 principali strategie di business nelle aziende informatiche, ti permetterà di scegliere in modo consapevole il tuo prossimo lavoro.
+
+Capirai quale azienda può darti ciò che stai cercando, e non mi riferisco solamente alla RAL.
+
+> Nota bene: a volte queste differenze non sono così nette. Esistono aziende che adottano in maniera ibrida entrambe le modalità, ma avremo modo di entrare più nel dettaglio riguardo a questo nelle considerazioni finali.
+
+## Azienda di consulenza
+
+Questa tipologia di azienda adotta una tipologia di business B2B (_business to business_), ovvero i clienti dei servizi offerti, sono altre aziende.
+
+Più nello specifico, l'azienda guadagna tramite l'operato dei dipendenti, che lavorano come consulenti sotto contratto di appalto, per realizzare progetti delle aziende clienti.
+
+Questo significa che il dipendente presta momentaneamente la sua esperienza e le sue competenze, per portare a termine uno o più progetti per la durata del contratto stipulato tra la propria azienda in cui si è dipendenti e l'azienda cliente.
+
+Alcuni esempi di aziende di consulenza sono: Reply, Deloitte e Accenture.
+
+## Azienda di prodotto
+
+Le aziende di prodotto invece hanno solitamente un business B2C (business to customer), ovvero il cliente è l'utente finale, colui che utilizza il prodotto o i prodotti, sviluppati dalla compagnia stessa.
+
+In questo modello di business, le attività interne sono finalizzate a migliorare e innovare il prodotto, da cui dipendono i ricavi e la sopravvivenza dell'azienda.
+
+Il prodotto potrebbe essere un sito web, una piattaforma, un'applicazione, o un'intera suite di questi prodotti digitali.
+
+Se il prodotto è digitale, il guadagno potrebbe provenire ad esempio dalla sottoscrizione di abbonamenti, acquisti in app, pubblicità e altre modalità che in ogni caso dipendono dall'interazione dell'utente finale con il prodotto stesso.
+
+Alcuni esempi di aziende di prodotto sono: Google, Meta e Spotify.
+
+> N.B. Quando si parla di _utente finale_ ci si potrebbe benissimo riferire a dipendenti di aziende, o ad aziende nel loro insieme, e non necessariamente a cittadini e utilizzatori _comuni_. Ci sono tantissimi business che sviluppano prodotti in ottica B2B, vendendo soluzioni come, per esempio, applicativi di fatturazione piuttosto che strumenti di produttività.
+
+## Principali differenze
+
+Andremo a vedere adesso quali sono le principali differenze a livello di esperienza per chi sviluppa e sceglie di lavorare per una o per l'altra tipologia.
+
+### Cultura aziendale
+
+La cultura aziendale è il complesso dei valori che caratterizzano un'azienda.
+
+Tutti sono responsabili del clima e della cultura aziendale all'interno della propria azienda, ma essa è principalmente influenzata dalle persone che sono ai vertici e che sono responsabili delle principali decisioni aziendali.
+
+Chi è al management dell'azienda infatti definisce non solo gli obiettivi e la mission, ma cerca di trasmettere i valori da condividere per raggiungere tali obiettivi.
+
+Variando il modello di business di cui parlavamo prima, anche il focus e la cultura dell'azienda cambia.
+
+Generalmente chi lavora per aziende di prodotto ha un senso di appartenenza maggiore rispetto a chi lavora in aziende di consulenza poiché si lavora in team per un obiettivo comune, ovvero la realizzazione e il successo del prodotto. Questo aumenta la probabilità di sentirsi valorizzati e supportati.
+
+Questa sensazione invece spesso viene meno nelle aziende di consulenza poiché si lavora per il cliente o per i clienti. Escludendo il senso di responsabilità per il proprio operato, caratteristica del tutto personale e variabile, lavorando per e presso il cliente difficilmente si _sente_ il progetto su cui si sta lavorando come "proprio", soprattutto quando capitano frequenti spostamenti nei progetti e variazioni delle persone che ci lavorano. Tutto questo sul lungo periodo potrebbe causare demotivazione, disinteresse e quasi un senso di abbandono.
+In altri casi, questa sensazione di distacco è meno forte. In alcune aziende di consulenza infatti si lavora in modalità "_progetti chiavi in mano_". Con questa modalità, i progetti dei clienti vengono presi in carico dall'azienda di consulenza, curati e sviluppati interamente dai propri team. Questo permette a chi sviluppa di avere un team di riferimento più stabile rispetto a quando si lavora presso il cliente, aumentando il senso di appartenenza.
+
+### Possibilità di carriera
+
+Le aziende di consulenza puntano come obiettivo principale ad acquisire commesse dalle aziende clienti e puntare alla loro soddisfazione.
+
+Se questo obiettivo è perseguito in maniera sana, per un/a developer lavorare in azienda di consulenza significa potenzialmente lavorare con diverse tecnologie e avere la possibilità di formarsi in modo continuo e variegato.
+Questo si potrebbe tradurre in una rapida crescita e una più ampia possibilità di carriera. E spesso, le aziende di consulenza sono il punto di ingresso principale anche per le figure più Junior.
+
+Se questo obiettivo invece è perseguito dall'azienda con disorganizzazione, acquisendo progetti solo con lo scopo di fatturare senza tenere conto della reale disponibilità di un adeguato numero di personale preparato, questo potrebbe influire sul team di sviluppo in forma di mole di lavoro eccessiva, causando demotivazione e frustrazione, e in particolare sulle figure Junior che potrebbero essere abbandonate a loro stesse senza un'adeguata formazione.
+
+Nelle aziende di prodotto invece la responsabilità principale di ogni reparto dell'azienda sarà quello di mantenere il prodotto attivo e attrattivo sul mercato. Questo vale sia per il reparto di marketing e comunicazione, quanto per il reparto tecnico sia a livello di innovazione e sviluppo dello stesso.
+
+Se l'azienda di prodotto ha una direzione precisa e organizzata, per chi sviluppa e ci lavora sarà più naturale puntare alla propria crescita formativa, alla qualità del proprio operato e alla collaborazione e crescita in team.
+
+Per quanto la qualità del prodotto sviluppato è obiettivamente una priorità delle aziende di prodotto, tirando le somme, le possibilità di carriera e di crescita sono comunque fattibili in entrambe le tipologie di azienda, il tutto si riduce a quanto queste siano organizzate e attente alla formazione dei propri dipendenti.
+
+Per una persona Junior o senza una particolare esperienza significativa, è sicuramente più semplice entrare in un'azienda di consulenza poiché nelle aziende di prodotto in genere vengono ricercate persone autonome e con un background solido.
+
+### Progetti e tecnologie
+
+Le aziende di consulenza in genere hanno tipologie di clienti simili e offrono soluzioni per specifici ambiti (finance, automotive, e-commerce, medical, ecc...).
+
+La possibilità di variare linguaggi e tecnologie è sicuramente più alta rispetto un'azienda di prodotto, soprattutto se questa ha un singolo progetto. Lavorare nelle aziende di consulenza infatti permette generalmente di avere molte opportunità e fare molte esperienze diverse.
+
+Anche se questo dipende molto dalla tipologia di clienti con cui l'azienda collabora. Potrebbe capitare infatti di lavorare con progetti _legacy_ che il cliente non intende aggiornare per una questione di costi o di tempi.
+
+Nelle aziende di prodotto invece generalmente si ha un singolo o pochi progetti. Questo per alcuni potrebbe risultare noioso. Ma ancora una volta, dipende dalla natura del progetto stesso. Potrebbe infatti trattarsi di un software abbastanza grande e complesso da mantenere viva la curiosità e la necessità di formazione per svilupparlo, manutenerlo ed evolverlo.
+
+## Conclusioni
+
+Come abbiamo visto, la tipologia di azienda influenza significativamente la nostra esperienza e la nostra carriera come developer.
+
+Ma quello che incide più di tutto è il modo in cui il management e i vari reparti gestiscono i progetti, a prescindere dalla tipologia di azienda.
+
+Sicuramente le aziende di prodotto hanno come principale priorità quella di salvaguardare la **qualità** di ciò che viene sviluppato, per cui è molto più probabile che la loro attenzione sia rivolta verso la **formazione** e la **soddisfazione** dei propri dipendenti come strategia per trattenere le competenze acquisite e i talenti.
+
+Questo non significa che tutte le aziende di consulenza non siano attente ai propri dipendenti e prediligano la quantità alla qualità. Come spiegato precedentemente, alcune aziende di consulenza, approcciandosi con la metodologia "_chiavi in mano_" riescono a curare i progetti dei clienti nella loro interezza, aumentando anche la **sensazione di appartenenza** dei propri dipendenti.
+
+Sperando che adesso abbiate più chiare le principali differenze, potete fare la vostra scelta consapevole!
diff --git a/docs/it/come-affrontare-l-eta-nel-mondo-it.md b/docs/it/come-affrontare-l-eta-nel-mondo-it.md
new file mode 100644
index 00000000..d03c0cbc
--- /dev/null
+++ b/docs/it/come-affrontare-l-eta-nel-mondo-it.md
@@ -0,0 +1,87 @@
+---
+layout: default
+title: Come affrontare l'età nel mondo IT
+nav_order: 5
+---
+
+
+# Come affrontare l'età nel mondo IT
+{: .no_toc }
+
+- TOC
+{:toc}
+
+
+
+In questo capitolo esploreremo la questione dell'età nel contesto dell'ambito IT. Spesso trascurato, questo aspetto riveste notevole rilevanza per coloro che operano in questo settore da qualche anno. Molte persone si trovano a confrontarsi con l'interrogativo sulla propria competitività nel mercato del lavoro in relazione all'età, chiedendosi se sono ancora in grado di mantenere un livello di competenza adeguato alle nuove tecnologie o se, viceversa, sono destinati a navigare tra mansioni manageriali, abbandonando il ruolo tecnico.
+
+È opportuno precisare che l'obiettivo di questo capitolo non è di certo dare delle certezze assolute o definire percorsi di carriera uguali per tutti, poiché ogni persona è unica e diversa in termini di passioni, ambizioni e attitudini. Quelle che seguono sono quindi delle considerazioni _personali_ che potrebbero aiutarti a comprendere come vuoi vivere la tua carriera dopo molti anni di esperienza e riflettere sulle implicazioni che potrebbero comportare alcune scelte.
+
+## Continuare ad essere dev, oppure diventare manager?
+
+Molto probabilmente questa è una domanda che hai già posto qualche volta, oppure ti sarà capitato di fare considerazioni simili con i tuoi colleghi durante la pause pranzo, o, addirittura anche con il/la tuo/a referente nei momenti dedicati alle valutazioni delle tue performance. Possiamo affermare che la maggior parte di chi sviluppa, con già qualche anno di esperienza alle spalle, risponderebbe che è possibile continuare a fare il dev anche dopo decine di anni di esperienza senza dover necessariamente abbandonare il codice. D'altronde se si è diventati developer per pura passione dello sviluppo, perché smettere?
+
+Forse, tu che leggi, penserai che con l'età che inizia ad avanzare possa risultare più arduo rimanere al passo con le tecnologie e che di conseguenza possa essere difficile rimanere competitivi rispetto ad una persona più giovane, spesso più aggiornata e stimolata. Pensiero assolutamente corretto e condivisibile, considerando che ragionamenti analoghi possono essere fatti anche su discipline diverse dal mondo IT. Ci sono decine di articoli che è possibile trovare in rete nei quali si evidenzia come sia più complicato trovare lavoro in età adulta, con consigli su come reinventarsi o su come rimanere competitivi in un mondo del lavoro che continua ad evolversi di anno in anno.
+
+Ma torniamo al pianeta IT: se hai già letto il capitolo _Cosa significa "essere dev"?_ avrai già realizzato che fare questo mestiere significa affrontare molte cose, non solo avere a che fare con linguaggi, librerie e frameworks. Chi si occupa di sviluppo deve realizzare che questi strumenti servono per uno scopo: risolvere problemi. Conoscere la nuova tecnologia non aiuta molto il core business di cui sei parte se non si applica bene al tuo dominio o alla necessità del momento. Molto spesso un/a dev giovane con tanta voglia di fare e sperimentare, cade in questo errore. Una persona che sviluppa da tanti anni potrà dare un contributo di valore nell'ambiente in cui si trova e aiutare anche dev più giovani a fare scelte più ponderate e corrette. Se tu che leggi, magari ancora non hai deciso come vuoi impostare la tua carriera, al di là della tua età e degli anni di esperienza, per lavorare al massimo in questo settore, poniti come obiettivo di non scrivere solo "bel codice", ma di portare _valore_ in ciò che fai per la tua azienda.
+
+## Pensare al "vero" obiettivo
+
+Ripetiamo: il lavoro del/la developer è (anche) risolvere problemi. Il nostro scopo non è, e non sarà sempre, trovare soluzioni accattivanti, magari con le tecnologie del momento, ed è questa la maturità che deve acquisire un/a developer negli anni e con l'esperienza.
+
+Vogliamo evidenziare questo aspetto con un aneddoto riportato nel libro Clean Architecure di Robert C. Martin. Senza entrare troppo nei dettagli, che puoi trovare nel libro, durante una sua esperienza lavorativa alla fine degli anni Ottanta ha dovuto, per pura esigenza di marketing, impiegare un database relazionale in un sistema di cui si occupava. Ma per motivi ingegneristici lui affermava che non era assolutamente necessario avere un database in quel sistema, che raggiungeva appieno il suo scopo così com'era, ma il mercato di quel periodo voleva i database nei sistemi, e l'azienda _accontentò_ il mercato. Dal canto suo, Martin era focalizzato sull'obiettivo ingegneristico reale, e crediamo che debba essere questa la competenza che chi fa questo lavoro dovrebbe sviluppare col tempo.
+
+Facciamo un esempio più recente: i microservizi. Chissà in quanti annunci di lavoro li avrai visti in questi ultimi anni.
+Oltre a valutare i vantaggi (e gli svantaggi) di questa architettura, sembra che non se ne possa più fare a meno. Peccato che nel marzo 2023 il team di Prime Video ha pubblicato un [post](https://www.primevideotech.com/video-streaming/scaling-up-the-prime-video-audio-video-monitoring-service-and-reducing-costs-by-90) sul proprio blog, indicando che con il passaggio da un'architettura distribuita a microservizi a un'architettura monolitica ha ridotto i costi infrastrutturali di oltre il 90%. Il team di Prime Video si è focalizzato su un obiettivo preciso: ottimizzare i costi, e ci sono riusciti con una soluzione tanto semplice quanto _classica_, il **monolite**.
+
+I due esempi sono diversi in termini di situazione e tempi, ma ci fanno comprendere una cosa: il nostro lavoro è cercare il modo migliore di raggiungere l'obiettivo ingegneristico che aiuti il business, a prescindere dalle mode del momento.
+
+Se sei un/a developer che riconosce del valore nelle scelte che compie, perché preoccuparsi dell'età che avanza?
+
+## Diventare manager
+
+Facciamo una breve considerazione sul diventare manager in modo da giungere alle dovute riflessioni che potrebbero esserti utili semmai un giorno dovessi fare questa scelta. Per manager intendiamo, per semplicità e senza andare troppo nel dettaglio, quei ruoli che non sono coinvolti nelle decisioni, e operativi per quanto concerne l'aspetto tecnico ma sostanzialmente incentrati nella gestione di alto livello dei progetti e dei team.
+Abbiamo constatato che è possibile rimanere dev anche con l'avanzare dell'età, ma molto spesso diventare manager sembra quasi l'unico modo per fare carriera. Ci sono realtà aziendali con una gerarchia tale per cui chi fa sviluppo è giunto solo ad un primo step della propria carriera, una base dalla quale poter avanzare, prima o poi, abbandonando la via del codice a favore di quella manageriale. Noi ci auguriamo che questo non sia il tuo caso, ma può capitare che il contesto lavorativo in cui ci si trova influenzi il modo di percepire la carriera e di conseguenza le nostre scelte, perché vediamo un'unica strada davanti a noi. Questo potrebbe indurci a pensare che non raggiungere un ruolo manageriale dopo molti anni di esperienza equivalga a un fallimento di carriera, portando noi stessi a sentirci in quel momento inadeguati rispetto alle richieste del mercato. Per evitare ciò, si sceglie di diventare manager per raggiungere una sorta di traguardo professionale e, perchè no, anche economico e di benefit che spesso sono legati a questo tipo di ruolo.
+
+A te che leggi, vogliamo dire che non è così: se in te c'è passione per lo sviluppo, non hai l'obbligo di intraprendere percorsi manageriali. La programmazione offre molte sfide e soddisfazioni che puoi trovare in contesti diversi da quello nel quale probabilmente ti trovi attualmente. Continua a studiare, ad approfondire e a confrontarti con altre persone con la tua stessa passione. E se dovessi realizzare di non trovarti bene nel contesto attuale, cerca realtà aziendali dove ci sono percorsi alternativi, che ti permetteranno di crescere tecnicamente e di continuare a perseguire i tuoi obiettivi.
+
+Concludiamo questa sezione dicendoti che non vogliamo convincerti a non diventare manager. Ci sono tante sfide in questo ruolo che sicuramente ti potrebbero dare molte soddisfazioni. Diventa manager, abbandonando pure la parte tecnica e il codice se ti rivedi in questa figura, se questo ruolo ti appassiona e sei convinto di questa decisione. Siamo certi che se intraprenderai questo percorso con decisione e passione potrai diventare un manager con il quale tutti avranno piacere di collaborare.
+
+## Non _solo_ developer
+
+Fermiamoci a riflettere brevemente su questa domanda apparentemente innocua ma allo stesso tempo interessante: se desideriamo continuare a scrivere codice, è necessario rimanere developer per sempre?
+
+Probabilmente nella tua mente starai già pensando al tuo contesto aziendale o alle tue precedenti esperienze, ricostruendo mentalmente le responsabilità di figure _ibride_ tra ruoli tecnici e manageriali, per citarne alcune: Team Leader, Tech Lead e Solution Architect a cui i/le developer fanno riferimento per ciò che riguarda decisioni più o meno delicate su aspetti tecnici. Come forse saprai, non è detto che queste figure, prese da altre responsabilità o coinvolte in altri processi più organizzativi, riescano ancora effettivamente a scrivere codice. Ogni realtà solitamente ridefinisce questi ruoli, proiettandoli nei propri contesti. Per esempio, un/a team leader in una startup che è poco strutturata è probabile che continui a sviluppare, rispetto a realtà più grandi e oliate dove il team leader è più simile a una figura manageriale. Ci sono, invece, realtà molto flessibili che danno la libertà ai propri team leader di gestirsi e decidere quanto addentrarsi negli aspetti tecnici.
+
+Questi ruoli sono molto interessanti e sfidanti qualora fare _solo coding_ iniziasse a non bastarti. Se vuoi gestire un team e avere responsabilità differenti, sicuramente prima o poi potrai intraprendere uno di questi percorsi senza rinunciare del tutto all'aspetto tecnico.
+
+Quale sia la tua scelta, ricorda che se vuoi essere un/a developer che aggiunga valore nonostante l'età, non è sufficiente che ti limiti alla programmazione, ma è necessario contribuire a ogni aspetto del progetto: sia che tu rivesta il ruolo di developer o di team leader, impegnati costantemente nel risolvere problemi e suggerire soluzioni, senza farti distrarre dai limiti imposti dai ruoli.
+Se sei ancora junior, proponi soluzioni anche se non hai la certezza in merito alla loro correttezza. Non solo l'impegno nello studio e nell'approfondimento, ma anche e soprattutto trarre insegnamento dai propri errori è un ottimo modo per crescere.
+Così, dopo anni di esperienza, potrai mettere in campo molte conoscenze che figure più giovani del team probabilmente non avranno.
+
+Un/a developer che sa comunicare e sa trasmettere le proprie conoscenze ad altri, sarà sempre di grande valore per un team e avrà un'autorevolezza al suo interno a prescindere dal ruolo e soprattutto dall'età.
+
+## Il bias del fare codice a vita
+
+La carriera di chi sviluppa è complessa sotto molti punti di vista e non priva di incognite: al primo posto possiamo assolutamente prendere coscienza del fatto che sia una categoria nuova e in continua evoluzione. Guardando alcuni schemi che illustrano l'evoluzione e le competenze necessarie per una particolare mansione, diventa evidente di fronte a noi un albero di opzioni impressionante. Da un punto di vista più generale non possiamo ignorare la crescita verso determinate mansioni più gestionali e meno operative, è un pensiero che prima o poi si tende a fare. Questo è legato non solo all’ambizione ma anche ad una considerazione sul proprio futuro, in generale sull’invecchiamento intellettuale e sulle conseguenze che inevitabilmente può avere sul nostro rendimento, sulla nostra freschezza e sulla capacità di stare dietro ad un mondo, quello informatico, in perenne vorticoso movimento; questo rendimento è legato a doppio filo con il nostro intelletto.
+
+Dal punto di vista della catalogazione, l’intelligenza, come capacità di risolvere un problema, viene descritta come Fluida o Cristallizzata (teorizzata dallo psicologo Cattell). La prima, quella fluida, è il pensiero logico, la nostra capacità di risolvere problemi nuovi. Quella cristallizzata, invece, è la nostra capacità di utilizzare le conoscenze pregresse; questa è quella che di solito cade sotto il nome di “seniority”. Nel lavoro di chi sviluppa sono importanti entrambe probabilmente in egual misura.
+
+Il passare del tempo va intuitivamente a beneficio dell'intelligenza cristallizzata perché ci dà un bacino più ampio da cui attingere. In passato questa catalogazione veniva legata al Q.I. da cui prende anche il nome, rappresentato dal rapporto tra età psicologica e anagrafica (da cui quoziente). L’intelligenza fluida, invece, ha una caratteristica inversa, segue un andamento decrescente con l'avanzare dell'età, facendoci perdere freschezza. Le nostre performance come velocità, capacità di visualizzazione ed elaborazione sono legate a questi due elementi che sommati formano il nostro intelletto.
+
+Gli studi più recenti (A Novembre 2023) a riguardo sono stati svolti dall’Università di Monaco, racchiusi in un articolo dal titolo ["Life cycle patterns of cognitive performance over the long run" di Anthony Strittmatter](https://www.pnas.org/doi/10.1073/pnas.2006653117) che ha studiato e cercato di dare una risposta quantitativa e non solo qualitativa alla domanda: _quanto è differente un cervello giovane da uno vecchio e quale è il periodo in cui rende di più?_.
+
+Il punto di partenza è stato quello di capire quale sia il metodo migliore per misurare questa performance senza farsi influenzare. Il campione in questo caso è fondamentale: cultura, classe sociale e posizione geografica possono influenzare il risultato ed è semplicemente intuibile; l’allenamento delle proprie capacità e la possibilità di stare vicino a chi detiene conoscenze avanzate danno sempre strumenti migliori per affrontare i problemi. Da questo lato la sfida è molto interessante perché sappiamo bene quanto un bias cognitivo possa influenzare non solo i risultati ma anche la loro interpretazione.
+
+Per questa analisi si è quindi deciso di usare gli scacchi come metro; le partite, infatti, sono catalogate dal 1890 e la vittoria è legata a processi cognitivi prettamente meritocratici dove tutti quei parametri in cui il dato può essere influenzato hanno meno peso. Il bacino si è presentato piuttosto ampio, sono a disposizione tutte le mosse in un arco di 125 anni, circa 24.000 partite. A questo punto sono stati elaborati collegando età e qualità delle mosse e la velocità con cui venivano eseguite, una ad una; per analizzare la validità delle mosse è stato usato un famoso motore di scacchi open source Stockfish.
+
+Il risultato è piuttosto disarmante, è stato notato innanzitutto che il picco di performance è tra i 35 e i 45 anni. Questo va un poco a sfatare il fatto che la giovane età sia legata a performance migliori in assoluto. Da questo punto di vista si nota come l’avanzare dell’età non faccia che migliorare la qualità delle nostre capacità per molti anni; questo chiaramente da un punto di vista prettamente statistico, picchi in tutte le direzioni sono possibili e sono quelli che spesso danno forza ai nostri bias. I dati hanno anche mostrato una cosa altrettanto interessante sugli estremi di questa curva: la quantità di performance guadagnata e poi persa con l’età. Ci troviamo di fronte ad una campana schiacciata, prima sale (dai 20) e poi scende (verso i 55). L’escursione in ambo i lati, ovvero nei 20 e poi nei 55, è solamente intorno al 10%.
+
+In buona sostanza, ciò che è evidente è che la nostra volontà di fare carriera non deve essere influenzata dalla preoccupazione di non farcela al sopravanzare di una certa età; per lo meno non deve esserlo dal punto di vista delle capacità intellettive. Statisticamente non c’è un vero e proprio declino cognitivo, ma ci si trova più che altro di fronte alla stanchezza o alla propria ambizione di cambiamento. Molti informatici famosi hanno sostenuto questa affermazione: _la carriera non deve essere intesa nella sola direzione manageriale_; se chi si trova a dover prendere questa scelta ha la voglia e la passione, può continuare a fare questo lavoro a vita, non c’è qualcosa che veramente ce lo neghi dal punto di vista fisiologico. Che carriera intraprenderemo quindi deve essere frutto di un desiderio, di una necessità che non sia legata alla paura di invecchiare; anche questo tema sarà sicuramente rivisto negli anni a venire anche dal punto di vista del mercato del lavoro.
+
+**Se vi piace programmare e avere le mani in pasta ed essere operativi, non fatevi spaventare dell’avanzare dell’età: è più un bias che un ostacolo tangibile!**
+
+## Conclusioni
+
+In questo capitolo abbiamo parlato di come affrontare l'età nel mondo IT. Questo è sempre un tema delicato, e non riguarda solo il mondo IT, senza considerare che ci sono tanti fattori collegati ad esso: famiglia, figli, tempo che non basta mai per aggiornarsi e studiare, stanchezza, ecc..
+L'obiettivo era di darti modo di fare le tue considerazioni, con l'auspicio che ciò possa portarti ad una maggiore chiarezza riguardo al tuo percorso professionale futuro, e che la passione, la volontà di dare sempre il tuo contributo e di condividere le tue esperienze con il team, possano continuare a farti a sviluppare con entusiasmo senza timore dell'età che avanza.
diff --git a/docs/it/community-e-networking.md b/docs/it/community-e-networking.md
new file mode 100644
index 00000000..0a1ceac4
--- /dev/null
+++ b/docs/it/community-e-networking.md
@@ -0,0 +1,113 @@
+---
+layout: default
+title: Community e Networking
+nav_order: 9
+---
+
+
+# Community e Networking
+{: .no_toc }
+
+- TOC
+{:toc}
+
+
+
+Questo capitolo nasce per due motivi: Il primo è quello di sfatare il mito del dev asociale, il secondo è quello di spiegare come fare networking e perché è così importante in un settore come il nostro.
+
+## Asocialità nel mondo Dev
+
+Chi sviluppa software è spesso visto come una persona asociale, tendenzialmente nerd e propensa a passare le sue giornate senza interagire con nessuno. Eppure, il mondo dello sviluppo software è tra i più vivi da un punto di vista di networking e community. Come mai, quindi, questa percezione è così radicata?
+
+### Perché si è propensi a pensare che i dev siano asociali?
+
+Non possiamo negare che esistano sviluppatori o sviluppatrici che non amano interagire con gli altri o stare in mezzo alla gente e che preferiscono passare le loro giornate in solitudine. Questo è vero, ma sarebbe sbagliato pensare che questo sia un tratto distintivo della nostra professione. In ogni settore lavorativo esistono persone che incarnano queste caratteristiche, quindi non è corretto pensare che il dev sia asociale per natura.
+
+Detto questo, è vero che lo sviluppo software è un lavoro che richiede molta concentrazione e che spesso si lavora in solitudine, il che può portare a una certa tendenza all'isolamento. Agli albori dell'informatica, quando non esistevano ancora i social network e le community online, era molto più facile per chi facesse questo lavoro isolarsi, il che ha portato alla nascita di una percezione così radicata che spesso anche chi fa parte del settore si stupisce di quante community esistano e di quanto sia facile fare networking.
+
+### Esistono Dev non asociali?
+
+Come abbiamo visto, la percezione del dev asociale è radicata, ma non corretta. Lo sviluppo software è di per sé un lavoro che spesso richiede di isolarsi, ma la carriera di chi sviluppa software è molto più ricca di questo. Il networking e la partecipazione alle community sono due aspetti fondamentali per chiunque voglia intraprendere questa carriera, tanto che spesso sono considerati requisiti fondamentali per chi vuole fare carriera.
+
+Il ruolo del dev è cambiato molto negli ultimi anni e oggi è molto più vicino al business e alla comunicazione rispetto a quanto non fosse in passato, o perlomeno, lo è per chi vuole fare il salto di qualità. Questo significa che un/una dev deve essere in grado di comunicare con colleghi di altri reparti, con i clienti e con i superiori, deve essere in grado di vendere le proprie idee e di convincere gli altri a seguire le sue idee. Queste sono tutte competenze che si acquisiscono con l'esperienza, ma che possono essere affinate anche attraverso il networking e la partecipazione alle community.
+
+## Community
+
+Le community sono un aspetto opzionale, ma molto importante per chiunque voglia intraprendere la carriera di sviluppatore. Sono un luogo dove poter imparare, confrontarsi e crescere, ma anche un luogo dove poter fare networking e conoscere persone che potrebbero aiutarci a crescere professionalmente e umanamente.
+
+### Cosa sono le community?
+
+Le community sono collettivi di persone che condividono un interesse comune. Nel nostro caso, le community sono un insieme di persone che condividono l'interesse per lo sviluppo software, anche in modo molto verticale.
+
+Questi collettivi si incontrano online o offline per confrontarsi, imparare e crescere insieme. Gli argomenti sono tra i più disparati, ma spesso si tratta di argomenti tecnici, come un linguaggio di programmazione, un framework o una libreria.
+
+### Perché partecipare alle community?
+
+Consideriamo la partecipazione alle community fondamentale, ma non obbligatoria, per chiunque voglia intraprendere la carriera di sviluppatore. Le community come detto sono un luogo di crescita personale e professionale, permettono inoltre di fare networking e ampliare la propria cerchia di conoscenze e amicizie, le quali potrebbero aiutarvi ad aprirvi molte possibilità future.
+
+Le community inoltre sono uno dei migliori modi per imparare qualcosa di nuovo, perché tendenzialmente in queste avviene uno scambio di conoscenze gratuite tra i vari membri! Quello che potreste apprendere un giorno, potreste insegnarlo ad altri!
+
+Ovviamente tra i pro non possiamo non citare il divertimento, le community sono luoghi di ritrovo di persone con uguali interessi, quindi potrebbe essere più facile per una persona creare un legame con queste.
+
+### Come partecipare alle community?
+
+Partecipare alle community è molto semplice. Esistono community online e offline, quindi possiamo scegliere quella che più ci si addice. Le community online sono molto più facili da raggiungere, ma quelle offline sono molto più ricche dal punto di vista del networking. Per non fare torti a nessuno, in questo capitolo non citeremo alcuna community in particolare, ma ci limiteremo a dire che molte di queste community sono raggiungibili tramite i social network, come Facebook, Twitter, Instagram, LinkedIn, Telegram, Discord, Slack, Meetup (Orientato alle community offline), ecc. e molte delle persone più attive sui social fanno parte di diverse community, quindi spesso sarà sufficiente seguire queste per entrare a far parte del loro mondo.
+
+### Come creare una community?
+
+Interessi in comune, passione e costanza sono gli ingredienti fondamentali per creare una community. Se abbiamo un interesse in comune con altre persone, una passione che vogliamo condividere e la costanza di portare avanti un progetto, possiamo creare una community. Non esiste una ricetta magica per farlo, ma esistono alcune regole che possiamo seguire per aumentare le probabilità di successo.
+
+- **Sii inclusivo**: Le community sono fatte di persone e ogni persona è diversa dall'altra. Se vogliamo creare una community, dobbiamo essere inclusivi e accettare le diversità. Non possiamo pensare di creare una community se non siamo disposti ad accettare questo.
+- **Sii costante**: La costanza è fondamentale per creare una community. Se io stesso non partecipo attivamente alla vita del mio gruppo, perché dovrebbero farlo gli altri? Se vogliamo creare una community, dobbiamo essere i primi a partecipare attivamente alla vita del gruppo.
+- **Trova un tema**: Le community nascono attorno a un tema, quindi dobbiamo trovare un tema che sia abbastanza ampio da poter attrarre un numero sufficiente di persone, ma abbastanza specifico da poter creare un gruppo di persone con interessi in comune.
+- **Stabilisci delle regole**: Se vogliamo creare una community, dobbiamo stabilire delle regole che permettano alle persone di interagire in maniera civile e rispettosa. Questo aspetto risulta sempre più importante con l'aumentare del numero di persone che partecipano alla community.
+- **Non demoralizzarti**: Se ci tieni veramente alla tua community non demoralizzarti se questa non diventa popolare. Capiamo possa essere un bel traguardo, ma non è fondamentale! Anche una community più raccolta può risultare molto attiva e portare dei benefici ai suoi membri!
+- **Essere aperti**: Il mondo delle community è fatto anche di collaborazione tra le stesse. Spesso, infatti, le community si aiutano a vicenda e si supportano, anche solo facendosi pubblicità a vicenda o scambiandosi consigli e risorse. Non chiudersi in se stessi e cercare di collaborare con altre community può portare a risultati inaspettati.
+
+## Networking
+
+Con networking intendiamo la capacità di creare e mantenere relazioni con altre persone, in particolare con altre persone che lavorano nel nostro stesso settore o condividono i nostri stessi interessi.
+
+### Networking all'inizio della carriera
+
+Il networking è importante per chiunque voglia intraprendere la carriera di sviluppatore, ma è particolarmente cruciale per chi si trovi agli inizi della carriera. Non avendo ancora un curriculum da poter mostrare e senza le competenze necessarie per poter essere assunti, possono risultare fondamentali le connessioni che si creano per poter trovare le prime opportunità. Quando si è agli inizi, inoltre, si ha ancora la possibilità di scegliere il proprio percorso e il networking è fondamentale per poter apprendere le varie opportunità che il mondo dello sviluppo software offre.
+
+### Networking e carriera
+
+Non puoi mai sapere se la persona seduta accanto a te in un meetup o in una conferenza potrebbe essere il tuo prossimo datore di lavoro o il tuo prossimo cliente, o più semplicemente un futuro collega che ti aprirà le porte di un'azienda in cui vorresti lavorare.
+
+Fare networking può aprirti possibilità che nemmeno pensavi di avere e può aiutarti a crescere professionalmente in maniera esponenziale. Non è raro, infatti, che un dev venga assunto in un'azienda grazie a una conoscenza che lo ha raccomandato per una posizione o che un dev noto internamente in un'azienda venga contattato dalla stessa per una posizione che non era stata ancora pubblicizzata, aumentando così le possibilità di essere assunto.
+
+Sicuramente tutti questi pro sono molto importanti, ma una cosa che non andrebbe mai trascurata è la bellezza di poter conoscere gente nuova e creare nuove connessioni genuine e durature.
+
+### Come faccio networking online?
+
+Negli ultimi anni (Decennio 2013-2023) il networking online è diventato sempre più importante e il grosso delle opportunità da questo punto di vista si trova su LinkedIn. Questo non significa che non si possa fare networking anche su altri social network, ma LinkedIn è sicuramente il social network più utilizzato per il nostro settore.
+
+Per fare networking su LinkedIn è necessario creare un profilo professionale, che sia in linea con il nostro settore di appartenenza e che sia aggiornato con le nostre esperienze e le nostre competenze. Una volta creato il profilo, sarà sufficiente iniziare a connettersi con altre persone, possibilmente con persone che potenzialmente condividano i nostri stessi interessi.
+
+Una volta connessi, sarà possibile interagire con queste persone, commentando i loro post o inviando loro messaggi privati. Questo ci permetterà di creare una relazione con loro e ci permetterà di farci conoscere. Questo è il primo passo per fare networking su LinkedIn.
+
+Ovviamente, come precedentemente detto non esiste solo LinkedIn, ma anche partecipare a una community online affine può essere un ottimo modo per iniziare ad accrescere la propria rete di contatti.
+
+Non esiste una formula magica da questo punto di vista, ma anche in questo caso, costanza e passione sono ingredienti fondamentali per intraprendere questo percorso.
+
+### Come faccio networking offline?
+
+Il networking offline è molto più difficile da intraprendere, ma è anche molto più efficace. Per fare networking offline è necessario partecipare a eventi, come meetup e conferenze, e interagire con le persone che partecipano a questi eventi.
+
+Come potrai immaginare, in questo caso bisognerà essere il meno timidi possibile e non aver timore delle altre persone! Potresti cominciare ponendo delle domande senza pensare a se e quanto queste possano essere stupide, nessuno nasce con tutte le risposte pronte!
+
+Come citato qualche paragrafo più in alto, non puoi mai sapere quanto una qualsiasi persona presente nella stanza possa influire sulla tua carriera, quindi cerca di interagire con tutti e cerca di conoscere il più possibile le persone che partecipano a questi eventi.
+
+Vuoi un esempio pratico del potere del networking? Questo capitolo fa parte di un libro scritto da una community di persone che condivide la passione per l'Open Source, e la prima stesura è stata fatta da due persone che si sono conosciute grazie ad un'amicizia in comune, a sua volta dev, che ci ha presentati e ci ha permesso di conoscerci. A distanza di parecchi mesi da quel primo contatto, abbiamo deciso di scrivere questo capitolo insieme dopo esserci visti ad un paio di conferenze, a dimostrazione di quanto il networking sia imprevedibile quanto efficace.
+
+## Posso fare questo lavoro senza fare networking?
+
+La risposta è, come sempre nel nostro settore, "dipende". Il networking è sicuramente un aspetto importante nella carriera dev, ma questo non significa che sia impossibile fare carriera senza fare networking.
+
+Come ogni altro aspetto di questo lavoro, networking e community sono _opportunità_ che abbiamo e che possiamo usare come trampolino di lancio o come banco di prova, ma non sono _necessità_. Se non ci sentiamo a nostro agio nel partecipare alle community o nel fare networking, non dobbiamo forzarci, ma dobbiamo essere consapevoli che questo potrebbe limitare le nostre possibilità di crescita, o comunque renderle più difficili.
+
+## Conclusioni
+
+In questo capitolo abbiamo visto come il networking e la partecipazione alle community siano due aspetti fondamentali per chiunque voglia intraprendere la carriera di sviluppatore. Sono due aspetti che possono aiutarci a crescere professionalmente e che possono aprirci opportunità che altrimenti non avremmo, ma è bene ricordare che non sono _necessità_, ma _opportunità_ che abbiamo e che possiamo sfruttare per crescere sia personalmente che professionalmente.
diff --git a/docs/it/cosa-significa-essere-dev.md b/docs/it/cosa-significa-essere-dev.md
index e245f64d..77be84c8 100644
--- a/docs/it/cosa-significa-essere-dev.md
+++ b/docs/it/cosa-significa-essere-dev.md
@@ -1,4 +1,17 @@
+---
+layout: default
+title: Cosa significa "essere dev"?
+nav_order: 2
+---
+
+
# _Cosa significa "essere dev"?_
+{: .no_toc }
+
+- TOC
+{:toc}
+
+
La domanda, di per sé, è piuttosto semplice.
diff --git a/docs/it/senior.md b/docs/it/senior.md
new file mode 100644
index 00000000..0b24fd4c
--- /dev/null
+++ b/docs/it/senior.md
@@ -0,0 +1,413 @@
+---
+layout: default
+title: Sviluppatore "senior"
+nav_order: 8
+---
+
+
+# Sviluppatore "senior"
+{: .no_toc }
+
+- TOC
+{:toc}
+
+
+
+L'industria del software si muove alla velocità della luce.
+
+Come sviluppatori software siamo costantemente bombardati da notizie di _nuove_ tecnologie, _nuovi_ framework, _nuovi_ linguaggi, _nuovi_ paradigmi, _nuovi_ modelli organizzativi, _nuovi_ modelli di sviluppo, _nuovi_ modelli di deployment, _nuovi_ modelli di testing, _nuovi_ modelli di integrazione, _nuovi_ modelli di delivery, _nuovi_ modelli di monitoraggio, etc.
+
+Una valanga travolgente di innovazione che non da segni di rallentamento.
+
+È questa l'arma a doppio taglio nelle mani di uno sviluppatore software. Da una parte abbiamo a che fare con infinite opportunità di crescita e il prospetto di non annoiarci mai. Dall'altra parte, siamo sempre alla rincorsa della "next big thing" e, per quanto ci sforziamo di stare al passo con i tempi, siamo sempre inesorabilmente un passo indietro.
+
+In questo contesto così dinamico, cosa significa essere uno sviluppatore "senior"?
+
+Facendo un parallelo, se per esempio dovessimo dare una definizione di un profilo "senior" nell'industria aeronautica, potremmo pensare al ruolo del capitano.
+
+Il capitano di un aereo è un profilo che è responsabile di tutti gli aspetti del volo, del velivolo, dei passeggeri e del personale di bordo. È un profilo che può sicuramente contare su diversi anni di studio, una grande esperienza (esplicitamente espressa in ore o miglia di volo). È sicuramente un percorso lungo che richiede tanta dedizione, ma anche un percorso piuttosto chiaro e standardizzato e che probabilmente non ha avuto significative variazioni negli ultimi 40 anni...
+
+Possiamo trovare una definizione simile anche in ambito software?
+
+_Dipende!_
+
+In questo capitolo cercheremo di esplorare cosa significa essere senior in ambito software. Discuteremo cosa può e deve offrire un senior al suo team e alla sua azienda, dagli aspetti più tecnici (hard skills) a quelli più umani (soft skills).
+
+Ma prima di imbarcarci in questo viaggio, è importante puntualizzare che non esiste una definizione canonica di "senior": ogni azienda, ogni team e ogni individuo hanno la propria definizione.
+
+La nostra esplorazione sarà contaminata dalle opinioni e le esperienze personali degli autori e lo spirito di questo capitolo non è quello di offrire una guida assolutamente corretta su come diventare senior in dieci mosse, ma piuttosto essere un piccolo almanacco di buone pratiche per ispirare coloro che ambiscono a diventare senior e per coloro che sono già riconosciuti come tali e sono alla ricerca di spunti per migliorarsi.
+
+## Senior? Si, ma quanto?
+
+Immaginiamo per un attimo di essere il CTO di un'azienda in forte crescita. Abbiamo costruito un prodotto grazie al supporto di un'azienda di consulenza esterna, ma adesso è fondamentale portare lo sviluppo _in-house_ e costruire un team interno per poter rendere l'azienda stabile e raggiungere i prossimi obiettivi di crescita.
+
+Quello che ci serve in questa fase è un team di sviluppatori senior che possa costituire la base attorno alla quale costruire e far crescere un team più ampio e variegato di professionisti del software.
+
+Iniziamo a pensare a come scrivere una _job spec_ - ovvero una descrizione dell'offerta e del ruolo - per la ricerca di questi sviluppatori senior. Cosa dovremmo scrivere? Cosa dovremmo cercare? Come definiamo il profilo che stiamo cercando?
+
+Non abbiamo ancora scritto il titolo del profilo ricercato e siamo già in preda ad un blocco creativo. Forse è il caso di andare a sbirciare cosa fanno le aziende concorrenti o altre aziende leader nel mercato del software...
+
+Dopo una breve ricerca online, ci troviamo ad avere compilata una lista di possibili ruoli che sembrano essere sinonimi di _senior_: Sviluppatore Senior, Sviluppatore _Staff_, Sviluppatore _Principal_, Architetto del software, Sviluppatore Mago, Sviluppatore Barbabianca, Sviluppatore Unicorno, Rockstar, Ninja, Guru...
+
+OK. Sembra quasi che stiamo cercando di creare un gruppo di appassionati di Dungeons and Dragons più che un team di sviluppatori software... ci serve una pausa!
+
+Dopo aver preso un caffè e aver fatto un giretto in giardino, torniamo alla scrivania e riprendiamo a ragionare su cosa stiamo cercando. Decidiamo di ignorare i vari titoli visti online e di concentrarci sul valore che stiamo cercando di portare all'interno della nostra azienda.
+
+Cosa ci serve? Cosa ci aspettiamo da questi sviluppatori senior?
+
+Un senior dovrebbe essere qualcuno che sia in grado di far progredire progetti e persone. Qualcuno che, con le proprie competenze, possa moltiplicare la produttività aziendale. Si, un _"moltiplicatore di forze"_, questo è quello che ci serve!
+
+Non vogliamo un eroe solitario in grado di scrivere migliaia di righe di codice al giorno e di produrre tanto quanto dieci sviluppatori! Piuttosto cerchiamo un individuo che sappia giocare di squadra e che sappia valorizzare e massimizzare le competenze e le esperienze di tutti i membri del team.
+
+Ok, facile a dirsi... ma, nella pratica, di quali competenze, compiti e responsabilitá stiamo parlando? Quale dovrebbe essere l'attitudine di questo profilo senior?
+
+## Gli anni di esperienza
+
+Una delle caratteristiche chiave che è possibile riscontrare nella maggior parte delle offerte di lavoro nel mercato del software è il numero di anni di esperienza.
+
+"Ricerchiamo professionista volenteroso con 5 anni di esperienza con React.js".
+
+Oppure piú genericamente: "Ricerchiamo professionista con almeno dieci anni di esperienza nel settore dello sviluppo software".
+
+Questo tipo di frasi sono così comuni da sembrare quasi banali e ogni tanto riescono anche a rubare qualche sorriso.
+
+Ecco un esempio simpatico. Sebastián Ramirez (anche conosciuto come _@tiangolo_), famoso per aver creato il web framework [FastAPI](https://fastapi.tiangolo.com/), postò [un tweet](https://twitter.com/tiangolo/status/1281946592459853830) menzionando un annuncio di lavoro nel quale si cercava un professionista con 5 anni di esperienza proprio con FastAPI. Beh, lui stesso, benché creatore e massimo esperto di FastAPI, non era idoneo per quell'opportunità in quanto aveva creato FastAPI solo 2 anni prima e non aveva ancora acquisito i 5 anni di esperienza richiesti!
+
+Ah, se solo potessimo tornare indietro nel tempo!
+
+Sembrerà ridicolo, ma è invece indicativo di quanto le offerte di lavoro abbiano requisiti assolutamente irrealistici e di quanto spesso si enfatizzino gli anni di esperienza con determinate tecnologie piuttosto che le competenze acquisite.
+
+Ok, tornando al punto, quanti anni servono per essere un senior? O ancora, qual è l'età minima richiesta per poter essere considerati degli sviluppatori senior?
+
+Queste sono due delle domande più fuorvianti da porsi nel mondo software, per quanto incredibilmente comuni!
+
+Perché?
+
+Beh, ritornando a indossare gli abiti del nostro fantomatico CTO, assumeremmo qualcuno solo perché è stato dieci anni seduto ad una scrivania a guardare lo schermo di un computer o lo assumeremmo perché è in grado di contribuire alla risoluzione di specifici problemi di business?
+
+È vero che aver investito più tempo in certe attività potrebbe significare aver avuto più occasioni per imparare ed eccellere in una data disciplina. Ma il mondo software è una disciplina così complessa ed in continuo cambiamento in cui l'equazione "tanto tempo = grandi competenze" diventa una semplificazione troppo banale e rischiosa.
+
+Nella mia carriera ho avuto la fortuna di lavorare con dei colleghi giovani ma brillanti, in grado di comprendere a fondo problemi tecnici e di business e in grado di dare un grandissimo contributo al team in cui lavoravano.
+
+Mi è anche capitato di lavorare con colleghi con tanti anni di esperienza e anche grosse aziende sul CV che invece si sono limitati a fare il minimo indispensabile e, quando coinvolti nella risoluzione di problemi complessi, mostravano serie lacune sia tecniche che di comprensione del business.
+
+Certo, queste sono estremizzazioni e non sono sicuramente la norma. Il punto è che non bisogna assolutamente puntare né agli anni di esperienza né all'età, ma piuttosto mirare alle competenze acquisite e alla capacità (e volontà) di continuare ad acquisirne di nuove.
+
+## Le competenze
+
+Se non è una questione di anni di esperienza sul campo su cosa dobbiamo concentrarci?
+
+Se definiamo un senior come qualcuno in grado far progredire progetti e persone, ci saranno sicuramente delle competenze necessarie al fine di poter raggiungere questi obiettivi.
+
+Queste competenze non sono esclusivamente tecniche ma anche non tecniche o di comunicazione. Uno sviluppatore senior deve saper familiarizzare con piú linguaggi di programmazione, framework, database, architetture software, etc, ma deve anche avere ottime capacità comunicative, di leadership, di business e problem-solving.
+
+A volte le _skill_ non tecniche possono risultare anche più importanti di quelle prettamente tecniche, perché non importa solamente quello che sai, ma soprattutto come tu sia in grado di trasmetterlo permettendo agli altri di sfruttare il tuo sapere, come condividere la tua esperienza, sbloccare situazioni difficili e rendere il gruppo di lavoro autosufficiente e produttivo.
+
+L’attitudine al comando è altrettanto importante, in quanto è responsabilità del senior quella di fare da tutor ai junior della squadra, dirigere i vari gruppi del progetto e prendere le scelte tecniche più difficili. Ed è suo anche il compito di motivare la squadra, assegnare i compiti in modo efficace e fare da guida e supporto all’occorrenza.
+
+Un’altra capacità indispensabile per lo sviluppatore senior è la propensione alla risoluzione dei problemi. Uno sviluppatore senior deve essere in grado di pensare in modo critico, analizzare problemi complessi e trovare soluzioni creative. Dovrebbe essere a suo agio all’interno di situazioni poco chiare e non ancora definite, pronto ad adattarsi ad ogni nuovo sviluppo.
+
+In fin dei conti, l’ingegneria del software non è altro che risoluzione di problemi!
+
+Tuttavia, i problemi non sono sempre di natura tecnica, specie all’interno delle organizzazioni più strutturate, dove sono presenti interlocutori con esperienze diverse e di differente formazione. In questo contesto i problemi possono essere comunicati nel modo sbagliato e mutare di frequente. Per questo diventa fondamentale contribuire alla comprensione dei problemi che si stanno riscontrando, formulare e condividere gli obiettivi e guidare la squadra di lavoro nella giusta direzione; competenze cruciali, queste, che possono avere un impatto enorme.
+Per questo, a volte, la migliore soluzione da un punto di vista strettamente tecnico non è necessariamente la migliore soluzione per una data azienda.
+
+Un senior dovrebbe essere in grado di riconoscere queste situazioni e di abbandonare soluzioni tecnicamente ottimali in favore di soluzioni piú adatte alla squadra e alle circostanze di business.
+
+Un esempio estremo potrebbe essere quello di uno sviluppatore capace di scrivere codice di basso livello e iper-ottimizzato per un dato obiettivo. Questo approccio potrebbe limitare l'accesso al progetto a pochissimi individui con competenze simili. Quante aziende hanno veramente l'esigenza di produrre codice così ottimizzato? Spesso è più conveniente puntare all'agilità e alla possibilità di iterare e sperimentare velocemente.
+
+Le competenze tecniche da sole non bastano a comprendere tutte le sfaccettature di un progetto e a trovare soluzioni che soddisfino tutte le necessità di business e spesso i migliori compromessi possono essere trovati con il giusto equilibrio di competenze sia tecniche che di business.
+
+## Il profilo a "T"
+
+Concentriamoci un attimo sulle competenze tecniche. Dopotutto, visto come funziona il settore del software oggigiorno, questo è il primo aspetto sul quale uno sviluppatore viene valutato! Se non si è in grado di dimostrare delle competenze tecniche adeguate alle aspettative, allora si avranno pochissime chance di emergere ed ottenere un'offerta di lavoro o una promozione!
+
+In qualità di sviluppatore senior, possedere competenze tecniche che coprano diverse aree è fondamentale. Per essere uno sviluppatore senior di successo è essenziale avere un profilo a _“forma di T”_ (o _T-Shaped profile_), che si concretizza nel saper padroneggiare una specifica competenza pur possedendo solide e ampie basi in altre aree.
+
+Immagina di disegnare una "T". la linea verticale rappresenta una profonda conoscenza in una specifica area tecnica. Più questa linea è lunga più si è raggiunta una padronanza della specifica area tecnica. Invece, la linea orizzontale rappresenta una vasta conoscenza in tante altre aree, non necessariamente una conoscenza approfondita ma sufficiente sviluppata da fornire i mezzi per poter spaziare tra gli argomenti piú disparati durante una conversazione tecnica.
+
+Questo tipo di profilo permette al singolo individuo di poter contribuire in modi diversi ad un progetto pur essendo esperto nella propria area di specializzazione primaria: avendo competenze diverse, i profili a T consentono una collaborazione efficace con membri di lavoro, aprendo la strada ad un processo di sviluppo con maggiori probabilità di successo.
+
+Un buon modo per costruire il profilo a T è quello di iniziare a sviluppare il tuo tratto verticale, ovvero quello che alla fine diventerà il tuo punto di forza! Concentrati per un po’ su una singola area. Ovviamente è meglio preferire delle aree tecniche per le quale ci si senta particolarmente propensi e per le quali si abbia un grosso interesse. Più qualcosa ci appassiona, più è facile stare al passo con l'innovazione e trovare il tempo per sperimentare ed imparare.
+
+Quando pensi di avere raggiunto la padronanza di una data competenza tecnica, allora potrai espandere la tua conoscenza partendo da lì, sviluppando così il tratto orizzontale. Esci fuori dalla tua comfort zone ed esplora argomenti correlati. Questi argomenti dovrebbero auspicabilmente arricchire le tue conoscenze pregresse e permetterti di contribuire in modo più esteso ai vari aspetti dello sviluppo di un prodotto software.
+
+Se, ad esempio, diventassi esperto nello sviluppo di API REST, potresti voler approfondire i database o lo sviluppo front-end, in quanto l'insieme di queste competenze ti permetterebbe di avvicinarti ad un profilo da programmatore full-stack. Allo stesso modo, potresti anche approfondire l’argomento IaC (_infrastructure-as-code_) ed imparare ad implementarlo nel processo produttivo. Non limitarti a scrivere software ma cerca di capire anche cosa è necessario per portare quel software in produzione.
+
+Il segreto non sta nel diventare un esperto in ognuna di queste ulteriori aree ma nell’apprendere quanto basta per capire le basi e per poter collaborare in modo efficace con chi, invece, le padroneggia a fondo.
+
+## Comprendere i compromessi
+
+Ad uno sviluppatore senior serve una vasta conoscenza dei principi dello sviluppo di software, che comprende non solo algoritmi e strutture dati ma anche diversi modelli architetturali, organizzazione del codice, testing, processi di sviluppo e scalabilità.
+
+L'idea è quella di sviluppare un pensiero critico, grazie al quale si possa essere in grado di comprendere e confrontare tecnologie, e paradigmi diversi e i compromessi che ne derivano.
+
+Un esempio classico potrebbe essere quello di comprendere e discutere le differenze e i compromessi tra architetture monolitiche o a microservizi. O ancora i compromessi che derivano da scelte di ottimizzazione che favoriscono la memoria piuttosto che la CPU. E così via: "alta scalabilità" contro "bassa latenza", "software generico e riutilizzabile" contro "software su misura", "complesso ed efficiente" contro "semplice e flessibile".
+
+Non ci sono soluzioni corrette o sbagliate, ma solo compromessi differenti. Ed è fondamentale comprendere questi compromessi e prevederne l’effetto, sia nel breve che nel lungo termine. La domanda da farsi è "quale compromesso è quello migliore per gli obiettivi di business presenti e futuri"?
+
+Raggiungere questo livello di maturità è tutto fuorché semplice. Sicuramente necessita di una significativa quantità di tempo investito nello sviluppare prodotti software, adottando diverse pratiche, diversi linguaggi di programmazione, framework, metodologie e così via.
+
+Potrai ampliare le tue conoscenze solamente se saprai riconoscere che ogni scelta tecnica comporta una serie di compromessi. Ci saranno sempre aspetti positivi e negativi.
+
+Purtroppo non esiste una formula magica per la tecnologia!
+
+Non esiste un singolo linguaggio o framework che possa essere utilizzato per costruire qualsiasi tipo di applicazione in modo ottimale! Se hai una visione sufficientemente completa del panorama tecnologico, dovresti essere in grado di capire quale insieme di tecnologie è il piú adatto per affrontare un problema specifico. Talvolta questo significa essere in grado di mettere da parte le nostre tecnologie preferite o quelle che fanno parte delle nostre competenze primarie e che ci fanno sentire piú produttivi a livello individuale.
+
+Ovviamente, non sempre possiamo avere una visione cristallina di ogni problema. Spesso bisogna confermare le proprie assunzioni con degli esperimenti ad hoc ed essere pronti ad essere smentiti.
+
+Bisogna trovare il modo di lasciare margine per commettere errori, imparare dai fallimenti e provare approcci alternativi. La strada per il successo raramente è una linea retta…
+
+## Andare a caccia di bug
+
+È risaputo che il software privo di bug non esiste; quindi, non proviamo neanche a pensare che uno sviluppatore senior possa scrivere codice senza bug!
+
+Benché i bug siano sempre dietro l'angolo, uno sviluppatore senior deve sapere cosa fare per ridurre al minimo il rischio di creare dei bug. Analogamente lo sviluppatore senior deve sapere come individuare i bug il più presto possibile, possibilmente prima che lo facciano gli utenti.
+
+Questo comporta sviluppare tutta una serie di competenze quali: comprendere ed approfondire i resoconti degli utenti, scrivere diversi tipi di test (unitari, di integrazione, end-to-end), individuare ed analizzare i casi limite, strutturare i log in modo che siano più facili da leggere e ricercare in caso di errori, riuscire a leggere ed interpretare varie metriche e dashboard.
+
+Un senior dovrebbe essere in grado di fare una grande differenza e di aiutare l’intero team a scrivere un software migliore, illustrando ed educando alle migliori pratiche per il test del software.
+
+Direi che non è troppo difficile scrivere test, ma scrivere buoni test è quasi un’arte! Per scrivere test efficaci, è necessario scrivere codice testabile. Ciò significa progettare codice modulare, privo di dipendenze e con input e output ben definiti. Quanto migliore è la progettazione del codice, tanto più facile sarà scriverne i test.
+
+I test devono essere facili da leggere, comprendere e mantenere. Usa nomi descrittivi per i tuoi test e scrivi test che coprano una caratteristica o un comportamento specifico. Evita di testare più funzioni nello stesso test, in quanto potrebbe rendere più difficile individuare l’origine dell’errore.
+
+Ma come imparare a fare tutto questo?! Anche qui, pratica, pratica e ancora pratica!
+
+Inizia accettando il fatto che il codice non testato è cattivo codice (o per lo meno codice che dovrebbe tenerti sveglio la notte). Quindi cerca di capire il settore aziendale specifico e che cosa ha senso testare e come. Quale tipo di input è più rappresentativo, quale tipo di output ci si aspetta e che tipo di effetti collaterali possono verificarsi.
+
+Impara i diversi tipi e i diversi framework di test. Infine, impara quali tipi di test forniscono il maggior valore per l’azienda e ottimizza il flusso di lavoro del team per concentrarvi maggiormente su questi fattori.
+
+## Promuovere le buone pratiche
+
+Uno sviluppatore senior dovrebbe aver sviluppato un certo grado di affinità con diversi linguaggi di programmazione e dovrebbe conoscere diversi paradigmi e le loro differenze. Ad esempio la programmazione ad oggetti (OOP) e quella funzionale; uno stile dichiarativo rispetto ad uno imperativo; differenze tra linguaggi compilati e interpretati. Possedere questo tipo di competenze può essere utile per risolvere lo stesso problema utilizzando strumenti e tecniche differenti e potendo così scegliere la soluzione che offre i compromessi più idonei per il problema in questione e per il team con cui si lavora.
+
+Similarmente è importante avere una buona conoscenza dei design pattern al fine di riuscire a strutturare il codice in modo più flessibile, rendendo più semplici potenziali evoluzioni future.
+
+Il codice è un elemento che dovrà evolversi con il cambiare delle esigenze del business ed è quindi importante progettare tenendo conto dell’evoluzione. I design pattern non sono una panacea ed a volte è facile abusarne e creare troppi livelli di astrazione. Un buon senior dovrebbe riuscire a trovare il giusto equilibrio tra semplicità e flessibilità.
+
+Bisogna conoscere le buone pratiche come i principi del "_Clean code_" ma è anche importante non essere dogmatici, ovvero applicare tutti i design pattern e le buone pratiche solo perché possiamo farlo. Bisogna piuttosto chiedersi: "qual è il vantaggio di applicare uno specifico pattern ad un dato problema?". Oppure "qual è il costo in termini di complessità aggiuntiva?".
+
+A volte, del codice semplice e imperativo, benché possa apparire poco elegante, può risultare molto efficace in termini di leggibilità. Altre volte, invece, è necessaria la struttura imposta da specifici design pattern, perché questa potrebbe rendere il codice più testabile, estendibile, configurabile, ecc.
+
+Come sviluppatore senior, essere in grado di fornire opinioni critiche su questi temi può avere un impatto estremamente positivo sul resto del team durante sessioni di _pair programming_ o revisioni del codice.
+
+## Quali tipi di soft skills?
+
+Abbiamo discusso le competenze tecniche che ti daranno un vantaggio nella tua carriera e ti permetteranno di essere riconosciuto come sviluppatore senior. Ma queste da sole non ti porteranno molto lontano. È arrivato il momento di discutere delle fantomatiche "soft skills".
+
+Se hai ottenuto quel colloquio per quella posizione a cui tieni tanto grazie alle tue competenze tecniche, riuscirai ad eccellere e a farti assumere se sarai in grado di dimostrare di avere delle solide soft skills.
+
+Ok, ok, ma quali sono queste soft skills? Come faccio a svilupparle? Come faccio a dimostrare di averle?
+
+È possibile trovare online liste infinite di soft skills che includono intraprendenza, capacità di comunicazione, cura per i dettagli, attitudine al "_problem solving_", leadership, negoziazione, gestione del tempo, e chi più ne ha più ne metta.
+
+Di seguito discuteremo alcune soft skills che ritengo essere fondamentali per un senior. Non è una lista da considerare esaustiva ma piuttosto un punto di partenza per capire in quali ambiti è possibile misurarsi e migliorarsi.
+
+### Voglia di crescere
+
+La mentalità di uno sviluppatore senior è cruciale quanto le sue competenze tecniche. Un ingegnere senior deve avere una mentalità incline alla crescita, la volontà di imparare e adattarsi e la propensione al continuo miglioramento.
+
+Siamo tutti consapevoli di quanto velocemente si evolva il mondo del software, lo abbiamo già detto ed una situazione di disagio che viviamo tutti i giorni. L'unica arma in nostro possesso per poter sopravvivere in questo mondo è quella di essere in grado di imparare velocemente e di adattarci ai cambiamenti.
+
+Imparare però significa anche essere a proprio agio con i fallimenti e vederli come un’opportunità per imparare. Questo significa talvolta essere disposto a correre dei rischi, provare soluzioni o tecnologie con le quali non abbiamo molta confidenza ed essere pronti a tornare indietro sui propri passi qualora quell'approccio non porti i frutti sperati.
+
+Ogni fallimento però è un passo in avanti verso il successo, una lezione appresa che ci permetterà di non ripetere gli stessi errori in futuro e di essere più consapevoli delle scelte che facciamo.
+
+### Essere una leva attiva, saper dire "NO" e debito tecnico
+
+Uno sviluppatore senior dovrebbe avere un ruolo molto proattivo in un’organizzazione. Non dovrebbe isolarsi in una stanza e continuare a sbattere le dita contro la tastiera. Un senior dovrebbe sapere quando è il momento di fare domande scomode e prendere in mano la situazione.
+
+Essere in grado di fornire un punto di vista fortemente tecnico in una conversazione aziendale può avere grande impatto e informare l’azienda su quale sia la strategia migliore per andare avanti. A tutti gli effetti, un senior dovrebbe diventare un ponte tra il prodotto e la tecnologia.
+
+Questo a volte significa che un senior dovrebbe anche sapere quando è il momento di dire NO. No a soluzioni rapide e sporche (che alla fine si ritorceranno contro) solo per rispettare una scadenza. No a piani che prevedono solo la costruzione di funzionalità su funzionalità senza considerare l’esperienza dell’utente e la stabilità a lungo termine del prodotto. No a scelte tecniche arbitrarie solo perché “abbiamo sempre fatto così ed è sempre andata bene”.
+
+Dire NO è facile ma al tempo stesso molto difficile. Tutti possono dire NO, questa è la parte facile! Il difficile è argomentare il perché di quel NO, proporre punti di vista alternativi, trovare compromessi e disinnescare bombe a orologeria a breve o lungo termine.
+
+Per riuscire a farlo serve un elevato livello di soft skills: devi saper comunicare in modo efficace usando le parole giuste e scegliere con saggezza le tue battaglie. Non puoi dire sempre NO a tutto o corri il rischio di essere preso per un ostruzionista scorbutico.
+
+Si tratta piuttosto di saper dire “NO, MA” piuttosto che un secco “NO”: provvedere ad una valida alternativa, seppur non ottima tecnicamente o di requisiti, è parte del ruolo. A volte è necessario accettare compromessi e fare scelte che non sono necessariamente le migliori dal proprio punto di vista. Ma è importante essere in grado di riconoscere quando è il momento di dire NO e quando è il momento di accettare un compromesso.
+E dovresti anche essere in grado di farlo di fronte alle persone giuste e al momento giusto… Se fatto bene, questo può avere un forte impatto positivo sull’azienda e sul team. Può portare all’innovazione e creare nuove potenzialità di lavoro o vantaggi competitivi unici.
+Questo è un argomento che viene spesso tirato in ballo quando si parla di debito tecnico, ovvero scelte tecniche non ideali che a lungo termine possono portare a problemi di stabilità e scalabilità fino al punto di danneggiare il business. Più il tempo passa e più il debito tecnico si accumula e più sarà difficile ripagarlo.
+
+Il debito tecnico è un argomento molto complesso e non esiste una soluzione unica per tutti i casi. A volte è necessario accettare un debito tecnico per poter rispettare una scadenza o per poter testare un'idea. Altre volte è necessario investire tempo per ripagare il debito tecnico accumulato in passato.
+
+Le capacità di un senior dovrebbero permettergli di capire quando è il momento di accettare un debito tecnico e quando è il momento di investire tempo per ripagarlo. Inoltre, dovrebbe essere in grado di comunicare in modo efficace i rischi associati al debito tecnico e le conseguenze che questo potrebbe avere sul business. Infine, un senior dovrebbe riuscire a negoziare con i product manager e i dirigenti per trovare il giusto compromesso tra debito tecnico e scadenze.
+
+### Capire l’azienda
+
+Per poter essere una leva attiva bisogna capire l’azienda il più profondamente possibile.
+
+Qual è lo scopo dell’azienda? Qual è la visione nel lungo termine? Esiste una strategia chiara? Quali sono i grandi punti di forza e quali di debolezza? Chi sono i clienti? Quali sono i prodotti e i servizi offerti? Quali sono i principali concorrenti?
+
+Un senior che sa rispondere a queste domande è in una buona posizione per utilizzare le proprie competenze tecniche per aiutare l’azienda ad avere successo.
+
+Solo con una solida comprensione dell’azienda sarai in grado di scegliere le battaglie giuste, concentrarti su ciò che conta e di contribuire alla progettazione di sistemi che possano servire l’azienda oggi ma anche essere adattati alle esigenze future.
+
+### La Comunicazione
+
+> "La buona comunicazione è stimolante quanto il caffè nero e rende altrettanto difficile il prendere sonno poi" - Anne Morrow Lindbergh
+
+Come ingegnere del software, le capacità comunicative sono fondamentali per il successo del riconoscimento della tua figura: devi essere in grado di comunicare efficacemente con diversi interlocutori, tra cui altri ingegneri, project manager, clienti e dirigenti. Ciò richiede un’ampia gamma di abilità comunicative, dal parlare e ascoltare allo scrivere e presentare (o farle tutte e quattro assieme).
+
+Poiché dovrai parlare con tutti gli interlocutori, dovresti imparare a comunicare concetti tecnici a interlocutori non tecnici in un modo che sia facile da comprendere. Ciò significa anche saper ascoltare i commenti e incorporarli nel tuo lavoro. La capacità di comunicare efficacemente con gli interlocutori è essenziale per garantire che tutti siano sulla stessa lunghezza d’onda e che i progetti siano portati a termine con successo.
+
+Un’altra importante abilità comunicativa per un ingegnere del software è quella di spiegare le incertezze e proporre idee su come affrontarle. Lo sviluppo del software è un processo intrinsecamente incerto e ci saranno sempre incognite e sfide impreviste.
+
+Come ingegnere del software, devi essere in grado di comunicare queste incertezze in modo chiaro e conciso. Devi anche essere in grado di proporre idee su come affrontare queste incertezze e far progredire il progetto.
+
+Inoltre, gli ingegneri del software devono essere in grado di parlare degli errori e delle lezioni apprese. È importante sottolineare che il fallimento è una parte inevitabile dello sviluppo del software ed è importante essere trasparenti sui fallimenti e sulle lezioni apprese. Ciò richiede capacità di comunicazione efficaci, compresa quella di assumersi la responsabilità degli errori e di comunicare onestamente. Inoltre, è necessario saper comunicare le lezioni apprese dai fallimenti e incorporarle nei progetti futuri. In un certo senso, un errore può anche essere visto come un investimento a lungo termine. Se questo viene comunicato bene può essere percepito in modo assolutamente positivo da parte dell'azienda e può convincere ad investire ancora di piú nella ricerca di nuove soluzioni e pratiche di sviluppo.
+
+Le capacità comunicative sono essenziali anche per la stesura della documentazione e per le presentazioni. Gli sviluppatori devono essere in grado di scrivere una documentazione chiara che spieghi come funzionano le loro soluzioni e come devono essere utilizzate e gestite nella produzione. Devono inoltre essere in grado di fornire presentazioni che comunichino efficacemente i concetti tecnici a un pubblico non tecnico. Ciò richiede una grande capacità di scrittura e di presentazione, oltre all’abilità di semplificare argomenti complessi e renderli digeribili per il pubblico.
+
+Una buona comunicazione può aprire molte porte e sbloccare situazioni complesse. Assicurati quindi di esercitarla il più possibile!
+
+### Supporto alla gestione
+
+Quando sei un buon comunicatore, diventi una persona che può essere molto efficace nel supportare diverse attività di gestione. Ad esempio, nella pianificazione e nell’organizzazione degli incontri. Puoi aiutare a tenere traccia delle priorità e del debito tecnico e a suddividere i compiti difficili in parti più gestibili.
+
+Ti trovi in una posizione unica per capire e sfruttare i punti di forza del team e per coinvolgere le persone giuste al momento giusto. Lavorando a stretto contatto con la direzione, puoi assicurarti che il tuo lavoro sia in linea con gli obiettivi aziendali generali e che gli sforzi del tuo team siano incanalati nella giusta direzione.
+
+La pianificazione è un’altra abilità determinante per un ingegnere del software. Richiede di suddividere i progetti di grandi dimensioni in attività più piccole e gestibili, di stimare il tempo necessario per ciascuna attività e di stabilirne la priorità. Una pianificazione efficace contribuisce a garantire che i progetti siano portati a termine in tempo e nel rispetto del budget.
+
+L’organizzazione degli incontri, come le riunioni in piedi, le revisioni informali e le retrospettive, possono offrire l’opportunità di condividere i progressi, identificare i problemi e pianificare il futuro. Come ingegnere del software, devi contribuire a guidare questi incontri e assicurarti che siano produttivi ed efficienti.
+
+Ovviamente gli sviluppatori senior non devono e non possono sostituire il ruolo dei project manager o dei product manager, ma piuttosto devono supportare questi ruoli e fornire la loro prospettiva tecnica per riuscire a mantenere gli obiettivi, i piani e l’esecuzione in linea con le aspettative del team tecnico.
+
+### Autonomia e attenzione alla consegna
+
+Le ultime due soft skills su cui ci soffermeremo sono l’autonomia e l’attenzione alla consegna.
+
+Gli sviluppatori senior hanno un ruolo prezioso nei progetti tecnici che richiedono grande dedizione e competenza. Questi progetti, come ottimizzare le prestazioni o ristrutturare l'architettura del codice, sono fondamentali per l'azienda, poiché aprono nuove possibilità di innovazione e crescita. Grazie alla loro esperienza, i senior possono apportare un contributo significativo a tali iniziative, aiutando a sbloccare il potenziale del team e dell'azienda nel suo complesso.
+
+In base alla mia esperienza, spesso un individuo può fare progressi rapidi in progetti tecnici, dedicandosi intensamente a questa attività per un breve periodo. Tuttavia, è essenziale evitare l'isolamento dal resto del team, anche in queste circostanze.
+
+Se stai lavorando a un progetto di questo tipo, assicurati di comunicare regolarmente con la direzione e altri colleghi senior per tenere sotto controllo i tuoi progressi, ottenere un riscontro utile e condividere le tue conoscenze.
+
+Ma la capacità di fornire valore lavorando in autonomia non è utile solo nei progetti di ricerca, ma è anche una buona abilità da padroneggiare in generale. Nell’industria del software, è più comune lavorare con cose che non conosciamo piuttosto che con cose che conosciamo!
+
+Ci sono sempre nuovi ambiti da esplorare, nuove sfide da affrontare e nuovi strumenti con cui confrontarsi. Pertanto, è importante essere in grado di imparare rapidamente e di aggiornarsi velocemente quando necessario. Non dovresti aspettare che siano gli altri a insegnarti e a dirti come fare certe cose, ma dovresti essere in grado di fare alcuni progressi per conto tuo, ad esempio consultando e comprendendo la documentazione e il codice esistente.
+
+Se avessi già una vasta competenza, dovrebbe essere quasi istintivo aggiungerne altra quando necessario. Naturalmente, è giusto chiedere aiuto se ti senti bloccato, ma è anche importante cercare di fare tutto il possibile per progredire da solo, in modo da costruire il maggior contesto possibile e massimizzare il risultato del tempo speso a ricevere aiuto da altri.
+
+In teoria, un ingegnere del software senior non ha bisogno di troppe indicazioni. È in grado di capire da solo ciò che è necessario per portare avanti le cose e di coinvolgere gli altri nel momento opportuno.
+
+Un altro aspetto riguarda la negoziazione delle aspettative e la comprensione di ciò che significa avere successo nell’ambiente attuale.
+
+È bene essere chiari con la direzione e con il resto del team tecnico e definire le caratteristiche del successo individuale e di squadra. Se non sai cosa ci si aspetta da te e dal resto del team, anche se pensi di fare la cosa giusta, potresti finire per non fornire il valore che ci si aspetta da te; allo stesso modo, potresti non essere in grado di aiutare il tuo team ad avere successo.
+
+Avere un simile atteggiamento di schiettezza e chiarezza di solito mantiene l’umore più alto e aiuta a evitare le delusioni. Certo, non è sempre possibile evitare tutte le delusioni o i fallimenti. Perciò, quando il problema si presenta, potresti essere tentato di dare la colpa a qualcun altro o al sistema. Ma è invece più maturo chiedersi cosa si sarebbe potuto fare meglio, o ancora meglio: cosa si potrebbe fare in futuro per evitare che problemi simili si ripresentino.
+
+## Come posso crescere?
+
+Se sei un ingegnere del software e vuoi aumentare le tue competenze e diventare un membro senior del tuo team, potresti chiederti quali sono i passi da intraprendere per raggiungere questo obiettivo.
+
+Beh, non temere! Ecco 4 idee (più alcune extra) che credo ti aiuteranno nel tuo percorso.
+
+### Scendere giù di un livello
+
+Innanzitutto, non limitarti a sfiorare la superficie delle tecnologie con cui stai lavorando. Scava più a fondo e impara a conoscere gli strati sottostanti. Probabilmente hai costruito un sito web o un'API, ma ti sei mai chiesto come funziona il protocollo HTTP? O anche come funziona il protocollo TCP e cosa succede per stabilire una connessione? Apprezzare questi dettagli ti darà una comprensione molto più ricca delle tecnologie con cui lavori ogni giorno.
+
+Sì, se cominci a scavare diventa un pozzo senza fondo... Quindi come fare ad addentrarsi più a fondo senza perdersi?
+
+La mia regola generale (che ho rubato/appreso dal mio amico [Roberto](https://www.linkedin.com/in/gambuzzi/)) è quella di scendere solo di un livello più in basso alla volta, partendo dalle tecnologie con cui si ha già familiarità.
+
+Possiamo immaginare un dato ambito tecnologico come una torre. Ogni piano della torre rappresenta tecnologie diverse, ognuna delle quali ha un livello di astrazione diverso. Ad esempio, il piano più alto potrebbe essere il livello di applicazione, il piano intermedio potrebbe essere il livello di rete e il piano più basso potrebbe essere il livello fisico. Verosimilmente il nostro lavoro ci richiede di conoscere molto bene un dato livello. Non è necessario conoscere tutti i livelli. Tuttavia, conoscere il livello immediatamente inferiore può essere molto utile per capire meglio il livello in cui lavoriamo.
+
+Ti serve qualche esempio?
+
+Hai già trascorso un po’ di tempo con OAuth e OpenID Connect? Probabilmente vorrai sapere cosa c’è dentro un JWT. Conosci il flusso del codice di autorizzazione OAuth e cosa succede con tutti i reindirizzamenti? Sai come funzionano gli algoritmi di firma come RSA e HMAC?
+
+Tutti questi sono argomenti che puoi esplorare per consolidare la tua conoscenza di questo particolare ambito. Ti permetteranno di esplorare concetti più generali che potresti riutilizzare in altri ambiti. Tutti costituiscono dei validi passi in avanti per ampliare le tue conoscenze e diventare un ingegnere più completo.
+
+Ed il modo migliore per esplorare questi piani è quello di costruire qualcosa. Puoi capire veramente qualcosa se riesci a costruirne un piccolo prototipo. Ad esempio potresti provare a decodificare un token JWT senza usare una libreria. Saresti poi in grado di andare oltre e implementare anche l’algoritmo di verifica della firma? Magari poresti anche provare a implementare un server OAuth2.0 per capire meglio come funziona il protocollo.
+
+Costruire prototipi è un ottimo modo per memorizzare alcuni concetti e mettere davvero alla prova la vostra conoscenza. Naturalmente, costruire richiede uno sforzo maggiore, quindi scegli con saggezza gli esercizi di prototipazione: non sarebbe pratico re-implementare oltre sessant'anni di ingegneria del software solo per il gusto di imparare!
+
+Un video divertente che mi è piaciuto molto ultimamente è [The Computer Science Iceberg](https://www.youtube.com/watch?v=H565avw-ufk). Perché mi piace così tanto? Perché è divertente, ironico e soprattutto perché illustra davvero bene l’idea di livelli graduali di astrazione e di ricerca di conoscenze fondamentali e generiche.
+
+### Divertiti
+
+Questa è una delle mie convinzioni principali: l’ingegneria del software è una professione molto impegnativa. Non perché sia più difficile di altre professioni, ma perché le cose si muovono così velocemente che non puoi mai smettere di imparare e ti sentirai sempre indietro.
+
+L’unica cosa che potrebbe rendere la professione un po’ più facile è una vera passione per la materia. Se sei appassionato, sarà più facile motivarti a imparare sempre cose nuove! E se non so se sono abbastanza appassionato? È comprensibile, soprattutto se sei all’inizio della tua carriera. C’è così tanto davanti a te che potrebbe essere spaventoso e persino scoraggiante.
+
+Anche in questo caso, il mio consiglio è di orientarti verso lo sviluppo di progetti concreti. Sviluppare qualcosa ti darà un riscontro tangibile del fatto che ciò che stai imparando può essere effettivamente utile. Potresti realizzare dei progetti secondari per mettere in pratica le nuove conoscenze.
+
+Inoltre, non dovresti essere timido nel mostrare ciò che hai costruito (e ciò che hai appreso) ai tuoi colleghi e persino ai tuoi amici al di fuori del lavoro! È probabile che riceverai un riscontro e che ti verranno in mente nuove idee e nuove cose che vorresti imparare e provare.
+
+Ancora meglio se ti rendi conto che puoi applicare alcune di queste conoscenze al lavoro. Magari potete sviluppare un nuovo percorso all’interno dell’azienda per cui lavori, magari potresti aiutare in qualcosa che al momento viene trascurato perché nessun altro ha il tempo o le competenze, magari tutto questo può dimostrare un valore maggiore e otterrai una promozione!
+
+Quando si applica questa mentalità di apprendimento continuo e di condivisione delle conoscenze sul lavoro, si potrebbe generare una stimolazione reciproca e ritrovarsi con un team che si diverte a imparare e a costruire insieme.
+
+Un’altra idea per far entrare le persone in sintonia tra loro e generare una stimolazione reciproca delle idee è quella di organizzare hackathon aziendali o giornate di studio gratuite. Questi sono ottimi modi per aiutare i team ad appassionarsi a ciò che fanno, a esplorare nuove idee, a imparare cose nuove e, in definitiva, a mettere le persone in condizione di fornire più valore nel breve e nel lungo termine.
+
+### Pair programming
+
+Il pair programming è un altro grande strumento che puoi sfruttare per dare una spinta alle tue competenze. Collaborare con il maggior numero possibile di persone all’interno dell’organizzazione è fondamentale. Anche se qualcuno è più giovane di te, può comunque avere intuizioni e prospettive che forse non avevi considerato prima. La programmazione in coppia offre una piattaforma per condividere idee e imparare gli uni dagli altri.
+
+Allo stesso modo, non scartare il valore dell’insegnamento agli altri. Anche i membri più anziani del team possono beneficiare delle tue conoscenze e della tua esperienza. Se fai coppia con altri, puoi condividere le tue competenze e aiutare tutti a crescere e a svilupparsi.
+
+Ho imparato tantissimi trucchi lavorando in coppia con altre persone. Anche piccole cose, come la configurazione dell’editor o del terminale. Lo so: non tutti amano la programmazione in coppia. Se questo è il caso, non preoccuparti! Ci sono altri approcci da seguire che possono comunque fornirti un feedback prezioso e aiutarti a imparare dai tuoi colleghi. Le revisioni interattive del codice e le sessioni di dimostrazione sono ottime alternative che consentono di condividere il proprio lavoro e ricevere riscontri senza dover lavorare insieme in tempo reale.
+
+Alla fine, la cosa più importante è rimanere aperti a nuove idee e approcci. Continuando a imparare e a crescere, saresti sulla buona strada per diventare uno sviluppatore di software senior. Quindi, perché non provare a fare un po' di pair programming e vedere cosa riesci a imparare?
+
+### Creazione di contenuti
+
+Prima di tutto, la creazione di contenuti può assumere diverse forme: articoli, presentazioni, video, discussioni tecniche su canali social, e chi più ne ha più ne metta! E indovina un po’? Non occorre essere un esperto per condividere qualcosa di nuovo che hai imparato. Anche se sei alle prime armi con un determinato argomento, la tua nuova prospettiva può portare valore agli altri e aiutarti a confrontarti con i gente più esperta nello specifico settore.
+
+Potresti ad esempio creare dei contenuti per dare le tue prime impressioni dopo aver provato un nuovo linguaggio di programmazione o un framework. Cosa ti è piaciuto? C’è stato qualcosa che ti ha confuso? Cosa ti è mancato rispetto alla tua precedente esperienza con altri strumenti simili?
+
+C'è un trucco: devi farlo diventare un’abitudine. Impegnati a seguire un programma regolare e svilupperai disciplina e coerenza nella creazione di contenuti. Inoltre, più creerai, più affinerai le tue capacità di comunicazione. E lo ripeto ancora una volta: la comunicazione è un’abilità fondamentale per qualsiasi sviluppatore senior.
+
+A proposito di comunicazione, è qui che la creazione di contenuti brilla. Come ingegneri, amiamo perderci nei dettagli tecnici, ma spiegare concetti complessi a interlocutori non tecnici può essere difficile. Creando contenuti, imparerai a comunicare i tuoi concetti in modo chiaro e coinvolgente per un pubblico più ampio. Inoltre, avrai l’opportunità di ricevere un parere sui tuoi contenuti e, se presterai attenzione, potrai migliorare ulteriormente le tue capacità comunicative.
+
+Hai mai sentito parlare di [_atomic essays_](https://www.ship30for30.com/post/how-to-write-an-atomic-essay-a-beginners-guide) (saggi atomici)? Si tratta di suddividere le tue idee in parti di contenuto più brevi e mirate. Questo approccio può rendere i tuoi contenuti più coinvolgenti e più facili da assimilare, soprattutto su piattaforme social come X (Twitter), dove la brevità è fondamentale. Se non sai che tipo di contenuti creare, questo potrebbe essere un buon formato per iniziare.
+
+Se non sai su cosa creare contenuti, ecco il mio consiglio: ogni giorno, alla fine della tua giornata lavorativa, scrivi una cosa nuova che pensi di aver imparato durante la giornata. Alla fine della settimana lavorativa, rivedi i tuoi punti. Sono sicuro che per almeno uno di questi potrebbe essere un argomento da condividere e sul quale potresti creare dei contenuti.
+
+La creazione di contenuti può aiutarti a diventare uno sviluppatore più esperto, affermandoti come personaggio di rilievo in un dato ambito, sviluppando le tue capacità di comunicazione e contribuendo alla comunità. Quindi, vai e condividi le tue conoscenze con il mondo.
+
+Ti sorprenderai dell’impatto che avrà su di te e sugli altri!
+
+### Altre idee
+
+Ecco alcuni altri consigli in ordine sparso che puoi aggiungere a quelli discussi sopra.
+
+Innanzitutto, cerca sempre di mantenere un atteggiamento positivo. Quando le cose si fanno difficili, è facile scoraggiarsi e perdere di vista il quadro generale. Ma ricorda che con tempo e risorse sufficienti, i team possono superare qualsiasi sfida. Quando manca questo lusso, sono certo che esistono compromessi accettabili che possono soddisfare le esigenze di tutti.
+
+Un’altra idea interessante per aggiornarsi ed evitare di restare troppo indietro in fatto di tecnologia o di stili di programmazione è quella di allenarsi con le "coding challenges", ovvero esercizi di programmazione come quelli che puoi trovare su [HackerRank](https://www.hackerrank.com/), [CodeWars](https://www.codewars.com/) o [Exercism](https://exercism.org/). Questi problemi spesso richiedono di scoprire o rispolverare specifici algoritmi o strutture dati. Puoi inoltre usare questi esercizi per esplorare nuovi linguaggi o metodologie. Sforzati di sperimentare diversi modi per risolvere i problemi. È un ottimo esercizio per le tue capacità di risoluzione dei problemi.
+
+È importante supportare le idee dei colleghi, anche quando avresti fatto le cose in modo diverso. Questo tipo di atteggiamento collaborativo aiuta a creare fiducia e favorisce una cultura dell’innovazione e del lavoro di squadra. Inoltre, la prossima volta che proporrai qualcosa, sono sicuro che le persone saranno disposte a discutere e a sostenere le tue idee.
+
+Quando si tratta di affrontare compiti difficili, non avere paura di offrirti come volontario. Che ne dici di affrontare quel _refactoring_ di cui nessuno vuole occuparsi? Fatti avanti! Quelle parti di codice complicate e incasinate che tutti evitano? Tuffati e cerca di dargli un senso! Assumendo questi compiti impegnativi, potrai farti una reputazione di risolutore di problemi e diventare la persona di riferimento per i lavori più difficili.
+
+Infine, come regola generale, cerca di migliorare un po’ le cose ogni volta che ne hai la possibilità. Che si tratti di documentare un processo, migliorare l’interfaccia utente di un’applicazione o snellire un flusso di lavoro, o persino correggere un errore di battitura in un file di documentazione. Ogni piccolo miglioramento è importante. Con il tempo, questi piccoli successi si accumulano e ci aiutano a diventare membri più validi del team.
+
+## Come faccio a vendermi come sviluppatore senior?
+
+Se penso di essere uno sviluppatore senior, cosa posso fare per essere riconosciuto come tale?
+
+Innanzitutto, inizia ad assumerti maggiori responsabilità. Cerca opportunità per dirigere progetti o fare da tutor a ingegneri junior. Condividi le tue conoscenze e la tua esperienza con gli altri e fornisci loro una guida.
+
+In secondo luogo, cerca di avere un impatto al di là del tuo team o progetto attuale. Partecipa a iniziative inter-funzionali, contribuisci a progetti open-source o intervieni a eventi di settore. Questo tipo di attività può aiutarti ad affermarti come guida intellettuale nel tuo settore e a dimostrare la tua esperienza a un pubblico più ampio.
+
+In terzo luogo, concentrati sullo sviluppo delle tue soft skills. In qualità di ingegnere senior, dovrai comunicare efficacemente sia con interlocutori tecnici che meno tecnici, condurre riunioni e negoziare efficacemente. Pertanto, lavora per migliorare le capacità di comunicazione, di leadership e di risoluzione dei conflitti per diventare un membro completo e rispettato del tuo team.
+
+Un altro modo per dimostrare la tua competenza è condividere le tue conoscenze con gli altri. Scrivi post su blog tecnici, registra video didattici o intervieni a eventi interni ed esterni per mostrare la tua esperienza e dimostrare la tua volontà di aiutare gli altri a imparare.
+
+Infine, cerca il parere dei tuoi colleghi, dei mentori e dei manager. Chiedi critiche costruttive e sii aperto a suggerimenti per migliorare.
+
+La ricettività ai commenti consente di migliorare continuamente le tue competenze e di dimostrare il tuo impegno a crescere e ad apprendere come ingegnere senior.
+
+In conclusione, la definizione di ingegnere software senior è complessa e sfaccettata, ma in generale implica il possesso di una profonda competenza tecnica, un’ampia conoscenza del settore e una serie di competenze trasversali che consentono una comunicazione efficace, la leadership e la risoluzione dei problemi.
+
+Per diventare uno sviluppatore senior, è importante affinare continuamente le proprie competenze, concentrandosi non solo sulle abilità tecniche ma anche sulla comunicazione, sulla leadership e sugli aspetti di business.
+
+Ciò potrebbe comportare il pair programming, la creazione di contenuti, la partecipazione volontaria a progetti impegnativi e la ricerca di nuove opportunità di apprendimento.
+
+In definitiva, il percorso verso il grado di senior non è lineare e richiede dedizione, perseveranza e propensione alla crescita. Quindi, continua a spronarti per andare sempre più a fondo, per divertirti e trovare gioia nel tuo lavoro e per sforzarti sempre di avere un impatto positivo sul tuo team e sull’organizzazione.
+
+Ma se ti sei chiesto durante la lettura se stessi descrivendo il perfetto sviluppatore senior, lascia che ti dica solo che non mi aspetto che le persone siano in grado di soddisfare ogni singolo aspetto esposto in questo articolo. Ci saranno cose in cui potrai eccellere e altre in cui sarai appena sufficiente. Fa parte della natura umana e va bene così!
+
+Non possiamo eccellere in tutto, ma dobbiamo conoscere i nostri punti di forza e di debolezza, lavorare con il nostro team per amplificare i punti di forza e compensare le debolezze… e sforzarci di migliorare ogni giorno!
diff --git a/docs/it/sviluppo-mobile.md b/docs/it/sviluppo-mobile.md
new file mode 100644
index 00000000..b9541627
--- /dev/null
+++ b/docs/it/sviluppo-mobile.md
@@ -0,0 +1,173 @@
+---
+layout: default
+title: Sviluppo Mobile
+nav_order: 6
+---
+
+
+# Sviluppo Mobile
+{: .no_toc }
+
+- TOC
+{:toc}
+
+
+
+## Che cos'è lo sviluppo mobile?
+
+Per "sviluppo mobile" si intende un insieme di processi e attività che coinvolgono l'analisi, la progettazione, la realizzazione e il rilascio di una o più applicazioni la cui esecuzione avverrà su dispositivi tascabili come smartphone e tablet.
+
+## Le fasi dello sviluppo mobile
+
+Le fasi di analisi e di progettazione nello sviluppo mobile condividono molte caratteristiche con lo sviluppo del software classico. Sebbene sia un settore di nicchia, in questo particolare momento dello sviluppo è necessario tenere in considerazione alcuni aspetti di fondamentale importanza. Ad esempio l'usabilità differente dettata dalle dimensioni compatte di uno smartphone, o dalla potenziale assenza di connettività, passando dall'architettura e dalle prestazioni del dispositivo o dalla durata della batteria.
+
+La fase di realizzazione, come per qualsiasi tipologia di software, consiste nel tradurre il prodotto delle analisi e della progettazione in istruzioni da fornire al nostro dispositivo. Con il passare degli anni si sono consolidate due tipologie di approcci allo sviluppo: lo sviluppo nativo e lo sviluppo ibrido. Lo sviluppo nativo si è evoluto tecnologicamente nel tempo ma ha mantenuto concettualmente lo stesso significato, discorso diverso per l'approccio ibrido: nato con una particolare filosofia che ha cambiato significato grazie alla diffusione dei moderni framework di sviluppo cross-platform come React Native e Flutter.
+
+Il rilascio di un'applicazione è probabilmente l'unica fase che differisce rispetto al classico processo che avviene per altre tipologie di software. In questa fase il mobile developer deve costruire degli artefatti che nella maggior parte dei casi possono essere distribuiti ai propri utenti passando attraverso delle piattaforme che prendono il nome di Store. È possibile distribuire queste applicazioni senza passare dagli store attraverso il sideloading, ma questo penalizzerà la diffusione del prodotto e renderà il processo di installazione e di aggiornamento più complesso del normale. Allo stato dell'arte attuale, per ragioni di sicurezza, in alcune piattaforme Apple è persino vietato il sideloading di applicazioni non distribuite attraverso lo store principale, sebbene la comunità europea stia cercando in qualche modo di forzare la mano per sfavorire il monopolio di Apple.
+
+## Cenni Storici
+
+La nascita dello sviluppo mobile e della professione del mobile developer va fatta coincidere con la diffusione di dispositivi tascabili come smartphone e tablet, in origine definiti palmari.
+
+Secondo [Wikipedia](https://it.wikipedia.org/wiki/Computer_palmare), "Un computer palmare (detto anche palmare), spesso indicato in lingua inglese con la sigla PDA (Personal Digital Assistant), o con l'ormai desueto termine palmtop, è un computer di dimensioni contenute, tali da essere portato sul palmo di una mano (da cui il nome), dotato anche di un touch screen."
+
+Questi computer sono nati principalmente con l'obiettivo di avere con sé agende, calendari, rubriche e calcolatrici dalle dimensioni contenute che potessero essere facilmente riposte in tasca o in un piccolo contenitore più facilmente trasportabile rispetto ad un laptop.
+
+Le aziende pioniere di questo settore sono state Palm, Texas Instruments e Microsoft: sebbene i primi palmari altro non erano che calcolatrici arricchite di funzionalità come rubrica e calendario, con il passare degli anni questi strumenti hanno iniziato ad evolvere e, di pari passo con il diffondersi a macchia d'olio di Internet e della microminiaturizzazione, a convergere verso un unico dispositivo ad oggi noto come smartphone.
+
+I primi palmari ad essere di fatto degli smartphone sono stati i Pocket PC di Microsoft. L'azienda di Redmond realizzò una piattaforma denominata Windows CE (Windows Embedded Compact) installabile su tutta una serie di dispositivi tascabili. Su questa piattaforma Microsoft ha continuato a realizzare versioni parallele dei suoi principali sistemi operativi Microsoft Windows compatibili con processori ARM, MIPS o SH3.
+
+L'abbandono del concetto di palmare e la convergenza verso gli smartphone si è avuta con la diffusione delle connessioni a Internet sui telefoni cellulari e con l'introduzione di sempre più strumenti accessori come il GPS, la radio FM, la fotocamera, e tutta la sensoristica di base di cui sono dotati gli ormai moderni smartphone.
+
+A dominare la prima generazione di smartphone è stata Nokia con SymbianOS. La multinazionale finlandese ha letteralmente conquistato le tasche della popolazione mondiale grazie al suo sistema operativo in grado di far girare le prime applicazioni realizzate in JavaME (Java MicroEdition). Sebbene inizialmente lo sviluppo di applicazioni per palmare e smartphone era un'attività riservata a chi era stato fisicamente assunto presso l'azienda madre, con la diffusione di Java, chiunque poteva studiare l'SDK della Sun per realizzare le proprie applicazioni.
+
+La generazione successiva di smartphone ha visto contendersi il mercato da aziende come Apple con l'introduzione dell'iPhone, uno dei primissimi smartphone privi di tastiera fisica e dotato esclusivamente di touchscreen; BlackBerry con il suo BlackBerry OS, Microsoft con Windows Phone, Nokia con SymbianOS e Google con Android. Di queste realtà, ad oggi fra i principali player si annoverano solo Apple con iOS/iPadOS e Google con Android: molte delle aziende precedentemente menzionate non sono state in grado di innovarsi e tenere il passo nella scena mobile.
+
+In questi anni, alcune realtà come Samsung prima e Huawei poi hanno tentato in qualche modo di eliminare il duopolio di Apple e Google, senza successo. Ad oggi, sviluppare su mobile significa sostanzialmente realizzare applicazioni per iPhone e iPad compatibili con il sistema operativo iOS sul fronte Apple, e per smartphone e tablet che montano il sistema operativo di Google sul fronte Android.
+
+## Le Piattaforme Target
+
+Sviluppare per mobile ad oggi si traduce fondamentalmente nel costruire artefatti software che possano funzionare su smartphone e tablet basati su sistemi operativi Android e iOS/iPadOS.
+
+Per programmare applicazioni mobile, sia che si scelga di realizzarle con approccio nativo, sia che si scelga l'approccio ibrido, richiede necessariamente l'installazione di un Software Development Kit (SDK) preciso, che prendono il nome rispettivamente di Android SDK e iOS SDK. Questi SDK contengono tutta una serie di prodotti come compilatori, emulatori, e strumenti aggiuntivi utili a chi sviluppa su mobile. Sebbene ultimamente la tecnologia stia virando verso alcune particolari architetture basate su ISA ARM, ad oggi la maggior parte dei computer desktop adotta ancora processori basati su architettura x86 a 64 bit: si rende quindi necessario installare strumenti come emulatori e simulatori per velocizzare lo sviluppo installando il proprio software in fase di sviluppo all'interno di macchine virtuali che rispecchiano quanto più il comportamento di un dispositivo fisico.
+
+Per quanto un emulatore (altresì noto come simulatore nel mondo Apple) sia di fatto una macchina virtuale molto simile ad un dispositivo fisico, lo stesso non ci consentirà di testare tutte le funzioni realmente esistenti su un vero dispositivo: questo spesso si traduce nel dover acquistare un parco dispositivi fisico sufficientemente capiente per poter testare la maggior parte delle funzioni non riproducibili all'interno di un emulatore, funzionalità spesso legate al comparto sensoristica come bluetooth, accelerometri, GPS, fotocamera, sensori d'impronta digitale e via discorrendo.
+
+Se dal punto di vista degli SDK è necessario passare obbligatoriamente dai prodotti ufficiali Google e Apple, non vale la stessa regola per gli IDE. Sul fronte Android, l'IDE più diffuso è Android Studio, nato a partire da un altro prodotto Jetbrains di nome IntelliJ IDEA, mentre su iOS possiamo utilizzare il software proprietario Apple XCode. Come menzionato precedentemente, nessuno ci vieta di utilizzare altri IDE come Visual Studio Code o persino un banale blocco note per scrivere il nostro codice poiché il compilatore risiede nell'SDK e non è strettamente legato all'IDE scelto. Certo, dovremo rinunciare a qualche funzionalità extra offerta da un IDE di riferimento, ma questo non ci impedirà di essere produttivi scrivendo il codice all'interno di un editor con cui abbiamo familiarità.
+
+Che dire invece dei linguaggi di programmazione? Qui è fondamentale fare un distinguo in quanto gli stessi variano in funzione dell'approccio scelto: se nativo o ibrido. In questa sezione tratteremo esclusivamente l'approccio nativo.
+
+Agli albori dello sviluppo mobile su Android ed iOS, i principali linguaggi di programmazione a farne da padroni sono stati rispettivamente Java per Android ed Objective-C per iOS. Google tuttavia ha sempre sofferto l'idea di non poter avere il controllo sul proprio linguaggio di programmazione mobile così come faceva invece Apple con Objective-C, e a partire dal 2014 ha iniziato a lavorare su un approccio di sviluppo proprietario che ha poi visto la luce qualche anno dopo. Lato Apple invece, con la nascita di Kotlin divenuto poi il principale linguaggio di programmazione per lo sviluppo mobile nativo, si è scelto di abbandonare Objective-C in favore di Swift, un linguaggio di programmazione moderno e molto meno complesso rispetto al suo predecessore.
+
+Questi due linguaggi di programmazione hanno dominato e tutt'ora dominano la scena dello sviluppo mobile, sebbene negli ultimi anni abbiamo vissuto un vero cambio di paradigma passando dalla programmazione imperativa alla programmazione dichiarativa: se prima il layout delle interfacce era fortemente disaccoppiato rispetto al codice sorgente della nostra app, con il passaggio al metodo Declarative UI le due cose si sono fuse, dando alla luce a Jetpack compose su Android e a SwiftUI su iOS.
+
+## Modalità di sviluppo: Nativo vs Ibrido
+
+Agli albori dello sviluppo mobile, l'unico modo possibile per realizzare applicazioni per smartphone e tablet consisteva nello studiare il linguaggio di programmazione di riferimento per poter interagire con l'SDK messo a disposizione da Apple o Google per programmare le app. Con il consolidarsi dei due principali sistemi operativi Android ed iOS, chi scriveva codice per realizzare app mobile poteva fondamentalmente scegliere se verticalizzare le proprie competenze su uno dei due per diventare un Android Mobile Developer o un iOS Mobile Developer, o se studiarli entrambi, diventando di fatto un Mobile Developer a tutto tondo.
+
+Realizzare la stessa applicazione per due sistemi operativi diversi significava avere due codici sorgenti completamente diversi, utilizzare due design system differenti, affrontare bug e problematiche diverse in funzione della piattaforma di riferimento, e soprattutto imparare due linguaggi di programmazione con un paradigma molto diverso fra loro: Java per Android ed Objective-C per iOS.
+
+Con il diffondersi degli smartphone e di internet, e con la progressiva transizione al contenuto mobile-first, molti web developer hanno deciso di convertirsi al mobile. L'unico limite a questo punto restava il linguaggio di programmazione: la maggior parte dei web developer era poco avvezzo all'utilizzo di Java ed Objective-C, e questo ha contribuito a far nascere i framework di sviluppo ibridi di prima generazione.
+
+Lo sviluppo ibrido nasce per far fronte al problema di dover necessariamente conoscere linguaggi di programmazione ed SDK di riferimento per ogni piattaforma mobile esistente: dato che la maggiorparte delle prime applicazioni non presenti sugli store girava sui browser degli smartphone, si è deciso di sfruttare javascript come linguaggio di programmazione per modellare dei framework che consentissero con un unico codice sorgente ed un unico design system, di realizzare applicazioni per entrambi i sistemi operativi di riferimento.
+
+Per farla breve, tutti i framework di sviluppo ibrido di prima generazione come Cordova, Phonegap e Ionic non facevano altro che renderizzare un sito web realizzato con il tris di tecnologie HTML, Javascript e CSS all'interno di una webview in un'app nativa. Sebbene questo consentisse di realizzare applicazioni più rapidamente e meno prone a bug o problematiche di vario genere, di contro ci si doveva scontrare con i limiti prestazionali dettati dalla tecnologia, dalle latenze di javascript, e soprattutto dall'assenza di fluidità d'esecuzione a causa dell'assenza di motori di rendering pensati per interagire nativamente con l'hardware del dispositivo.
+
+Questo ha spinto i progettisti a ripensare l'approccio allo sviluppo ibrido: invece di utilizzare delle webview per renderizzare dei siti web, si è deciso di utilizzare in linguaggio di programmazione di riferimento per comunicare con un motore di rendering che consentisse di disegnare le interfacce in modo completamente nativo sugli smartphone. I framework di seconda generazione come Xamarin, Flutter, MAUI e React Native fondamentalmente producono un artefatto la cui logica di business scritta con il linguaggio di programmazione target è stata tradotta in codice macchina.
+
+Qui la domanda potrebbe sorgere spontanea: ma quindi realizzare app con un framework di sviluppo ibrido di seconda generazione ci consente di fatto di sviluppare app native? La risposta in questo caso è sì. E verrebbe quindi naturale chiedersi che tipo di strategia adottare quando si ha la necessità di realizzare un'applicazione mobile, soprattutto se queste valutazioni devono tradursi in un percorso di carriera professionale.
+
+Sviluppare in nativo o sviluppare in ibrido, come tutte le cose, ha dei pro e dei contro, vediamo insieme vantaggi e svantaggi delle due soluzioni:
+
+| | **Sviluppo Nativo** | **Sviluppo Ibrido** |
+| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **Vantaggi** | **Prestazioni massime**: è pressoché impossibile battere le performance del codice nativo dato che lo stesso non passa attraverso un motore di rendering, le istruzioni vengono tradotte in codice macchina
**Miglior interazione**: come per il punto precedente, comunicare con la sensoristica o con gli accessori dello smartphone è pressoché immediato
**User experience proprietaria**: ogni piattaforma target ha ormai un design system di riferimento, è possibile quindi utilizzare le componenti standard per modellare le interfacce grafiche
**Applicazioni più leggere**: l'assenza di un framework si traduce in zero overhead in memoria o sullo storage | **Singola codebase**: come menzionato più volte precedentemente, questo aspetto ha un impatto sui tempi e sui costi di sviluppo e di manutenzione dell'intera codebase e dell'intero team
**Design system unico**: quando si ha la necessità di realizzare applicazioni fortemente tematiche o con una brand identity ben strutturata, avere un unico design system consente di comunicare le idee del prodotto in modo più efficace
**Prestazioni ottime**: a meno di realizzare prodotti molto di nicchia (realtà aumentata o videogames), l'uso dei motori di rendering consente di disegnare sullo schermo componenti con una reattività prossima al nativo e con una latenza del tutto impercettibile |
+| **Svantaggi** | **Codice sorgente duplicato**: se l'obiettivo è raggiungere entrambe le piattaforme, è necessario scrivere l'applicazione sia per Android che per iOS
**Bug e problematiche duplicate**: questa è una diretta conseguenza di avere un doppio codice sorgente; un errore di business è ridondante, un bug proveniente da un'implementazione strettamente legata al target di riferimento esisterà solo su quella determinata piattaforma
**Costi**: anche in questo caso il doppio codice sorgente si traduce in tempistiche, costi di sviluppo e manutenzione pressoché doppi | **Overhead del framework**: questo problema si traduce fondamentalmente in applicazioni leggermente più pesanti in memoria e sullo storage
**Interazione limitata**: spesso interagire con sensori o strumenti del dispositivo si traduce nell'introdurre canali di comunicazione, definendo ulteriori layer di scambio dati fra framework e codice nativo |
+
+Quando scegliere se realizzare un'applicazione in nativo o con un approccio ibrido? Nessuno conosce questa risposta in quanto la stessa dipende fondamentalmente dal tipo di prodotto che si vuole realizzare, dalle prestazioni che si intende ricercare, e soprattutto dai costi da affrontare. Ad oggi i framework di sviluppo ibridi di seconda generazione ci consentono di realizzare la maggior parte delle applicazioni mobile presenti sul mercato senza scomodare lo sviluppo nativo.
+
+## Modalità di rilascio
+
+A differenza dello sviluppo web dove l'applicativo viene eseguito all'interno di un browser, nello sviluppo mobile il prodotto finale deve essere installato sul dispositivo fisico, assumendo un comportamento simile a quello desktop.
+
+Come precedentemente accennato, per poter installare ufficialmente un'applicazione su uno smartphone è necessario passare per i canali ufficiali: i più diffusi sono rispettivamente il Google Play Store per il rilascio di applicazioni pensate per funzionare su telefoni e tablet basati su sistema operativo Android, e l'App Store per i dispositivi Apple. È possibile sfruttare il sideloading per poter installare un'app senza passare dagli store, ma questo richiede dei passaggi aggiuntivi che disabilitano alcuni controlli di sicurezza sui dispositivi Android, mentre su Apple è necessario utilizzare alcuni canali dedicati paralleli all'App Store, tipicamente adoperati in ambito business, oppure, scegliendo strade meno sicure come l'hacking con jailbreak.
+
+Queste sono le due principali piattaforme target che chi sviluppa su mobile può decidere di supportare sebbene in passato, in seguito ad una diatriba politica fra Stati Uniti e Cina, l'azienda Cinese Huawei abbia deciso di smettere di usufruire del ramo commerciale di Google creandosi una piattaforma per il rilascio di app ad-hoc che prende il nome di App Gallery. Ovviamente esistono anche altre minoranze sul mercato, ma sarebbe troppo complesso indicizzarle tutte.
+
+Per rilasciare applicazioni sulle due principali piattaforme target, è necessario registrarsi al Google Play Store come Google Play Developer, e all'Apple Developer Program. L'iscrizione alle due piattaforme ha un costo una tantum per quanto concerne Google e un canone fisso annuo per Apple, che consentono alla piattaforma di inserire una barriera d'accesso che privilegia la qualità alla quantità.
+
+A valle della registrazione, le applicazioni possono essere caricate sui rispettivi store e un team di professionisti procederà ad analizzare le nostre applicazioni e a valutare se le stesse sono conformi ai termini e condizioni che abbiamo siglato in fase di registrazione. A differenza di altre piattaforme, storicamente rilasciare applicazioni mobile è più difficile, complesso e temporalmente più lento, in quanto le app devono precedentemente superare un controllo di qualità da parte degli addetti agli store non del tutto automatizzabile e automatizzato.
+
+Quando compiliamo un artefatto per Android, abbiamo la possibilità di scegliere due formati di destinazione: apk e aab. Storicamente il formato apk è stato il primo file in grado di consentire l'installazione di un'app su Android. Formalmente altro non è che un archivio compresso che contiene alcuni descrittori dell'app, noti come Manifest file, e un ulteriore archivio con la logica dell'applicazione con estensione di tipo dex, acronimo di Dalvik Executable Format, in onore della prima macchina virtuale Android progettata da Dan Bornstein in Google.
+
+Con il passare degli anni, il diffondersi di smartphone e tablet, e il passaggio attraverso diverse architetture di processori, Google ha deciso di battezzare un nuovo archivio file pensato appositamente per il rilascio delle app sul Google Play Store e che prende il nome di Bundle AAB (Android App Bundle). Questo formato di file consente di memorizzare solo le informazioni strettamente necessarie al funzionamento dell'app, privando l'artefatto degli ABI (Application Binary Interface) e rendendolo molto più compatto. Fondamentalmente in Google si sono accorti che gli apk, con il passare del tempo, stavano crescendo di dimensione poiché gli stessi includevano tutti gli ABI esistenti. Si è scelto quindi di rivoluzionare il comportamento del Google Play Store, che compila apk multipli in funzione degli ABI direttamente sul Google Play Store: in questo modo Google Play Store stessa può fornirci degli apk in funzione dell'ABI del nostro smartphone. L'ABI rappresenta una particolare specifica progettuale definita per consentire il funziomanento di un programma su macchine di marche diverse purchè accomunate da un tipo particolare di hardware o di sistema operativo.
+
+Lato iOS, il principale output file ottenibile a valle di una compilazione di un'app ha come estensione IPA che sta per iOS App Package (l'acronimo risponde anche alla definizione iPhone Application prima che Apple rivoluzionasse la lineup dei nomi dei propri sistemi operativi mobile). Come per l'APK, questo file contiene alcuni descrittori del prodotto, questa volta in formato .plist, un formato molto conosciuto nel mondo Apple, e la logica dell'applicazione in formato .app, oltre ad una serie di file aggiuntivi come le icone.
+
+## Il ruolo di chi sviluppa su mobile
+
+Chi sviluppa su mobile è fondamentalmente un full-stack developer le cui competenze sono modellate in modalità Pi-shaped. Sebbene lo sviluppo mobile si possa concretizzare di fatto in una branca del frontend, la necessità di interagire con strumenti molto più a basso livello come i sensori o il dover scrivere logica di business che spesso elabora dati e li memorizza su basi di dati o su storage ospitati localmente al dispositivo, rende questa figura professionale uno specialista del backend. Quale miglior figura condivide sia le competenze backend che quelle frontend se non un full-stack developer? La specializzazione orizzontale del Pi-Shaped invece si concretizzano nel possedere conoscenze minime di UI e UX quando si tratta di disegnare e progettare interfacce grafiche, e di CI/CD quando è necessario compilare e rilasciare gli artefatti sui principali store.
+
+Il percorso di formazione e specializzazione di chi sviluppa su mobile è molto complesso e richiede più competenze trasversali:
+
+- Padronanza dei linguaggi di programmazione: fondamentalmente chi sviluppa mobile deve conoscere più linguaggi di programmazione sebbene lo stesso decida di seguire la strada della programmazione ibrida. Conoscere Kotlin o Swift quando programmiamo con React Native o Flutter ci consente di scrivere moduli nativi quando abbiamo la necessità di interfacciarci con l'hardware di smartphone e tablet
+- Conoscenza del sistema target: per costruire applicazioni accattivanti e funzionali, è necessario conoscere i behavior pattern del sistema operativo di riferimento. Disporre le componenti grafiche in un certo modo all'interno dell'applicazione o sfruttare determinati flussi dettati dalle tecnologie proprietarie del dispositivo consente agli utenti delle nostre app di sentirsi a casa propria quando usano i nostri prodotti.
+- Competenze di ingegneria del software: utilizzare i giusti pattern architetturali, scegliere i design pattern corretti, e scrivere gli algoritmi per la logica di business nel modo giusto consente di realizzare applicazioni robuste, performanti e facilmente estendibili.
+- Conoscenze di basi di dati e storage: spesso e volentieri si renderà necessario memorizzare i dati all'interno di una base di dati o sul file system del dispositivo. Sapere come progettare un database, ottimizare l'indicizzazione dei dati ed eseguire query ottimizzate può avere un forte impatto sulle performance e sull'estendibilità della nostra applicazione
+- Competenze di rete: chi sviluppa su mobile deve essere in grado di costruire client in grado di scambiare i dati con un server remoto in sicurezza e soprattutto deve poter modulare le modalità di presentazione dei dati in funzione della presenza/assenza di connessione
+- Competenze da DevOps: integrare strumenti di test all'interno di un processo di continuous integration finalizzato al rilascio dell'applicazione sui principali store è fondamentale per chi sviluppa su mobile
+- Padronanza di UI/UX: saper riconoscere interfacce ben progettate e ben bilanciate sono ottime skill di contorno che qualunque mobile developer dovrebbe possedere
+
+Sebbene non sia necessario verticalizzarsi su ognuna di queste competenze, è importante avere almeno un'infarinatura di base delle skill che possono poi essere interpretate da altri stakeholders all'interno del proprio team di sviluppo. Una formazione impostata su conoscenze Pi-Shaped in ambito mobile non può che portar giovamento nell'interazione con gli altri attori quali backend engineers, UI/UX designers, DevOps, eccetera.
+
+## Ingegneria del software per lo sviluppo mobile
+
+Secondo [Wikipedia](https://it.wikipedia.org/wiki/Ingegneria_del_software), l' ingegneria del software è quella disciplina informatica che si occupa dei processi produttivi e delle metodologie di sviluppo finalizzate alla realizzazione di sistemi software. Si propone una serie di obiettivi legati all'evoluzione dello sviluppo del software (inteso come attività industriale) sia da un punto di vista tecnologico (per es. attraverso la definizione di nuovi linguaggi di programmazione) che metodologico (per esempio il perfezionamento dei modelli di ciclo di vita del software).
+
+Lo sviluppo mobile prevede di fatto la realizzazione di prodotti software, ed è per questo motivo che sarebbe buona prassi applicare i principi dell'ingegneria del software anche in questo ambito. Ogni linguaggio di programmazione, e quindi ogni SDK, predilige un subset di design pattern e pattern architetturali da utilizzare durante la realizzazione di applicazioni mobile. Elencarli tutti, soprattutto spiegando dettagliatamente il funzionamento e il comportamento di ogni singolo componente, non rientra fra gli obiettivi di questo capitolo. Ci limiteremo a fornire un'infarinatura generale sui principali componenti da utilizzare quando si sceglie di realizzare applicazioni per mobile.
+
+I pattern architetturali più utilizzati sono:
+
+- [Model-View-Controller](https://it.wikipedia.org/wiki/Model-view-controller): Il componente centrale del MVC, il modello, cattura il comportamento dell'applicazione in termini di dominio del problema, indipendentemente dall'interfaccia utente (view). Il modello gestisce direttamente i dati, la logica e le regole dell'applicazione. Una vista può essere una qualsiasi rappresentazione in output di informazioni, come un grafico o un diagramma. Sono possibili viste multiple delle stesse informazioni, come ad esempio un grafico a barre per la gestione e la vista tabellare per l'amministrazione. La terza parte, il controller, accetta l'input e lo converte in comandi per il modello e/o la vista.
+- [Model-View-Viewmodel](https://it.wikipedia.org/wiki/Model-view-viewmodel): Questo pattern propone un ruolo più attivo della View rispetto a MVC: la View è in grado di reagire agli eventi, eseguire operazioni ed effettuare il binding con i dati. In questo contesto, alcune delle funzionalità del Controller vengono integrate nella View, che si basa su un'estensione del Model: il ViewModel. Il ViewModel è un Model esteso con funzionalità per la manipolazione dei dati e per l'interazione con la View
+- Model-View-Presenter: Questo modello rappresenta un’evoluzione dell’MVC e si concentra sulla separazione tra la presentazione dei dati e la logica di business. La differenza principale tra MVC e MVP è la posizione della logica di presentazione. Nell’MVC, il Controller è responsabile della logica di presentazione, mentre nell’MVP è il Presenter ad essere dedicato a questo compito.
+- Model-View-Intent (Android): L'architettura MVI è un pattern architetturale particolarmente utilizzato per la progettazione di interfacce utente in applicazioni basate su framework reattivi. Il modello rappresenta lo stato immutabile dell'applicazione, la view si occupa di visualizzare lo stato dell'applicazione e reagire agli input, e l'intent rappresenta le azioni o gli eventi che possono influenzare lo stato dell'applicazione. Il flusso di dati in MVI è unidirezionale: gli Intent vengono emessi dalla vista, elaborati dal modello per aggiornare lo stato e la vista viene quindi aggiornata per riflettere il nuovo stato.
+- View-Interactor-Presenter (iOS): Introdotto come un'alternativa al popolare pattern MVC per migliorare la separazione delle responsabilità e rendere il codice più testabile e manutenibile. La View è passiva e si occupa solo di visualizzare i dati e trasmettere gli input dell'utente al Presenter, l'Interactor contiene la logica di business dell'applicazione. Gestisce il recupero e la manipolazione dei dati, rispondendo alle richieste provenienti dal Presenter. L'Interactor può comunicare con il Modello (se presente) per ottenere o aggiornare i dati. Il Presenter Si occupa di presentare i dati dalla logica di business (Interactor) alla Vista. Il Presenter riceve gli input dall'utente attraverso la View, comunica con l'Interactor per ottenere i dati necessari, e infine aggiorna la View con le informazioni pertinenti. Il pattern VIP può includere un quarto componente, il model, più semplice e privo di logica di business. Il flusso di dati nel VIP pattern è principalmente unidirezionale.
+- View-Interactor-Presenter-Entity-Router (iOS): È un'evoluzione del pattern VIP, ed introduce due nuovi elementi, l'Entity e il Router. L'Entity rappresenta gli oggetti di dominio dell'applicazione e può contenere la logica di business e sono trasferite tra l'Interactor e il Repository/DataManager. Il Router gestisce la navigazione tra le schermate dell'applicazione e può essere utilizzato per avviare nuovi moduli VIPER e per gestire la navigazione tra essi. Il pattern VIPER cerca di risolvere alcuni dei problemi di separazione di responsabilità che potrebbero sorgere in altre architetture. La chiara separazione delle componenti facilita la comprensione del codice, rende più semplice l'aggiunta di nuove funzionalità e favorisce la testabilità delle singole unità.
+
+I design pattern più utilizzati sono:
+
+- Repository: Incapsula la logica di accesso ai dati, fornendo un'interfaccia comune per recuperare o salvare dati da diverse fonti.
+- Builder: Separa la creazione di un oggetto complesso dalla sua rappresentazione, consentendo la creazione di diverse rappresentazioni dell'oggetto con lo stesso processo di realizzazione.
+- Observer: Definisce una dipendenza uno a molti tra oggetti in modo che quando uno degli oggetti cambia stato, tutti i componenti sottoscritti vengano notificati e aggiornati automaticamente.
+- Dependency Injection: Fornisce un modo per fornire le dipendenze di un oggetto da parte di un'altra parte esterna, spesso attraverso l'iniezione di dipendenze tramite costruttore o metodi.
+- Factory: Definisce un'interfaccia per la creazione di un oggetto, ma lascia la scelta della sua classe di implementazione alle sottoclassi, ritardandone l'inizializzazione a runtime.
+- Adapter: Converte l'interfaccia di una classe in un'altra interfaccia che un client si aspetta di utilizzare, consentendo a classi incompatibili di lavorare insieme.
+- Singleton: Assicura che una classe abbia una sola istanza e fornisce un punto di accesso globale a questa istanza.
+- Facade: Fornisce un'interfaccia unificata a un insieme di interfacce in un sottosistema, semplificando così l'uso e la comprensione di quel sottosistema.
+- Decorator: Aggiunge dinamicamente nuove responsabilità a un oggetto fornendo una serie di oggetti che racchiudono l'oggetto originale.
+- Composite: Consente di trattare oggetti individuali e composizioni di oggetti in modo uniforme, permettendo la creazione di strutture gerarchiche.
+- Command: Incapsula una richiesta come un oggetto, consentendo di parametrizzare le richieste e rendendo le operazioni annullabili.
+- Strategy: Definisce una famiglia di algoritmi, incapsula ciascuno di essi e li rende intercambiabili. Consente all'algoritmo di variare indipendentemente dai clienti che lo utilizzano.
+- State: Permette a un oggetto di modificare il suo comportamento quando il suo stato interno cambia. L'oggetto sembra mutare la sua classe.
+- Delegate: Permette di delegare alcune funzionalità ad un altro oggetto. Questo pattern è particolarmente utile e necessario quando l'oggetto che invoca un’azione è disaccoppiato dall’oggetto che ne implementa il funzionamento.
+
+Anche i framework di sviluppo ibrido hanno la possibilità di interfacciarsi con pattern architetturali e design pattern di vario genere. La maggior parte dei framework ibridi di seconda generazione si basano su pattern che ruotano attorno alla definizione di stato. Ad esempio, su React Native i pattern di state management più utilizzati sono rispettivamente Redux, Hooks e MobX, mentre su Flutter troviamo BLoC, ChangeNotifier e Riverpod.
+
+## Design system per mobile
+
+Un design system è una raccolta di componenti riutilizzabili e standard ben definiti che possono essere utilizzati per costruire graficamente applicazioni. Questi sistemi sono utilizzati nel design e nello sviluppo di prodotti digitali come applicazioni mobile o siti web e possono comprendere librerie di pattern/componenti, linguaggi di design, guide dello stile (carattere, colore, spaziatura, posizionamento), componenti codificati, componenti di brand identity e documentazione.
+
+Essi fungono da punto di riferimento insieme a un linguaggio di design che assicura che i vari team coinvolti nella progettazione e realizzazione di un prodotto creino applicazioni coerenti nell'aspetto e nel comportamento. Fra i principali vantaggi nello scegliere di utilizzare un design system abbiamo un flusso di lavoro più efficiente dalla progettazione alla produzione, la creazione di un linguaggio unificato tra i team interfunzionali, progettazioni più veloci grazie a componenti riutilizzabili, user experience coerente e un linguaggio di design fisso e ben definito. Inoltre, favoriscono una manutenzione ed estendibilità migliore, riducendo il debito di progettazione e tecnico, e offrono un focus più forte per i team di prodotto, consentendo ai team di concentrarsi sulla risoluzione dei bisogni degli utenti.
+
+Un design system è composto da vari elementi, modelli, stili e linee guida che contribuiscono a semplificare ed ottimizzare la fase di progettazione. I fattori critici da considerare nella creazione di un design system hanno a che fare con l'ambito e la capacità di riprodurre i progetti, nonché la disponibilità di risorse e tempo. Se i design system non vengono implementati e mantenuti correttamente, possono diventare disorganizzati, compromettendo l'efficienza del processo di progettazione. Tuttavia, se implementati correttamente, possono semplificare il lavoro, rendere i prodotti finali più coesi e sostenere i progettisti durante le sfide complesse legate all'esperienza utente.
+
+È importante sempre tenere a mente che ci sono differenze sostanziali fra design system, linguaggi di pattern e UI kit. Un linguaggio di pattern consente ai suoi modelli di esistere in molte forme e configurazioni diverse; ad esempio, un modulo di accesso con campi per nome utente e password, e pulsanti per accedere, registrarsi e recuperare la password persa è un modello, indipendentemente dal fatto che i pulsanti siano verdi o viola. I modelli sono chiamati tali proprio perché la loro natura esatta può variare, ma le somiglianze consentono al rapporto tra di essi di rimanere invariato. D'altra parte, un design system ha sempre un insieme di linee guida visive che definiscono colori e tipografia ben precisi. La maggior parte dei design system consente agli elementi di un linguaggio di design di essere configurati in base alle esigenze. Uno UI kit è semplicemente un insieme di componenti dell'interfaccia utente, senza regole esplicite fornite per il suo utilizzo.
+
+I principali linguaggi di design proprietari che possiamo utilizzare su mobile sono rispettivamente Material Design e Human Interface Guidelines, sebbene per quest'ultimo sarebbe più corretto identificarlo come UI kit che come linguaggio di design.
+
+Material Design è un linguaggio di design sviluppato da Google nel 2014. Esso utilizza layout basati su griglie, animazioni e transizioni responsive, padding, ed effetti grafici come luci e ombre. Il principale obiettivo di Material Design è la definizione di un nuovo linguaggio visivo che combina principi di buon design con novità tecniche e scientifiche. La filosofia dietro al Material Design ha a che fare con componenti semplici disegnate con penna su carta e trasformati poi in elementi digitali. Con il passare degli anni, il Material Design si è evoluto dando alla luce prima il Material Design 2, e successivamente il Material Design 3 altresì noto come Material You.
+
+Spostandoci sullo sviluppo mobile per iOS, non abbiamo un vero e proprio design system nonostante Apple abbia ben documentato il proprio processo di definizione delle interfacce grafiche, bensì uno UI kit composto da un insieme di componenti di sistema che ci consentono di disegnare interfacce grafiche interattive e vicine alla filosofia delle applicazioni di sistema di iOS/iPadOS. Fra queste componenti possiamo trovare label, input testuali, bottoni, checkbox e radio button, switch, selettori, liste, card, etc.
+
+Quando si sceglie un design system per realizzare un prodotto mobile non è necessario sceglierne uno proprietario fra quelli menzionati precedentemente. È possibile lasciarsi ispirare da un design system ben definito e rimodellarne lo UI kit, così come è possibile costruirne uno completamente da zero o utilizzare altri modelli più diffusi come il Flat Design. In questo caso l'unico limite è la fantasia.
diff --git a/docs/it/testing.md b/docs/it/testing.md
new file mode 100644
index 00000000..3d9b29c2
--- /dev/null
+++ b/docs/it/testing.md
@@ -0,0 +1,211 @@
+---
+layout: default
+title: Testing
+nav_order: 4
+---
+
+
+# Testing
+{: .no_toc }
+
+- TOC
+{:toc}
+
+
+
+Il testing è una parte fondamentale di ogni progetto software. In questo capitolo vedremo come testare il nostro codice in modo efficace.
+
+## Piramide del testing
+
+Esistono diversi tipi di test, ognuno con un suo scopo ben preciso.
+
+Si fa spesso riferimento alla piramide del testing, che rappresenta la proporzione tra di essi:
+![Piramide del testing](/book/assets/images/piramide.svg)
+
+Nel resto del capitolo li vedremo nel dettaglio.
+
+### Unit test
+
+Il test unitario è un processo di sviluppo software in cui le parti testabili più piccole di un'applicazione, denominate unità, vengono esaminate individualmente per verificarne il corretto funzionamento. Chi sviluppa, o chi si occupa del controllo qualità del software, completa i test unitari durante il processo di sviluppo. Per unità solitamente si intende una funzione o una piccola serie di funzioni i cui comportamenti sono strettamente legati.
+
+Il punto principale è la presenza di un contesto isolato con un obiettivo.
+
+L'unità che ci si appresta a testare non dovrebbe avere _dipendenze_, ossia richiamare codice di altre unità. Quando ciò accade, il codice richiamato (la dipendenza) dovrebbe essere _messa sotto mock_, cioè essere sostituito, nel contesto dello unit test, da una funzione che ne fa le veci. Questa funzione, denominata appunto **mock**, ci permette di simulare tutti i comportamenti che potrebbe avere la dipendenza senza dipendere direttamente da essa.
+
+Parliamo anche del concetto di _coverage_: Solitamente gli unit test permettono di raggiungere alti livelli di code coverage proprio per via della loro granularità. Per Coverage si intende infatti la percentuale di righe di codice testate sul totale.
+
+Solitamente i problemi rilevabili negli unit test sono più facili da correggere perché riguardano piccole porzioni di codice e molti test sono riutilizzabili anche in altri progetti se si usa codice condiviso.
+
+D'altro canto, se i test sono scritti male o non forniscono una buona coverage, danno falsa sicurezza e non prevengono i bug, e il (tanto) tempo impiegato a scriverli risulta inutile.
+
+### Integration test
+
+Il test di integrazione è una tecnica di test del software che ha come obiettivo quello di testare più componenti o moduli di un sistema software insieme. Ha lo scopo di verificare che i diversi componenti, quando combinati, funzionino correttamente e producano i risultati attesi.
+
+Concetti principali:
+
+- **Scope**: Anche qui parliamo di contesto e obiettivi specifici.
+- **Stubs**: Sostituti di moduli e dipendenze necessari al funzionamento dei test.
+- **Spettro più ampio**: A differenza dello unit test che verifica un modulo / una funzione / un contesto specifico e ridotto, l’integration testing integra più moduli e ne testa le interdipendenze e la comunicazione.
+
+Tipologie di test:
+
+- **Big-bang**: Si creano decine, centinaia, migliaia di test in base alla dimensione della codebase. Si testa tutto, tutto assieme. Solitamente il tutto viene fatto in un singolo integration test, o in pochissimi. Funziona per codebase ridotte.
+- **Top-down testing**: Approccio incrementale, si parte dai moduli ad altissimo livello (Controller nel caso di un MVC) e si scende al livello più basso (Se si utilizzano i fat model si arriva anche fino a lì). Funziona per codebase grosse, iniziare è più complesso ma ha più impatto, pian piano diventa sempre più facile perché i livelli superiori sono già stati testati.
+- **Bottom-up testing**: Approccio incrementale al contrario. Si parte da sotto e si va in alto. Anche qui parliamo di grosse codebase, iniziare è più facile ma ha meno impatto, proseguendo anche qui diventa sempre più facile perché l’impalcatura sotto funziona.
+- **Sandwich** o **Hybrid Testing**: Combinazione dei due approcci sopra basati su un planning di priorità.
+
+Quando si lavora in team, più o meno grandi, non sempre ci si può assicurare che quanto sviluppato da una parte del team comunichi correttamente con quanto sviluppato da un’altra parte del team: gli Integration test sono fondamentali in questi contesti. Inoltre, se è facile individuare e correggere il comportamento di una specifica funzione (tramite unit test o tramite semplice attenzione quando si sviluppa), più difficile è notare eventuali differenze nel modo in cui i componenti di un’applicazione interagiscono tra di loro. I test di integrazione sono OTTIMI per garantire questa sicurezza.
+Infine, l’integrazione tra componenti non è solo da intendersi come "corretta comunicazione e scambio di informazioni tra le parti" ma anche "corretta gestione degli errori". In definitiva, se due o più componenti funzionano assieme e i test sono stati scritti correttamente, abbiamo quasi l'assoluta certezza del loro funzionamento combinato.
+
+D'altro canto è complesso realizzare dei test di integrazione e mantenerli nel tempo per via dell’evoluzione naturale del software su cui si lavora.
+
+Rispetto agli unit test, infatti, è più complicato trovare gli errori essendo più ad ampio spettro.
+
+Molto complesso individuare tutte le integrazioni che ha senso testare. La coverage al 100% è infatti inverosimile in progetti grossi.
+Spesso realizzare questi test è più complesso perché bisogna prima avere idea della codebase sottostante, a prescindere che si lavori in TDD (Test Driven Development - vedi paragrafo successivo) o meno.
+
+### End-to-end test
+
+Il test end-to-end (E2E) è una metodologia di test del software che si concentra sul test dell'intero sistema software dall'inizio alla fine, simulando scenari del mondo reale e interazioni dell'utente. Ha lo scopo di garantire che il sistema funzioni correttamente nel suo insieme e soddisfi i requisiti aziendali desiderati. A differenza degli altri tipi di test, fin ora trattati, qui il test interagisce con l'applicativo **solo** attraverso le interfacce più esterne (Browser o Api).
+
+E qui sta il punto. I requisiti sono essenzialmente aziendali e non tecnici.
+
+Nei test E2E, l'intera applicazione o sistema viene testato in un modo che imiti il modo in cui verrebbe utilizzato dagli utenti finali. Implica la simulazione delle interazioni dell'utente, l'inserimento dei dati e la convalida degli output previsti su più componenti, moduli e livelli del sistema.
+
+Anche qui parliamo di contesto e obiettivi, ma chiaramente non sono più “specifici” di per sé perché, ad esempio, testare “specificatamente” un flusso di pagamento coinvolge centinaia di parti. Inoltre, vista la complessità rilevata nel realizzare questi test, solitamente si usano strumenti che perlomeno automatizzino alcune parti del processo, come un live recording via estensione del browser.
+
+A differenza degli altri tipi di test, qui possiamo verificare se l’esigenza non funzionale, e quindi di business, sia rispecchiata nel comportamento della piattaforma.
+
+Infine, a differenza degli altri tipi di test trattati, qui vediamo all’atto pratico come i dati agiscono a 360 gradi.
+
+Ricreando scenari realistici, abbiamo modo di avere una sicurezza “definitiva” (tra molte virgolette) del comportamento della piattaforma.
+
+D'altro canto, è difficile prevedere e analizzare quante farne e cosa testare. Inoltre il test è più lungo da scrivere perché mentre per un integration test basta cambiare un flag per ottenere un flusso diverso, un test e2e deve probabilmente essere riscritto perché ha flussi differenti per giungere alla stessa conclusione.
+
+## Tipologie di test
+
+Esistono diverse tipologie di test, ognuna con un suo scopo ben preciso. Vediamole brevemente:
+
+- **Functional testing**: Il test funzionale è un tipo di test in cui il target sono le specifiche funzionali. Il sistema viene infatti testato rispetto ai requisiti funzionali, garantendo che questi siano adeguatamente soddisfatti dall'applicazione.
+- **Performance testing**: Il test di performance è un tipo di test in cui il target è la performance del sistema. Il sistema viene infatti testato rispetto ai requisiti di performance, garantendo che questi siano adeguatamente soddisfatti dall'applicazione.
+- **Usability testing**: Il test di usabilità è un tipo di test in cui il target è l'usabilità del sistema. Il sistema viene infatti testato rispetto ai requisiti di usabilità, garantendo che questi siano adeguatamente soddisfatti dall'applicazione.
+- **Security testing**: Il test di sicurezza è un tipo di test in cui il target è la sicurezza del sistema. Il sistema viene infatti testato rispetto ai requisiti di sicurezza, garantendo che questi siano adeguatamente soddisfatti dall'applicazione.
+- **Regression testing**: Il test di regressione è un tipo di test in cui il target è la regressione del sistema. Il sistema viene infatti testato rispetto ai requisiti di regressione, garantendo che questi siano adeguatamente soddisfatti dall'applicazione.
+
+Esistono molte altre tipologie di test, come _compatibility testing_, _acceptance testing_, _exploratory testing_, _golden testing_, _contract testing_, ma queste sono le più comuni.
+
+## Tecniche di test
+
+Esistono tre tecniche di test, ognuna con un suo scopo ben preciso. Vediamole brevemente:
+
+- **Black-box testing**: Il test _black-box_ è una tecnica di test in cui il tester non ha conoscenza dell'implementazione del sistema. Il focus è sull'esaminazione del funzionamento dell'applicazione (quindi senza conoscere il codice sorgente) rispetto ai requisiti specificati. Il tester verifica se l'applicazione si comporta come previsto. Questo metodo è applicabile a quasi tutti i tipi di software e sistemi, indipendentemente dai linguaggi o dalla tecnologia utilizzata.
+- **White-box testing**: Il test _white-box_ è una tecnica di test in cui il tester ha conoscenza dell'implementazione del sistema, quindi dell'intero codice sorgente. Questo approccio si concentra sull'esaminare il comportamento interno del software e sul garantire che tutte le vie logiche ed i segmenti di codice siano testati. Il test ha un focus sulla validazione dei percorsi di esecuzione all'interno del codice, assicurando che tutte le condizioni, i cicli ed i percorsi di codice siano testati. Questo metodo è efficace nell'individuare bug specifici nel codice, come errori di logica, infinity loop e istruzioni non raggiunte.
+- **Grey-box testing**: Il test _grey-box_ è una tecnica di test in cui il tester ha conoscenza parziale dell'implementazione del sistema. Questo tipo di testing è particolarmente utile quando si desidera testare il software da una prospettiva esterna, ma con una comprensione sufficiente della sua architettura interna per creare test più mirati ed efficaci. I tester hanno accesso limitato al codice sorgente e alla struttura interna, permettendo loro di comprendere alcuni aspetti dell'architettura del software senza una conoscenza dettagliata. Il _grey-box_ testing si concentra sulle interfaccie e le API del sistema, testando la comunicazione e l'interazione tra diverse unità o moduli. Il vantaggio principale riguarda la maggiore efficienza, data la combinazione di conoscenze interne ed esterne, permettendo di creare test più mirati, aumentando l'efficienza del processo di testing.
+
+Di solito queste tre tecniche vengono utilizzate per individuare eventuali falle nel sistema. Solitamente il _Black-box testing_ è la tecnica più utilizzata, in quanto permette di individuare falle che non sono state individuate durante lo sviluppo e non richiede una conoscenza pregressa del sistema.
+
+## Metodologie di testing
+
+### Manual testing
+
+Il manual testing è una metodologia in cui i test vengono eseguiti manualmente dalla figura del tester. Questo approccio ha diversi svantaggi e solitamente viene utilizzato solo per testare le funzionalità più critiche del sistema quando non è possibile automatizzare i test. Questa metodologia viene chiamata anche _explorative testing_, tramite la quale si prova a rompere l'applicazione creando scenari difficilmente automatizzabili e scrivendo di conseguenza i test.
+
+### Automated testing
+
+L'automated testing è una metodologia in cui i test vengono eseguiti automaticamente da un software. Questo approccio ha diversi vantaggi: **Ripetibilità**, **Riduzione dei costi**, **Riduzione dei tempi di sviluppo**.
+
+### Continuous testing
+
+Il continuous testing è una metodologia in cui i test vengono eseguiti automaticamente ad ogni commit o ad ogni modifica del codice sorgente.
+
+Solitamente viene utilizzato in congiunzione con il concetto di _continuous integration_, ovvero una metodologia di sviluppo software in cui i membri di un team integrano il proprio lavoro frequentemente, generalmente ogni giorno o più volte al giorno. Ogni integrazione viene verificata da un'automazione di build (compilazione) che permette di individuare errori di integrazione il prima possibile.
+
+### Test-driven development
+
+Il test-driven development (TDD) è una metodologia di sviluppo software che prevede di scrivere i test prima di scrivere il codice.
+La parola "test" nell'acronimo è spesso mal interpretata. Il TDD non è uno strumento per testare l'applicazione, ma per far emergere il design dell'applicativo partendo dagli obiettivi, sottoforma di test, che vogliamo soddisfare. Questo ci permette di rispettare il principio YAGNI (_You aren't gonna need it_), ovvero non scrivere codice per esigenze future, ma solo per soddisfare l'implementazione dei test da soddisfare.
+
+Il TDD inizia con la scrittura dei test prima di scrivere il codice effettivo. Il ciclo TDD - Spesso chiamato _red-green-refactor_ - è semplice ma potente:
+
+1. Scrivi un Test: Inizia scrivendo un test che descriva il comportamento che desideri implementare. Questo test inizierà sicuramente come un test fallito, poiché il codice non esiste ancora.
+
+2. Scrivi il Codice Minimale: Scrivi il codice minimo necessario per far passare il test. In questa fase, non preoccuparti troppo della qualità del codice; l'obiettivo è far passare il test.
+
+3. Rifattorizza il Codice: Ora che il test è passato, puoi iniziare a migliorare la qualità del tuo codice. Rimuovi duplicazioni, migliora la leggibilità e assicurati che il codice sia pulito e ben strutturato.
+
+Un altro vantaggio del TDD è che si sta automaticamente creando una documentazione tecnica. Guardando la descrizione dei test, è facile comprendere come debba comportarsi l'applicazione.
+
+Non c'è rosa senza spine! Il TDD non è una pratica facile da padroneggiare. Un ottimo modo per iniziare, è l'esercitazione attraverso esercizi mirati, chiamati _kata_, spesso usati in sede di colloquio.
+
+**Ping Pong TDD**
+
+Tendenzialmente quando si fa Test Driven Development si è da soli davanti al proprio programma da completare e davanti alla propria tastiera. Esiste però una pratica che porta più persone a fare Test Driven Development insieme che prende il nome di _Ping Pong TDD_.
+Questo è un metodo molto coinvolgente di applicare il TDD.
+
+Come accennato, è un pre-requisito del metodo essere almeno in due.
+
+Le regole di questo _gioco_ si basano sull'alternarsi alla tastiera quando si scrive un test. Il primo "turno" è diverso da tutti i successivi: chi si trova per primo alla tastiera scrive un test che fallisce, poi passa la tastiera al suo pair. Da questo e per tutti i turni successivi, quando una persona inizia il proprio turno deve:
+
+- Far diventare verdi i test scrivendo il codice di produzione adatto.
+- Scrivere un test rosso.
+
+Una volta che il test rosso viene scritto, il turno sarà finito e la tastiera tornerà a chi ha iniziato la sessione di ping pong. In pratica ad ogni turno l'obiettivo è far passare i test e successivamente crearne di nuovi fino al completamento del software.
+
+### Behavior-driven development
+
+Il behavior-driven development (BDD) è una metodologia che permette di esplicitare i requisiti funzionali, tramite test. Questo permette una maggior comprensione degli sviluppi, creando un dialogo tra Product Team e Dev Team, con i test come lingua comune.
+
+Questo tipo di test viene scritto con un linguaggio chiamato _gherkins_, composto da Feature e vari scenari. Ogni scenario è composto da:
+
+1. Given: una fase di creazione delle pre-condizioni.
+2. When: un'azione sotto test.
+3. Then: una condizione da verificare.
+
+Di seguito un esempio che descrive una semplice ricerca su Google:
+
+```
+Feature: Google Searching
+ As a web surfer, I want to search Google, so that I can learn new things.
+
+ Scenario: Simple Google search
+ Given a web browser is on the Google page
+ When the search phrase "panda" is entered
+ Then results for "panda" are shown
+```
+
+## Test Coverage
+
+La test coverage è una metrica che indica la percentuale di codice sorgente che viene eseguita (_coperta_) durante l'esecuzione dei test. Questa metrica è molto importante, in quanto permette di capire quanto il codice sorgente è stato testato. Solitamente si cerca di raggiungere una test coverage del 100%, ma questo non è sempre possibile, oltre che non necessario. Una test coverage del 100% non garantisce che il codice sorgente sia privo di bug, esattamente come non lo garantisce una coverage del 50%. Come in moltissimi altri aspetti della programmazione, la parola _dipende_ assume un significato molto importante.
+
+**La test coverage ci dice quanto del nostro codice si comporta come ci aspettiamo, ma non è detto che ciò che ci aspettiamo sia corretto.**
+
+### Over-testing
+
+Altra nota importante è relativa alla _coverage 100%_: solitamente si sconsiglia l'adozione di una coverage così alta in quanto si rischia di incorrere in un fenomeno chiamato _over-testing_, nel quale si testano tutte le possibili casistiche, anche quelle che non hanno senso e che impiegano molto tempo ad essere scritte. Questo fenomeno è molto pericoloso, in quanto si rischia di scrivere codice per il mero raggiungimento di un numero, la coverage appunto, che non aggiunge valore al prodotto e che non soddisfa alcun requisito funzionale o non funzionale.
+
+## Tools e Frameworks per il Testing
+
+Ora che abbiamo esplorato i vari tipi di test e le loro applicazioni, è di fondamentale importanza conoscere gli strumenti e i framework che possono rendere questi processi più efficienti ed efficaci. Ogni tipologia di test può essere supportata e migliorata dall'uso di tool specifici, che aiutano l'automazione dei test stessi, rendendo più semplice la scrittura del codice di test e fornendo feedback più dettagliati sui risultati.
+
+Quelle che seguono sono delle liste non esaustive di strumenti che solitamente vengono presi ad esempio quando si parla di una specifica modalità di testing. Ogni linguaggio ha, nella maggior parte dei casi, più di uno strumento per ogni modalità e il suggerimento, come per tutto ciò che riguarda il mondo dello sviluppo, è quello di sperimentare con ognuno di essi e di prendere delle decisioni informate riguardo a quali utilizzare.
+
+### Strumenti per Unit-Test
+
+- **JUnit**: è un framework di test unitari utilizzato in ambito Java. Ampiamente utilizzato per testare singole classi e metodi con annotazioni intuitive.
+
+- **pytest**: Come deducibile dal nome, pytest è un framework utilizzato in ambiente Python, molto versatile che rende semplice scriver test unitari complessi. Offre funzionalità come la parametrizzazione dei test e i fixtures per configurare il contesto di test.
+
+### Strumenti per Integration Test
+
+- **Postman**: Utilizzato principalmente per testare API. Permette di creare richieste HTTP, impostare vari ambienti di test e verificare le risposte delle API. Molto utile anche in un contesto di embedding.
+
+- **TestNG(Java)**: Fornisce funzionalità avanzate per i test d'integrazione. Inclusa l'esecuzione parallela dei test e la gestione delle dipendenze.
+
+### Strumenti per End-to-End Test
+
+- **Selenium**: È un framework utilizzato per automatizzare i browser web. E' ideale per testare interazioni utente complesse in web app.
+
+- **Cypress**: Una soluzione più moderna per il testing E2E, apprezzata per la sua NON complessità d'uso e l'integrazione con ambienti di sviluppo Javascript.
+
+- **Playwright**: Un altro framework moderno che consente di automatizzare il browser e di eseguire test E2E. Punta molto sulle performance e sull'affidabilità di esecuzione delle azioni sugli elementi in pagina.
diff --git a/docs/it/introduzione.md b/index.md
similarity index 96%
rename from docs/it/introduzione.md
rename to index.md
index 9b6dbfb7..10930a63 100644
--- a/docs/it/introduzione.md
+++ b/index.md
@@ -1,3 +1,19 @@
+---
+layout: default
+title: Introduzione
+nav_order: 1
+permalink: /
+---
+
+
+# Il Libro Open Source
+{: .no_toc }
+
+- TOC
+{:toc}
+
+
+
## Benvenuto
Chiunque tu sia, da qualunque posto tu provenga, benvenuto in un viaggio incredibile nel mondo dello sviluppo software.