<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dev-Iadicola</title>
    <description>The latest articles on DEV Community by Dev-Iadicola (@dev_iadicola).</description>
    <link>https://dev.to/dev_iadicola</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2138925%2F6dd30c44-71a1-4568-a668-759ac9486600.png</url>
      <title>DEV Community: Dev-Iadicola</title>
      <link>https://dev.to/dev_iadicola</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dev_iadicola"/>
    <language>en</language>
    <item>
      <title>Domain-Driven Design: modellare il software attorno al business</title>
      <dc:creator>Dev-Iadicola</dc:creator>
      <pubDate>Mon, 20 Jul 2026 17:00:27 +0000</pubDate>
      <link>https://dev.to/dev_iadicola/domain-driven-design-modellare-il-software-attorno-al-business-4eho</link>
      <guid>https://dev.to/dev_iadicola/domain-driven-design-modellare-il-software-attorno-al-business-4eho</guid>
      <description>&lt;h2&gt;
  
  
  Il problema: software che non parla la lingua del business
&lt;/h2&gt;

&lt;p&gt;Un gestionale per un'azienda di logistica ha una classe &lt;code&gt;Item&lt;/code&gt; che viene usata per i prodotti in magazzino, per le righe degli ordini, per i pacchi in spedizione e per le voci di fatturazione. Quattro concetti diversi, una sola classe. Quando il team di magazzino parla di "item", intende un prodotto fisico con peso e dimensioni. Quando il team di fatturazione parla di "item", intende una voce con prezzo e tasse. Il codice non distingue i due significati e questo genera bug, fraintendimenti e complessità accidentale.&lt;/p&gt;

&lt;p&gt;Il &lt;strong&gt;Domain-Driven Design&lt;/strong&gt; (DDD), proposto da Eric Evans nel 2003, affronta questo problema alla radice: il software deve modellare il dominio di business usando il &lt;strong&gt;linguaggio&lt;/strong&gt; del business. Non il linguaggio dei programmatori — il linguaggio degli esperti di dominio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ubiquitous Language: parlare la stessa lingua
&lt;/h2&gt;

&lt;p&gt;Il primo principio del DDD e l'&lt;strong&gt;Ubiquitous Language&lt;/strong&gt;: un vocabolario condiviso tra sviluppatori e esperti di dominio, usato nel codice, nelle conversazioni e nella documentazione. Se l'esperto di magazzino dice "picking list", il codice ha una classe &lt;code&gt;PickingList&lt;/code&gt;. Se l'esperto di fatturazione dice "nota di credito", il codice ha una classe &lt;code&gt;NotaDiCredito&lt;/code&gt;. Non &lt;code&gt;CreditNoteEntity&lt;/code&gt; o &lt;code&gt;InvoiceItemDTO&lt;/code&gt; — il nome nel codice e il nome nel dominio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bounded Context: confini di significato
&lt;/h2&gt;

&lt;p&gt;Un &lt;strong&gt;Bounded Context&lt;/strong&gt; e un confine entro il quale un termine ha un significato preciso. "Item" nel contesto Magazzino e un prodotto fisico. "Item" nel contesto Fatturazione e una voce economica. Sono due classi diverse in due contesti diversi, non una classe condivisa con flag e condizioni.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Contesto Magazzino&lt;/strong&gt;: &lt;code&gt;Product&lt;/code&gt; con peso, dimensioni, posizione scaffale, quantità&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contesto Ordini&lt;/strong&gt;: &lt;code&gt;OrderLine&lt;/code&gt; con prodotto riferito per ID, quantità ordinata, prezzo al momento dell'ordine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contesto Fatturazione&lt;/strong&gt;: &lt;code&gt;InvoiceLine&lt;/code&gt; con descrizione, importo, aliquota IVA&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contesto Spedizione&lt;/strong&gt;: &lt;code&gt;Parcel&lt;/code&gt; con peso totale, dimensioni, indirizzo destinatario&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ogni contesto ha il proprio modello, ottimizzato per le proprie esigenze. I contesti comunicano tramite interfacce esplicite o eventi, non condividendo classi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building blocks tattici
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Entity
&lt;/h3&gt;

&lt;p&gt;Un oggetto con &lt;strong&gt;identita&lt;/strong&gt;: due ordini con gli stessi prodotti sono comunque ordini diversi perché hanno ID diversi. L'identita persiste attraverso i cambiamenti di stato.&lt;/p&gt;

&lt;h3&gt;
  
  
  Value Object
&lt;/h3&gt;

&lt;p&gt;Un oggetto senza identita, definito solo dai suoi &lt;strong&gt;valori&lt;/strong&gt;: &lt;code&gt;Money(100, 'EUR')&lt;/code&gt; e uguale a un altro &lt;code&gt;Money(100, 'EUR')&lt;/code&gt;. I Value Object sono immutabili. &lt;code&gt;Email&lt;/code&gt;, &lt;code&gt;Address&lt;/code&gt;, &lt;code&gt;DateRange&lt;/code&gt; sono Value Object classici. In PHP si implementano come classi &lt;code&gt;readonly&lt;/code&gt; con validazione nel costruttore.&lt;/p&gt;

&lt;h3&gt;
  
  
  Aggregate
&lt;/h3&gt;

&lt;p&gt;Un cluster di Entity e Value Object con un &lt;strong&gt;Aggregate Root&lt;/strong&gt; come unico punto di accesso. &lt;code&gt;Order&lt;/code&gt; (root) contiene &lt;code&gt;OrderLine&lt;/code&gt; (entity interna). Non accedi mai a un &lt;code&gt;OrderLine&lt;/code&gt; senza passare dall'&lt;code&gt;Order&lt;/code&gt;. L'Aggregate garantisce la consistenza interna: le regole di business (es. "il totale non può essere negativo") sono verificate dall'Aggregate Root.&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain Event
&lt;/h3&gt;

&lt;p&gt;Un fatto accaduto nel dominio: &lt;code&gt;OrderPlaced&lt;/code&gt;, &lt;code&gt;PaymentReceived&lt;/code&gt;. Gli eventi permettono ai Bounded Context di comunicare senza accoppiamento diretto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Repository
&lt;/h3&gt;

&lt;p&gt;L'interfaccia per persistere e recuperare Aggregate. Definita nel dominio, implementata nell'infrastruttura. Un Aggregate = un Repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  DDD in PHP: e praticabile?
&lt;/h2&gt;

&lt;p&gt;Si, con alcune accortezze. PHP 8.1+ con readonly properties, enum e named arguments rende i Value Object naturali. Le interfacce per i Repository e il Dependency Injection sono supportati nativamente. I Domain Event si implementano con un semplice dispatcher. Il costo principale e culturale: il team deve investire tempo nell'analisi del dominio con gli esperti di business.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quando usare DDD
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Usa DDD&lt;/strong&gt; quando il dominio e complesso e le regole di business sono il cuore del valore dell'applicazione&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa DDD&lt;/strong&gt; quando ci sono esperti di dominio disponibili per collaborare con il team tecnico&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa DDD&lt;/strong&gt; quando il linguaggio del business e confuso e serve una modellazione esplicita&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non usare DDD&lt;/strong&gt; per CRUD senza logica di business significativa: il costo di modellazione non si ripaga&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non usare DDD&lt;/strong&gt; se non hai accesso agli esperti di dominio: DDD senza domain expert e un esercizio accademico&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DDD non e un'architettura: e un approccio alla modellazione. Si combina con qualsiasi architettura — MVC, Hexagonal, Clean, CQRS. Il suo valore non e nelle classi o nelle interfacce, ma nel modo di &lt;strong&gt;pensare&lt;/strong&gt; al software: partendo dal dominio, non dalla tecnologia.&lt;/p&gt;




&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://iadicola.it/articoli/domain-driven-design-modellare-software-attorno-al-business?utm_source=devto&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Leggi l'articolo completo su iadicola.it&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>domaindriven</category>
      <category>ddd</category>
      <category>boundedcontext</category>
    </item>
    <item>
      <title>Hexagonal Architecture: il dominio al centro, il framework ai margini</title>
      <dc:creator>Dev-Iadicola</dc:creator>
      <pubDate>Fri, 17 Jul 2026 17:00:13 +0000</pubDate>
      <link>https://dev.to/dev_iadicola/hexagonal-architecture-il-dominio-al-centro-il-framework-ai-margini-1i4n</link>
      <guid>https://dev.to/dev_iadicola/hexagonal-architecture-il-dominio-al-centro-il-framework-ai-margini-1i4n</guid>
      <description>&lt;h2&gt;
  
  
  Il problema: il framework che diventa il padrone
&lt;/h2&gt;

&lt;p&gt;In un'applicazione Laravel tipica, la business logic dipende da Eloquent, da Facade, da Request, da Mail. Se Laravel cambia un'API interna, il tuo dominio si rompe. Se vuoi testare la logica senza database, non puoi — e tutto accoppiato. Se un giorno devi migrare a Symfony (succede), devi riscrivere tutto. Il framework dovrebbe essere un &lt;strong&gt;dettaglio implementativo&lt;/strong&gt;, non il fondamento su cui il dominio si regge.&lt;/p&gt;

&lt;p&gt;L'&lt;strong&gt;Architettura Esagonale&lt;/strong&gt;, proposta da Alistair Cockburn nel 2005, inverte questa dipendenza: il dominio e al centro, autosufficiente. Il framework, il database, le API esterne sono alla periferia, collegati tramite &lt;strong&gt;Ports&lt;/strong&gt; (interfacce) e &lt;strong&gt;Adapters&lt;/strong&gt; (implementazioni).&lt;/p&gt;

&lt;h2&gt;
  
  
  Ports and Adapters: la struttura
&lt;/h2&gt;

&lt;p&gt;L'esagono (la forma e metaforica, non geometrica) ha tre zone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core (Domain)&lt;/strong&gt;: al centro. Contiene entita, value objects, regole di business, interfacce dei repository. Non importa nulla dal framework. Zero dipendenze esterne.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ports&lt;/strong&gt;: interfacce che definiscono come il dominio comunica con l'esterno. &lt;strong&gt;Driving ports&lt;/strong&gt; (primari): come il mondo esterno usa il dominio (es. &lt;code&gt;OrderServiceInterface&lt;/code&gt;). &lt;strong&gt;Driven ports&lt;/strong&gt; (secondari): come il dominio usa il mondo esterno (es. &lt;code&gt;OrderRepositoryInterface&lt;/code&gt;, &lt;code&gt;PaymentGatewayInterface&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adapters&lt;/strong&gt;: implementazioni concrete dei ports. Un adapter HTTP traduce una request in una chiamata al driving port. Un adapter PostgreSQL implementa il driven port del repository. Un adapter Stripe implementa il driven port del gateway di pagamento.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Esempio teorico: un sistema di pagamenti
&lt;/h2&gt;

&lt;p&gt;Il dominio definisce un'interfaccia &lt;code&gt;PaymentGatewayInterface&lt;/code&gt; con &lt;code&gt;charge(Money $amount, Card $card): PaymentResult&lt;/code&gt;. Il dominio non sa se il pagamento passa da Stripe, PayPal o Satispay. Sa solo che esiste un gateway che accetta un importo e una carta e restituisce un risultato.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;StripePaymentAdapter&lt;/code&gt; implementa l'interfaccia usando l'SDK di Stripe&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PayPalPaymentAdapter&lt;/code&gt; implementa la stessa interfaccia usando l'API PayPal&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FakePaymentAdapter&lt;/code&gt; implementa l'interfaccia per i test — approva sempre, senza rete&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cambiare gateway di pagamento richiede una sola modifica: quale adapter viene iniettato. Il dominio — con tutte le sue regole su limiti di importo, retry, idempotenza — non cambia di una riga.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hexagonal vs MVC: non si escludono
&lt;/h2&gt;

&lt;p&gt;MVC e Hexagonal non sono alternative: sono &lt;strong&gt;complementari&lt;/strong&gt;. MVC organizza il flusso HTTP (request → controller → view). Hexagonal organizza la struttura interna dell'applicazione (dominio → ports → adapters). Un'applicazione può usare MVC per il layer HTTP e Hexagonal per la struttura del dominio.&lt;/p&gt;

&lt;p&gt;In pratica: il Controller (MVC) e un &lt;strong&gt;adapter HTTP&lt;/strong&gt; (Hexagonal) che traduce la request in una chiamata a un &lt;strong&gt;driving port&lt;/strong&gt; (l'interfaccia del Service). Il Repository Eloquent e un &lt;strong&gt;adapter di persistenza&lt;/strong&gt; che implementa un &lt;strong&gt;driven port&lt;/strong&gt; (l'interfaccia del Repository definita nel dominio).&lt;/p&gt;

&lt;h2&gt;
  
  
  La regola della dipendenza
&lt;/h2&gt;

&lt;p&gt;La regola fondamentale dell'Hexagonal Architecture e la &lt;strong&gt;direzione delle dipendenze&lt;/strong&gt;: tutto punta verso il centro. Gli adapter dipendono dai ports. I ports dipendono dal dominio. Il dominio non dipende da nulla. Mai una &lt;code&gt;use Illuminate\...&lt;/code&gt; dentro una classe di dominio. Mai un &lt;code&gt;use Doctrine\...&lt;/code&gt; in un'entita.&lt;/p&gt;

&lt;p&gt;Questa regola sembra rigida ma produce un beneficio concreto: puoi testare l'intero dominio con mock dei ports — senza database, senza HTTP, senza servizi esterni. I test girano in millisecondi e testano la logica pura.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quando usare l'Hexagonal Architecture
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Usa Hexagonal&lt;/strong&gt; quando la business logic e complessa e deve sopravvivere al framework&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa Hexagonal&lt;/strong&gt; quando il progetto ha una vita lunga (anni) e il framework potrebbe cambiare&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa Hexagonal&lt;/strong&gt; quando la testabilita del dominio e una priorità&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non usare Hexagonal&lt;/strong&gt; per CRUD semplici: il layer di astrazione aggiuntivo non paga il costo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non usare Hexagonal&lt;/strong&gt; se il team non e pronto: la curva di apprendimento e reale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L'Hexagonal Architecture non e una moda: e una risposta strutturale al problema dell'accoppiamento con il framework. Quando il dominio e al centro e il framework e ai margini, il codice che conta — la business logic — e protetto, testabile e portabile.&lt;/p&gt;




&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://iadicola.it/articoli/hexagonal-architecture-dominio-al-centro-framework-ai-margini?utm_source=devto&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Leggi l'articolo completo su iadicola.it&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>hexagonal</category>
      <category>ports</category>
      <category>adapters</category>
    </item>
    <item>
      <title>Serverless PHP: quando ha senso e come funziona con Bref</title>
      <dc:creator>Dev-Iadicola</dc:creator>
      <pubDate>Thu, 16 Jul 2026 17:00:14 +0000</pubDate>
      <link>https://dev.to/dev_iadicola/serverless-php-quando-ha-senso-e-come-funziona-con-bref-1n3l</link>
      <guid>https://dev.to/dev_iadicola/serverless-php-quando-ha-senso-e-come-funziona-con-bref-1n3l</guid>
      <description>&lt;h2&gt;
  
  
  Serverless non significa "senza server"
&lt;/h2&gt;

&lt;p&gt;Il termine "serverless" e fuorviante: i server esistono, semplicemente non li gestisci tu. Il cloud provider (AWS, Google Cloud, Azure) si occupa di provisioning, scaling, patching e monitoring dell'infrastruttura. Tu deployi codice e paghi per esecuzione — niente VPS da mantenere, niente Apache da configurare, niente aggiornamenti di sicurezza del sistema operativo.&lt;/p&gt;

&lt;p&gt;Per anni, PHP e stato escluso dal mondo serverless dominato da Node.js e Python. &lt;strong&gt;Bref&lt;/strong&gt; ha cambiato le cose: e un runtime PHP open-source per AWS Lambda che permette di deployare applicazioni PHP — incluse applicazioni Laravel e Symfony — su infrastruttura serverless.&lt;/p&gt;

&lt;h2&gt;
  
  
  Come funziona Bref
&lt;/h2&gt;

&lt;p&gt;Bref fornisce &lt;strong&gt;Lambda layers&lt;/strong&gt; con il runtime PHP precompilato. Il tuo codice viene impacchettato e caricato su Lambda. Quando arriva una richiesta, Lambda avvia un'istanza del runtime, esegue il codice e restituisce il risultato. Se arrivano 1000 richieste simultanee, Lambda avvia 1000 istanze. Se non arrivano richieste per 15 minuti, le istanze vengono terminate. Paghi solo per il tempo di esecuzione effettivo.&lt;/p&gt;

&lt;p&gt;Bref offre tre modalita:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web function&lt;/strong&gt;: gestisce richieste HTTP tramite API Gateway. Adatta per applicazioni web complete.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event-driven function&lt;/strong&gt;: risponde a eventi (SQS, S3, EventBridge). Adatta per job, processing, integrations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Console function&lt;/strong&gt;: esegue comandi CLI (Artisan, Symfony Console). Adatta per cron job e task schedulati.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Vantaggi concreti
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Costo a consumo&lt;/strong&gt;: paghi per millisecondo di esecuzione. Un'applicazione con poco traffico costa centesimi al mese. Un VPS costa 5-20 EUR/mese anche se non riceve traffico.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scaling automatico&lt;/strong&gt;: da 0 a migliaia di istanze senza configurazione. Nessun capacity planning, nessun autoscaling group da configurare.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero manutenzione server&lt;/strong&gt;: niente aggiornamenti OS, niente patch di sicurezza, niente monitoring dell'infrastruttura.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy atomici&lt;/strong&gt;: ogni deploy e una nuova versione della funzione. Rollback istantaneo alla versione precedente.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  I limiti reali
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cold start&lt;/strong&gt;: la prima invocazione dopo un periodo di inattivita richiede 200-800ms per avviare il runtime PHP. Per applicazioni interattive con requisiti di latenza stretti, può essere un problema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tempo massimo di esecuzione&lt;/strong&gt;: Lambda ha un timeout di 15 minuti. Job di lunga durata non sono adatti.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filesystem effimero&lt;/strong&gt;: &lt;code&gt;/tmp&lt;/code&gt; ha 512MB-10GB ma viene cancellato tra le invocazioni. File upload e processing richiedono S3.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sessioni&lt;/strong&gt;: senza filesystem persistente, le sessioni PHP devono usare DynamoDB, Redis o un altro store esterno.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vendor lock-in&lt;/strong&gt;: il codice diventa dipendente da AWS. Migrare a un altro provider o a un VPS richiede lavoro.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Casi d'uso ideali per PHP serverless
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API con traffico variabile&lt;/strong&gt;: un'API che ha picchi durante il giorno e zero traffico di notte. Paghi solo quando viene usata.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhook e integrazioni&lt;/strong&gt;: endpoint che ricevono callback da servizi esterni (Stripe, GitHub, Mailgun). Traffico imprevedibile e sporadico.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Processing asincrono&lt;/strong&gt;: generazione PDF, resize immagini, invio email batch. Event-driven, senza server dedicato.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cron job&lt;/strong&gt;: task schedulati che girano per pochi secondi al giorno. Pagare un VPS 24/7 per 30 secondi di lavoro non ha senso.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quando NON usare serverless
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Applicazioni con traffico costante&lt;/strong&gt;: se il server e sempre occupato, un VPS dedicato costa meno di Lambda&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebSocket e connessioni persistenti&lt;/strong&gt;: Lambda non supporta connessioni long-lived&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Applicazioni con stato locale&lt;/strong&gt;: file system, cache in-memory, sessioni PHP native non funzionano&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team senza esperienza AWS&lt;/strong&gt;: la curva di apprendimento di IAM, API Gateway, CloudFormation e reale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Serverless PHP con Bref non e la soluzione universale, ma per i casi d'uso giusti — traffico variabile, processing asincrono, cron job — offre un rapporto costo/semplicità che nessun VPS può eguagliare. Il futuro di PHP non e solo Apache su un server: e anche funzioni che si avviano in millisecondi e si spengono quando non servono.&lt;/p&gt;




&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://iadicola.it/articoli/serverless-php-quando-ha-senso-come-funziona-bref?utm_source=devto&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Leggi l'articolo completo su iadicola.it&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>lambda</category>
      <category>bref</category>
    </item>
    <item>
      <title>CQRS: separare lettura e scrittura per scalare e semplificare</title>
      <dc:creator>Dev-Iadicola</dc:creator>
      <pubDate>Wed, 15 Jul 2026 17:00:13 +0000</pubDate>
      <link>https://dev.to/dev_iadicola/cqrs-separare-lettura-e-scrittura-per-scalare-e-semplificare-1di5</link>
      <guid>https://dev.to/dev_iadicola/cqrs-separare-lettura-e-scrittura-per-scalare-e-semplificare-1di5</guid>
      <description>&lt;h2&gt;
  
  
  Il problema: un modello che fa tutto
&lt;/h2&gt;

&lt;p&gt;In un e-commerce, il modello &lt;code&gt;Order&lt;/code&gt; serve sia per creare/modificare ordini (scrittura) sia per visualizzare la lista ordini, i report e le dashboard (lettura). Ma le esigenze sono opposte: la scrittura ha bisogno di validazione, regole di business e transazioni atomiche. La lettura ha bisogno di query ottimizzate, join complessi, aggregazioni e cache. Un singolo modello che fa entrambe le cose diventa un compromesso permanente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CQRS&lt;/strong&gt; (Command Query Responsibility Segregation) propone di separare i due percorsi: un modello per la scrittura (Commands) e un modello per la lettura (Queries). Ognuno ottimizzato per il proprio scopo, senza compromessi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Command e Query: le due meta
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Commands: modificare lo stato
&lt;/h3&gt;

&lt;p&gt;Un Command rappresenta un'intenzione di cambiare lo stato del sistema: &lt;code&gt;CreateOrderCommand&lt;/code&gt;, &lt;code&gt;CancelOrderCommand&lt;/code&gt;, &lt;code&gt;UpdateAddressCommand&lt;/code&gt;. Il Command contiene i dati necessari per l'operazione. Un &lt;strong&gt;Command Handler&lt;/strong&gt; riceve il Command, esegue la validazione di business, modifica lo stato e persiste. I Command non restituiscono dati (al massimo un ID o un acknowledge).&lt;/p&gt;

&lt;h3&gt;
  
  
  Queries: leggere lo stato
&lt;/h3&gt;

&lt;p&gt;Una Query rappresenta una richiesta di dati: &lt;code&gt;GetOrderDetailsQuery&lt;/code&gt;, &lt;code&gt;ListPendingOrdersQuery&lt;/code&gt;, &lt;code&gt;GetMonthlySalesReportQuery&lt;/code&gt;. Un &lt;strong&gt;Query Handler&lt;/strong&gt; riceve la Query e restituisce dati. Le Query non modificano mai lo stato — sono pure letture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Perché separare: vantaggi concreti
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ottimizzazione indipendente&lt;/strong&gt;: il modello di scrittura usa un ORM con validazione e regole. Il modello di lettura usa query SQL dirette, viste materializzate, cache aggressiva. Nessun compromesso.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalabilità asimmetrica&lt;/strong&gt;: la maggior parte delle applicazioni legge 10x più di quanto scrive. Con CQRS puoi scalare il read path (cache, repliche) senza toccare il write path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modelli dedicati&lt;/strong&gt;: il DTO di lettura per la dashboard ha campi diversi dall'entita di dominio. Con CQRS sono modelli separati, non proiezioni forzate dello stesso oggetto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testabilita&lt;/strong&gt;: Command Handler e Query Handler sono unita testabili indipendentemente.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  CQRS senza Event Sourcing
&lt;/h2&gt;

&lt;p&gt;Un malinteso comune e che CQRS richieda Event Sourcing. Non e così. CQRS e la separazione dei modelli di lettura e scrittura — può usare lo stesso database con tabelle diverse, o lo stesso database con query diverse. Event Sourcing e un pattern complementare ma opzionale che aggiunge la persistenza degli eventi come fonte di verità.&lt;/p&gt;

&lt;p&gt;La forma più semplice di CQRS in PHP: il Command Handler usa Eloquent per validare e salvare. Il Query Handler usa query SQL dirette o viste per leggere. Stesso database, due percorsi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Esempio pratico in PHP
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write side&lt;/strong&gt;: &lt;code&gt;CreateOrderHandler&lt;/code&gt; riceve un &lt;code&gt;CreateOrderCommand&lt;/code&gt;, valida il carrello, verifica il stock, calcola il totale, crea l'ordine tramite il Repository, dispara eventi&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read side&lt;/strong&gt;: &lt;code&gt;OrderDashboardQuery&lt;/code&gt; esegue una singola query SQL con join e aggregazioni che restituisce i dati esatti per la dashboard — nessun ORM, nessun N+1, nessun over-fetching&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quando usare CQRS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Usa CQRS&lt;/strong&gt; quando le esigenze di lettura e scrittura sono significativamente diverse&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa CQRS&lt;/strong&gt; quando la lettura e il collo di bottiglia e vuoi ottimizzarla indipendentemente&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa CQRS&lt;/strong&gt; quando i report e le dashboard richiedono strutture dati diverse dalle entita di dominio&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non usare CQRS&lt;/strong&gt; per CRUD semplici dove lettura e scrittura usano lo stesso modello senza problemi&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non usare CQRS&lt;/strong&gt; se il team non distingue chiaramente Command da Query: la separazione forzata diventa confusione&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CQRS non e un'architettura completa: e un principio di separazione. Applicato nei punti giusti — dove lettura e scrittura hanno requisiti diversi — semplifica entrambi i percorsi. Applicato ovunque per dogma, aggiunge complessità senza beneficio.&lt;/p&gt;




&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://iadicola.it/articoli/cqrs-separare-lettura-e-scrittura-per-scalare?utm_source=devto&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Leggi l'articolo completo su iadicola.it&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>cqrs</category>
      <category>commandquery</category>
      <category>readwrite</category>
    </item>
    <item>
      <title>Un gestionale di magazzino costruito attorno a chi lavora in magazzino</title>
      <dc:creator>Dev-Iadicola</dc:creator>
      <pubDate>Mon, 13 Jul 2026 17:00:23 +0000</pubDate>
      <link>https://dev.to/dev_iadicola/un-gestionale-di-magazzino-costruito-attorno-a-chi-lavora-in-magazzino-1f1k</link>
      <guid>https://dev.to/dev_iadicola/un-gestionale-di-magazzino-costruito-attorno-a-chi-lavora-in-magazzino-1f1k</guid>
      <description>&lt;p&gt;Un gestionale di magazzino costruito attorno a chi lavora in magazzino&lt;/p&gt;

&lt;p&gt;Ogni magazzino vive di una domanda continua: &lt;em&gt;cosa è entrato, cosa è uscito, e dove si trova adesso?&lt;/em&gt; Sembra semplice, ma chiunque ci abbia lavorato sa che la realtà è fatta di terminali condivisi, operatori che si alternano, merce che esce prima di essere registrata e inventari che non tornano mai. Ho progettato questo gestionale partendo proprio da quei problemi concreti, e quasi ogni decisione tecnica nasce da una frustrazione vera del lavoro quotidiano.&lt;/p&gt;

&lt;p&gt;Ne racconto qui le più interessanti — non perché siano complicate, ma perché ognuna risolve un problema che chi gestisce un magazzino riconosce al volo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Si entra col PIN, non con email e password
&lt;/h2&gt;

&lt;p&gt;In un magazzino il computer (o il tablet) è uno solo e lo usano in tanti, a turno. Chiedere a ogni operatore di fare &lt;em&gt;logout&lt;/em&gt; e poi &lt;em&gt;login&lt;/em&gt; con email e password ogni volta che si avvicina al terminale è una di quelle cose che, sulla carta, funziona — e nella pratica nessuno fa. Risultato classico: tutti lavorano con lo stesso utente e diventa impossibile sapere chi ha fatto cosa.&lt;/p&gt;

&lt;p&gt;La soluzione qui è diversa. Il terminale resta acceso e "loggato" praticamente sempre, per mesi. Ma ogni movimento richiede un &lt;strong&gt;PIN di 4 cifre&lt;/strong&gt; personale: l'operatore digita il suo codice, fa l'operazione, e quel movimento resta legato al suo nome per sempre. Il PIN "scade" dopo pochi minuti di inattività, così il sistema chiede di reinserirlo e non rischia mai di attribuire un'operazione alla persona sbagliata.&lt;/p&gt;

&lt;p&gt;È un doppio orologio pensato apposta: uno lento, che tiene il dispositivo pronto all'uso e non costringe a riloggarsi di continuo; uno veloce, che garantisce la &lt;strong&gt;tracciabilità&lt;/strong&gt; reale di ogni singolo gesto. Per chi entra e esce dal terminale venti volte al giorno cambia tutto.&lt;/p&gt;

&lt;h2&gt;
  
  
  L'app capisce da sola se è una vendita o un consumo interno
&lt;/h2&gt;

&lt;p&gt;Quando la merce esce dal magazzino, può uscire per due motivi molto diversi: o viene &lt;strong&gt;venduta a un cliente&lt;/strong&gt;, oppure viene &lt;strong&gt;consumata internamente&lt;/strong&gt; dalla produzione. Sono due cose che vanno registrate in modo diverso, e di solito si chiede all'operatore di scegliere ogni volta da un menù. Ogni scelta manuale è un'occasione per sbagliare.&lt;/p&gt;

&lt;p&gt;Qui l'app lo capisce da sola, in base a &lt;em&gt;chi&lt;/em&gt; sta lavorando. Un operatore "normale" scarica sempre verso un cliente; un operatore della produzione scarica sempre verso la produzione. Chi usa il sistema non deve decidere nulla: fa il suo lavoro e la classificazione corretta arriva automaticamente. Il supervisore, che ha una visione completa, è l'unico che può scegliere manualmente quando serve.&lt;/p&gt;

&lt;p&gt;Meno scelte da fare significa meno errori, e numeri di fine mese che tornano.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creare un articolo "al volo", senza bloccare la merce
&lt;/h2&gt;

&lt;p&gt;Capita spessissimo: arriva un bancale, l'operatore scansiona il codice a barre e… quell'articolo non esiste ancora a sistema. La reazione naturale sarebbe mettere tutto in pausa, chiamare il responsabile, far creare la scheda. Nel frattempo la merce resta lì e il lavoro si ferma.&lt;/p&gt;

&lt;p&gt;Con questo gestionale, se la funzione è attiva, l'operatore può &lt;strong&gt;creare l'articolo sul momento&lt;/strong&gt;, direttamente dalla schermata di carico, compilando un piccolo modulo veloce. L'articolo nasce subito ed è immediatamente disponibile per essere caricato. La merce entra, il lavoro non si ferma, e il supervisore potrà completare i dettagli con calma in un secondo momento.&lt;/p&gt;

&lt;h2&gt;
  
  
  L'inventario si conta "alla cieca"
&lt;/h2&gt;

&lt;p&gt;Il momento dell'inventario fisico è quello in cui i conti dovrebbero tornare — ed è proprio quello in cui si bara di più, spesso senza volerlo. Se l'operatore vede a schermo &lt;em&gt;"a sistema risultano 100 pezzi"&lt;/em&gt;, è umano che, contandone 98, finisca per scrivere 100 "tanto è quello giusto".&lt;/p&gt;

&lt;p&gt;Qui durante la conta l'operatore &lt;strong&gt;non vede mai la quantità attesa&lt;/strong&gt;: inserisce soltanto quello che conta davvero. Solo dopo, il supervisore confronta il conteggio con i dati di sistema, vede le differenze e decide cosa fare. Se approva, è il sistema stesso a generare in automatico le rettifiche necessarie per allineare le giacenze.&lt;/p&gt;

&lt;p&gt;È una conta più onesta, e una correzione tracciata: si sa sempre quale rettifica è nata da quale inventario.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le giacenze possono andare in negativo (e va bene così)
&lt;/h2&gt;

&lt;p&gt;Molti gestionali bloccano lo scarico se a sistema "non c'è abbastanza merce". Sembra prudente, ma nella realtà è il contrario: la merce magari è già uscita fisicamente e semplicemente non è ancora stata registrata. Bloccare l'operazione costringe le persone a "barare" pur di andare avanti, e il dato diventa ancora meno affidabile.&lt;/p&gt;

&lt;p&gt;Questo sistema permette alla giacenza di scendere sotto lo zero, perché preferisce &lt;strong&gt;registrare la verità&lt;/strong&gt; piuttosto che una finzione ordinata. Però, appena succede, fa scattare un &lt;strong&gt;avviso per il supervisore&lt;/strong&gt;. E gli avvisi sono intelligenti: non ripetono lo stesso allarme all'infinito, ma segnalano una sola volta finché la situazione non cambia davvero. Così le notifiche restano utili invece di diventare rumore da ignorare.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trovare un articolo in un istante
&lt;/h2&gt;

&lt;p&gt;Cercare un prodotto è l'azione più frequente in assoluto. Per questo la ricerca funziona sia per &lt;strong&gt;codice&lt;/strong&gt; (anche il codice a barre) sia per &lt;strong&gt;descrizione&lt;/strong&gt;, e restituisce subito la posizione in magazzino, la quantità disponibile e il fornitore. Niente filtri complicati: si scrive e si trova.&lt;/p&gt;

&lt;h2&gt;
  
  
  I permessi li decide il responsabile, non il programmatore
&lt;/h2&gt;

&lt;p&gt;Le regole di un magazzino cambiano nel tempo: oggi un certo ruolo può fare una cosa, domani no. Di solito modificare "chi può fare cosa" significa chiamare lo sviluppatore e aspettare un aggiornamento.&lt;/p&gt;

&lt;p&gt;Qui il supervisore ha a disposizione una &lt;strong&gt;tabella dei permessi&lt;/strong&gt; che può modificare da solo, con qualche clic: decide quali ruoli possono creare articoli, approvare inventari, gestire utenti e così via. Le regole si adattano all'organizzazione senza bisogno di toccare il codice.&lt;/p&gt;

&lt;p&gt;E ogni modifica importante — agli articoli, ai fornitori, ai PIN degli utenti — viene registrata in un &lt;strong&gt;diario delle attività&lt;/strong&gt;: chi, cosa, quando. Una rete di sicurezza per quando serve capire come si è arrivati a una certa situazione.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sotto il cofano, in breve
&lt;/h2&gt;

&lt;p&gt;Senza entrare nel tecnico: l'applicazione gira interamente nel browser, quindi funziona da computer, tablet o smartphone senza installare nulla, e la scansione dei codici a barre può usare sia un lettore fisico sia la fotocamera del telefono. È costruita con tecnologie web moderne e ampiamente collaudate, pensate per restare veloci e reattive anche con molti operatori che lavorano contemporaneamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  La filosofia, alla fine
&lt;/h2&gt;

&lt;p&gt;Il filo conduttore di tutte queste scelte è uno solo: &lt;strong&gt;la tecnologia deve adattarsi al modo in cui si lavora davvero in magazzino, non il contrario&lt;/strong&gt;. Niente passaggi inutili imposti all'operatore, niente dati "puliti" ma falsi, niente regole rigide che costringono a trovare scorciatoie. Un gestionale che riduce gli errori non perché controlla di più le persone, ma perché chiede loro di pensare di meno alle cose che la macchina può capire da sola.&lt;/p&gt;




&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://iadicola.it/articoli/gestionale-magazzino-costruito-attorno-a-chi-lavora-magazzino?utm_source=devto&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Leggi l'articolo completo su iadicola.it&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>excel</category>
      <category>php</category>
      <category>crm</category>
      <category>erp</category>
    </item>
    <item>
      <title>Mediator Pattern: comunicazione senza caos</title>
      <dc:creator>Dev-Iadicola</dc:creator>
      <pubDate>Sun, 12 Jul 2026 17:00:36 +0000</pubDate>
      <link>https://dev.to/dev_iadicola/mediator-pattern-comunicazione-senza-caos-5f4n</link>
      <guid>https://dev.to/dev_iadicola/mediator-pattern-comunicazione-senza-caos-5f4n</guid>
      <description>&lt;h2&gt;
  
  
  Il problema: tutti parlano con tutti
&lt;/h2&gt;

&lt;p&gt;Un form complesso ha 10 campi interdipendenti. Selezionare "tipo: azienda" mostra il campo P.IVA e nasconde il codice fiscale. Selezionare "paese: estero" disabilita il CAP e cambia il formato del telefono. Cambiare la provincia aggiorna la lista dei comuni. Ogni campo conosce gli altri e li manipola direttamente: &lt;code&gt;$tipoField-&amp;gt;onChange(function() use ($pivaField, $cfField) { ... })&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Con 10 campi che comunicano tra loro hai potenzialmente 90 connessioni dirette (N*(N-1)). Aggiungere l'undicesimo campo richiede di aggiornare tutti quelli che interagiscono con esso. Rimuoverne uno rompe tutti quelli che lo referenziano. E un groviglio che nessuno vuole toccare.&lt;/p&gt;

&lt;p&gt;Il &lt;strong&gt;Mediator Pattern&lt;/strong&gt; introduce un coordinatore centrale: i campi non comunicano tra loro, comunicano con il mediator. Il mediator conosce le regole di interazione e coordina le risposte. Ogni campo conosce solo il mediator, non gli altri campi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cos'e il Mediator Pattern: definizione formale
&lt;/h2&gt;

&lt;p&gt;Il Gang of Four definisce il Mediator come un pattern comportamentale che "definisce un oggetto che incapsula come un insieme di oggetti interagisce. Il Mediator promuove l'accoppiamento lasco impedendo agli oggetti di riferirsi esplicitamente l'un l'altro". La struttura prevede:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mediator&lt;/strong&gt;: l'interfaccia con un metodo &lt;code&gt;notify(sender, event)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ConcreteMediator&lt;/strong&gt;: implementa la logica di coordinamento tra i componenti&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Colleague&lt;/strong&gt;: ogni componente che comunica tramite il mediator. Conosce il mediator, non gli altri colleague.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Esempio teorico: una chat room
&lt;/h2&gt;

&lt;p&gt;Una chat room e l'esempio classico del Mediator. Ogni utente (&lt;code&gt;Colleague&lt;/code&gt;) invia messaggi alla room (&lt;code&gt;Mediator&lt;/code&gt;), non direttamente agli altri utenti. La room decide chi riceve il messaggio: tutti (broadcast), un gruppo (canale), o un singolo utente (messaggio privato).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ChatRoom::notify(User $sender, string $message, ?string $channel)&lt;/code&gt; riceve il messaggio&lt;/li&gt;
&lt;li&gt;Se il canale e specificato, inoltra solo ai membri del canale&lt;/li&gt;
&lt;li&gt;Se e un messaggio privato (@user), inoltra solo al destinatario&lt;/li&gt;
&lt;li&gt;Altrimenti, broadcast a tutti tranne il mittente&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aggiungere un utente alla room non richiede di modificare gli altri utenti. Aggiungere regole (moderazione, filtro spam, rate limiting) richiede di modificare solo il mediator. I colleague restano semplici.&lt;/p&gt;

&lt;h2&gt;
  
  
  Esempio teorico: orchestrazione di microservizi
&lt;/h2&gt;

&lt;p&gt;Un ordine e-commerce coinvolge: inventario, pagamento, spedizione, notifiche, fatturazione. Senza mediator, ogni servizio chiama gli altri direttamente — un groviglio di dipendenze. Con un &lt;code&gt;OrderOrchestrator&lt;/code&gt; (mediator), il flusso diventa lineare: il payment service notifica l'orchestrator "pagamento riuscito", l'orchestrator chiama l'inventario per riservare, poi la spedizione per preparare, poi la fatturazione per emettere, poi le notifiche per informare il cliente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mediator vs Observer
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Observer&lt;/strong&gt;: comunicazione one-to-many. Un subject notifica tutti gli observer. Gli observer non si conoscono ma il subject non coordina le loro risposte.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mediator&lt;/strong&gt;: comunicazione many-to-many coordinata. Il mediator riceve notifiche da qualsiasi colleague e decide come e chi coinvolgere nella risposta.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L'Observer e passivo: "e successo X, fate quello che volete". Il Mediator e attivo: "e successo X, quindi tu fai A, tu fai B, e tu aspetti". Se serve coordinamento tra le risposte, il Mediator e la scelta giusta.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quando usare il Mediator Pattern
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Usa il Mediator&lt;/strong&gt; quando molti oggetti comunicano tra loro in modi complessi e le dipendenze dirette sono un groviglio&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa il Mediator&lt;/strong&gt; quando vuoi centralizzare le regole di interazione in un unico punto modificabile&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa il Mediator&lt;/strong&gt; quando aggiungere o rimuovere un componente non deve richiedere modifiche agli altri&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non usare il Mediator&lt;/strong&gt; se i componenti hanno interazioni semplici e dirette: il mediator aggiunge un layer di indirezione non necessario&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attenzione&lt;/strong&gt;: il mediator può diventare un God Object se accumula troppa logica. Se cresce troppo, suddividilo in sotto-mediator specializzati.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il Mediator Pattern e il pattern del &lt;strong&gt;coordinamento centralizzato&lt;/strong&gt;: trasforma una rete di dipendenze N-a-N in una stella con il mediator al centro. La complessità non scompare — si sposta in un punto unico, visibile e manutenibile.&lt;/p&gt;




&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://iadicola.it/articoli/mediator-pattern-comunicazione-senza-caos?utm_source=devto&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Leggi l'articolo completo su iadicola.it&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>architettura</category>
      <category>mediator</category>
      <category>comportamentale</category>
      <category>coordinamento</category>
    </item>
    <item>
      <title>Memento Pattern: catturare e ripristinare lo stato</title>
      <dc:creator>Dev-Iadicola</dc:creator>
      <pubDate>Sat, 11 Jul 2026 17:00:35 +0000</pubDate>
      <link>https://dev.to/dev_iadicola/memento-pattern-catturare-e-ripristinare-lo-stato-5h7n</link>
      <guid>https://dev.to/dev_iadicola/memento-pattern-catturare-e-ripristinare-lo-stato-5h7n</guid>
      <description>&lt;h2&gt;
  
  
  Il problema: tornare indietro senza rompere l'incapsulamento
&lt;/h2&gt;

&lt;p&gt;Un editor di testo deve supportare l'undo. Per annullare un'operazione, serve lo stato precedente del documento. La soluzione ingenua e rendere pubbliche tutte le proprieta dell'editor per poterle salvare dall'esterno. Ma questo viola l'incapsulamento: il codice che gestisce l'undo conosce i dettagli interni dell'editor, e se la struttura interna cambia, il sistema di undo si rompe.&lt;/p&gt;

&lt;p&gt;Il &lt;strong&gt;Memento Pattern&lt;/strong&gt; risolve il dilemma: l'oggetto stesso crea uno snapshot del proprio stato (il memento) e lo fornisce all'esterno come oggetto opaco. Chi gestisce la history (il caretaker) conserva i memento senza poterne leggere il contenuto. Solo l'oggetto originale sa come ripristinare il proprio stato da un memento.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cos'e il Memento Pattern: definizione formale
&lt;/h2&gt;

&lt;p&gt;Il Gang of Four definisce il Memento come un pattern comportamentale che "senza violare l'incapsulamento, cattura e esternalizza lo stato interno di un oggetto in modo che l'oggetto possa essere ripristinato a questo stato in seguito". Tre attori:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Originator&lt;/strong&gt;: l'oggetto il cui stato deve essere salvato (es. l'editor). Ha metodi &lt;code&gt;createMemento()&lt;/code&gt; e &lt;code&gt;restore(Memento $m)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memento&lt;/strong&gt;: l'oggetto opaco che contiene lo snapshot dello stato. Espone il contenuto solo all'Originator.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caretaker&lt;/strong&gt;: gestisce la collection di memento (la history). Non accede mai al contenuto dei memento.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Esempio teorico: undo/redo in un editor grafico
&lt;/h2&gt;

&lt;p&gt;Un editor grafico ha un canvas con forme (rettangoli, cerchi, linee). Ogni azione dell'utente (spostare una forma, cambiare colore, ridimensionare) modifica lo stato. Il sistema di undo funziona così:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prima di ogni azione, il canvas chiama &lt;code&gt;createMemento()&lt;/code&gt; che salva le posizioni, dimensioni e colori di tutte le forme&lt;/li&gt;
&lt;li&gt;Il caretaker (un &lt;code&gt;HistoryManager&lt;/code&gt;) pusha il memento nello stack di undo&lt;/li&gt;
&lt;li&gt;L'utente preme Ctrl+Z: il caretaker poppa l'ultimo memento e chiama &lt;code&gt;canvas-&amp;gt;restore($memento)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Il canvas legge lo stato dal memento e si riporta alla configurazione precedente&lt;/li&gt;
&lt;li&gt;Il memento poppato va nello stack di redo per permettere Ctrl+Y&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Memento e serializzazione in PHP
&lt;/h2&gt;

&lt;p&gt;In PHP, il Memento si implementa spesso tramite &lt;strong&gt;serializzazione&lt;/strong&gt;. Il memento può essere un array associativo dello stato, un oggetto immutabile, o persino una stringa JSON. L'importante e che il contenuto sia opaco per il caretaker:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Array memento&lt;/strong&gt;: &lt;code&gt;createMemento(): array&lt;/code&gt; restituisce &lt;code&gt;['title' =&amp;gt; $this-&amp;gt;title, 'content' =&amp;gt; $this-&amp;gt;content]&lt;/code&gt;. Semplice ma espone la struttura.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Oggetto memento&lt;/strong&gt;: una classe &lt;code&gt;EditorMemento&lt;/code&gt; con proprieta private. Solo l'editor sa come leggerle. Più sicuro.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memento criptato&lt;/strong&gt;: lo stato viene serializzato e criptato. Anche se il caretaker accede al memento, non può leggerne il contenuto.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Memento vs Command per l'undo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Command con undo&lt;/strong&gt;: ogni command sa come annullarsi. L'undo e &lt;em&gt;inverso&lt;/em&gt;: esegue l'operazione opposta. Funziona se ogni operazione ha un inverso chiaro.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memento&lt;/strong&gt;: salva lo stato completo prima di ogni operazione. L'undo e &lt;em&gt;ripristino&lt;/em&gt;: riporta allo stato salvato. Funziona anche quando l'operazione inversa non esiste o e ambigua.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il Command e più efficiente (salva solo il delta), il Memento e più robusto (salva tutto). Per operazioni semplici e reversibili usa Command. Per stati complessi dove l'inverso e difficile da calcolare, usa Memento.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quando usare il Memento Pattern
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Usa il Memento&lt;/strong&gt; quando devi implementare undo/redo e lo stato dell'oggetto e complesso&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa il Memento&lt;/strong&gt; quando vuoi salvare checkpoint/snapshot dello stato per recovery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa il Memento&lt;/strong&gt; quando l'accesso diretto allo stato violerebbe l'incapsulamento&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non usare il Memento&lt;/strong&gt; se lo stato e enorme e i memento consumano troppa memoria — considera il salvataggio incrementale&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non usare il Memento&lt;/strong&gt; se l'operazione inversa e semplice e chiara: Command con undo e più leggero&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il Memento Pattern e il pattern della &lt;strong&gt;fotografia dello stato&lt;/strong&gt;: cattura un istante, lo conserva, e lo ripristina quando serve. E il fondamento di ogni sistema di undo, versioning e recovery che rispetti l'incapsulamento degli oggetti.&lt;/p&gt;




&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://iadicola.it/articoli/memento-pattern-catturare-e-ripristinare-lo-stato?utm_source=devto&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Leggi l'articolo completo su iadicola.it&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>snapshot</category>
      <category>ripristino</category>
      <category>memento</category>
      <category>comportamentale</category>
    </item>
    <item>
      <title>Visitor Pattern: aggiungere operazioni senza modificare le classi</title>
      <dc:creator>Dev-Iadicola</dc:creator>
      <pubDate>Fri, 10 Jul 2026 17:00:23 +0000</pubDate>
      <link>https://dev.to/dev_iadicola/visitor-pattern-aggiungere-operazioni-senza-modificare-le-classi-3f50</link>
      <guid>https://dev.to/dev_iadicola/visitor-pattern-aggiungere-operazioni-senza-modificare-le-classi-3f50</guid>
      <description>&lt;h2&gt;
  
  
  Il problema: nuove operazioni su classi chiuse
&lt;/h2&gt;

&lt;p&gt;Hai una gerarchia di nodi AST (Abstract Syntax Tree) per un linguaggio di template: &lt;code&gt;TextNode&lt;/code&gt;, &lt;code&gt;VariableNode&lt;/code&gt;, &lt;code&gt;IfNode&lt;/code&gt;, &lt;code&gt;ForNode&lt;/code&gt;, &lt;code&gt;IncludeNode&lt;/code&gt;. Devi aggiungere operazioni diverse su questi nodi: rendering HTML, compilazione in PHP, conteggio delle variabili usate, validazione della sintassi, pretty-printing. Se aggiungi un metodo per ogni operazione a ogni classe nodo, le classi esplodono di complessità. E peggio: ogni nuova operazione richiede di modificare tutte le classi nodo.&lt;/p&gt;

&lt;p&gt;Il &lt;strong&gt;Visitor Pattern&lt;/strong&gt; inverte la responsabilità: invece di aggiungere metodi ai nodi, crei un nuovo oggetto Visitor per ogni operazione. Il visitor "visita" ogni nodo e il nodo gli dice "sono un IfNode, trattami come tale". Questa tecnica si chiama &lt;strong&gt;double dispatch&lt;/strong&gt;: il comportamento dipende sia dal tipo del visitor che dal tipo del nodo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cos'e il Visitor Pattern: definizione formale
&lt;/h2&gt;

&lt;p&gt;Il Gang of Four definisce il Visitor come un pattern comportamentale che "rappresenta un'operazione da eseguire sugli elementi di una struttura di oggetti. Il Visitor permette di definire nuove operazioni senza cambiare le classi degli elementi su cui opera". La struttura:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Visitor&lt;/strong&gt;: interfaccia con un metodo &lt;code&gt;visit&lt;/code&gt; per ogni tipo di elemento (&lt;code&gt;visitTextNode(TextNode $n)&lt;/code&gt;, &lt;code&gt;visitIfNode(IfNode $n)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ConcreteVisitor&lt;/strong&gt;: implementa l'operazione specifica per ogni tipo di nodo (es. &lt;code&gt;HtmlRendererVisitor&lt;/code&gt;, &lt;code&gt;VariableCounterVisitor&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Element&lt;/strong&gt;: interfaccia con un metodo &lt;code&gt;accept(Visitor $v)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ConcreteElement&lt;/strong&gt;: ogni nodo implementa &lt;code&gt;accept()&lt;/code&gt; chiamando &lt;code&gt;$v-&amp;gt;visitXxx($this)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Il double dispatch spiegato
&lt;/h2&gt;

&lt;p&gt;PHP (come Java e C#) supporta solo il &lt;strong&gt;single dispatch&lt;/strong&gt;: il metodo chiamato dipende dal tipo dell'oggetto su cui viene chiamato, non dal tipo dei parametri. Il Visitor simula il double dispatch con due chiamate polimorfiche:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Il client chiama &lt;code&gt;$node-&amp;gt;accept($visitor)&lt;/code&gt; — primo dispatch basato sul tipo del nodo&lt;/li&gt;
&lt;li&gt;Dentro &lt;code&gt;accept()&lt;/code&gt;, il nodo chiama &lt;code&gt;$visitor-&amp;gt;visitIfNode($this)&lt;/code&gt; — secondo dispatch basato sul tipo del visitor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il risultato: il comportamento dipende da &lt;em&gt;entrambi&lt;/em&gt; i tipi. Un &lt;code&gt;HtmlRendererVisitor&lt;/code&gt; che visita un &lt;code&gt;IfNode&lt;/code&gt; produce HTML diverso da un &lt;code&gt;VariableCounterVisitor&lt;/code&gt; che visita lo stesso &lt;code&gt;IfNode&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Esempio teorico: analisi di un AST
&lt;/h2&gt;

&lt;p&gt;Con il Visitor puoi aggiungere operazioni illimitate senza toccare i nodi:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;HtmlRendererVisitor&lt;/code&gt;: trasforma l'AST in HTML. &lt;code&gt;visitTextNode()&lt;/code&gt; restituisce il testo, &lt;code&gt;visitIfNode()&lt;/code&gt; valuta la condizione e renderizza il branch corretto.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PhpCompilerVisitor&lt;/code&gt;: compila l'AST in codice PHP. &lt;code&gt;visitIfNode()&lt;/code&gt; genera &lt;code&gt;if ($condition) { ... }&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;VariableCollectorVisitor&lt;/code&gt;: raccoglie tutte le variabili usate. &lt;code&gt;visitVariableNode()&lt;/code&gt; aggiunge il nome alla lista.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SecurityAuditorVisitor&lt;/code&gt;: cerca pattern pericolosi. &lt;code&gt;visitIncludeNode()&lt;/code&gt; verifica che il path non contenga input dell'utente non sanitizzato.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ogni nuova operazione e una nuova classe Visitor. I nodi non cambiano mai. Questo e il potere del pattern: l'asse delle operazioni e aperto all'estensione.&lt;/p&gt;

&lt;h2&gt;
  
  
  Visitor nel mondo reale: Rector e PHPStan
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rector&lt;/strong&gt; (il tool di refactoring automatico per PHP) e costruito interamente sul Visitor Pattern. Ogni regola di refactoring e un Visitor che attraversa l'AST del codice PHP. &lt;code&gt;RenameClassRector&lt;/code&gt; visita i nodi di tipo &lt;code&gt;Name&lt;/code&gt; e li rinomina. &lt;code&gt;AddReturnTypeDeclarationRector&lt;/code&gt; visita i nodi &lt;code&gt;ClassMethod&lt;/code&gt; e aggiunge i return type. Aggiungere una nuova regola significa creare un nuovo Visitor, senza toccare il parser o i nodi AST.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PHPStan&lt;/strong&gt; usa lo stesso principio: ogni regola di analisi statica e un visitor che ispeziona nodi specifici dell'AST cercando pattern problematici.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quando usare il Visitor Pattern
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Usa il Visitor&lt;/strong&gt; quando la struttura degli oggetti e stabile ma le operazioni cambiano spesso&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa il Visitor&lt;/strong&gt; quando vuoi aggiungere operazioni a classi che non puoi o non vuoi modificare&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa il Visitor&lt;/strong&gt; per separare algoritmi complessi dalle strutture dati su cui operano&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non usare il Visitor&lt;/strong&gt; se la gerarchia di classi cambia spesso: ogni nuovo tipo richiede un nuovo metodo in tutti i visitor&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non usare il Visitor&lt;/strong&gt; se hai 2-3 operazioni semplici: un metodo nella classe e più diretto&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il Visitor Pattern e il pattern della &lt;strong&gt;separazione operazione-struttura&lt;/strong&gt;. Quando la struttura e stabile e le operazioni crescono, il Visitor evita di riaprire classi chiuse e mantiene ogni operazione in un'unita coesa e testabile.&lt;/p&gt;




&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://iadicola.it/articoli/visitor-pattern-aggiungere-operazioni-senza-modificare-classi?utm_source=devto&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Leggi l'articolo completo su iadicola.it&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>visitor</category>
      <category>comportamentale</category>
      <category>doppiodispatch</category>
    </item>
    <item>
      <title>Gestionale Magazzino, un software che può farti risparmiare soldi, tempo ed errori</title>
      <dc:creator>Dev-Iadicola</dc:creator>
      <pubDate>Thu, 09 Jul 2026 17:00:21 +0000</pubDate>
      <link>https://dev.to/dev_iadicola/gestionale-magazzino-un-software-che-puo-farti-risparmiare-soldi-tempo-ed-errori-26f9</link>
      <guid>https://dev.to/dev_iadicola/gestionale-magazzino-un-software-che-puo-farti-risparmiare-soldi-tempo-ed-errori-26f9</guid>
      <description>&lt;p&gt;Ogni magazzino vive di una domanda che si ripete dalla mattina alla sera: &lt;em&gt;cosa è entrato, cosa è uscito, e dove si trova adesso?&lt;/em&gt; Sembra una cosa semplice, ma chiunque ci abbia lavorato sa che la realtà è fatta di terminali condivisi, operatori che si alternano, merce che esce prima di essere registrata, fornitori da rincorrere e inventari che non tornano mai del tutto.&lt;/p&gt;

&lt;p&gt;Ho progettato questo gestionale partendo proprio da lì: non da un elenco astratto di funzioni, ma dai problemi concreti di chi il magazzino lo vive ogni giorno. Quasi ogni scelta dell'applicazione nasce da una frustrazione reale del lavoro quotidiano — e la cosa interessante è &lt;em&gt;come&lt;/em&gt; è stata risolta. In questo articolo faccio un giro completo dell'applicazione, area per area, spiegando lungo il percorso perché funziona così.&lt;/p&gt;

&lt;h2&gt;
  
  
  Due ambienti, due esigenze diverse
&lt;/h2&gt;

&lt;p&gt;L'applicazione è divisa in due mondi pensati per due modi di lavorare completamente diversi.&lt;/p&gt;

&lt;p&gt;Il primo è il &lt;strong&gt;terminale dell'operatore&lt;/strong&gt;: la postazione dove si scansiona, si carica, si scarica, svolgono resi e si conta. Deve essere veloce, a prova di errore, utilizzabile anche da chi non ha alcuna dimestichezza con i computer e magari ha i &lt;strong&gt;&lt;em&gt;guanti addosso&lt;/em&gt;&lt;/strong&gt;. Funziona benissimo su un tablet o uno smartphone.&lt;/p&gt;

&lt;p&gt;Il secondo è il &lt;strong&gt;cruscotto del supervisore&lt;/strong&gt;: la cabina di regia dove si tiene tutto sotto controllo, si analizzano i dati, si gestiscono le anagrafiche e si prendono le decisioni. Qui contano la visione d'insieme e il controllo, non la velocità di scansione.&lt;/p&gt;

&lt;p&gt;La stessa applicazione, quindi, mostra cose diverse a persone diverse — e già questa è una scelta di progetto importante: ognuno vede solo ciò che gli serve davvero.&lt;/p&gt;

&lt;h3&gt;
  
  
  Il Software funziona sia su Desktop, Terminale e Smartphone
&lt;/h3&gt;

&lt;p&gt;Per permettere la funzionalità ovunque ti trovi, senza spostarsi e dover andare da una zona per poter effettuare le operazioni.&lt;/p&gt;




&lt;h2&gt;
  
  
  Il terminale: il lavoro di tutti i giorni
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Autenticazioni col PIN.
&lt;/h3&gt;

&lt;p&gt;In un magazzino il computer (o il tablet) è uno solo e lo usano in tanti, a turno. Chiedere a ogni operatore di fare &lt;em&gt;logout&lt;/em&gt; e &lt;em&gt;login&lt;/em&gt; con email e password ogni volta che si avvicina alla postazione è una di quelle cose che, sulla carta, funziona — e nella pratica nessuno fa. Il risultato classico: lavorano tutti con lo stesso utente, e diventa impossibile sapere chi ha fatto cosa.&lt;/p&gt;

&lt;p&gt;Qui la logica è diversa. Il terminale resta acceso alla prima autenticazione con email e password. Ma ogni operazione richiede un &lt;strong&gt;PIN personale di 4 cifre&lt;/strong&gt;: l'operatore lo digita, fa il suo movimento, e quel movimento resta legato al suo nome per sempre. Il PIN "scade" dopo pochi minuti di inattività, così il sistema lo richiede di nuovo e non rischia mai di attribuire un'operazione alla persona sbagliata.&lt;/p&gt;

&lt;p&gt;È un doppio orologio pensato apposta: uno lento, che tiene il dispositivo pronto all'uso senza costringere a riloggarsi di continuo; uno veloce, che garantisce la &lt;strong&gt;tracciabilità reale&lt;/strong&gt; di ogni singolo gesto. Per chi entra e esce dalla postazione decine di volte al giorno cambia completamente l'esperienza, e per chi deve controllare cambia l'affidabilità dei dati.&lt;/p&gt;

&lt;p&gt;Se un operatore passa lo smartphone a un altro operatore, per identificarsi deve digitare il PIN nella schermata.&lt;/p&gt;

&lt;p&gt;Il design permette di effettuare lo scambio di utenti in modo veloce. Ogni utente ha un PIN personale che non deve condividere con nessun operatore.&lt;/p&gt;

&lt;h3&gt;
  
  
  Il carico: far entrare la merce
&lt;/h3&gt;

&lt;p&gt;Quando arriva merce, l'operatore apre la schermata di &lt;strong&gt;carico&lt;/strong&gt;, scansiona il codice a barre dell'articolo con laser o camera (o lo cerca per codice), inserisce le quantità e, se serve, il numero del documento di trasporto e il fornitore.&lt;/p&gt;

&lt;p&gt;L'utente clicca &lt;em&gt;Conferma&lt;/em&gt;, e la giacenza si aggiorna all'istante.&lt;/p&gt;

&lt;p&gt;Ogni carico non è solo un "più uno" sul totale: genera un &lt;strong&gt;movimento registrato&lt;/strong&gt; che conserva chi l'ha fatto, quando, quanto, da quale fornitore e con quale documento. Niente si perde, e tutto è ricostruibile, tutto &lt;strong&gt;rintracciabile e monitorato.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo scarico: l'app capisce da sola il perché
&lt;/h3&gt;

&lt;p&gt;Quando la merce esce, può uscire per due motivi molto diversi: o viene &lt;strong&gt;venduta a un cliente&lt;/strong&gt;, oppure viene &lt;strong&gt;consumata internamente dalla produzione&lt;/strong&gt;. Sono due cose che vanno registrate in modo diverso, e di solito si chiede all'operatore di sceglierle da un menù. Ogni scelta manuale è un'occasione per sbagliare.&lt;/p&gt;

&lt;p&gt;Così ho pensato a questo approccio:&lt;/p&gt;

&lt;p&gt;Qui l'app lo capisce da sola, in base a &lt;em&gt;chi&lt;/em&gt; sta lavorando. Un operatore "normale" scarica sempre verso un cliente; un operatore della produzione scarica sempre verso la produzione. Chi usa il sistema non deve decidere nulla: fa il suo lavoro e la classificazione corretta arriva in automatico. Il supervisore, che ha la visione completa, resta l'unico che può scegliere manualmente quando il caso lo richiede.&lt;/p&gt;

&lt;p&gt;Meno scelte da fare significa meno errori — e numeri di fine mese che tornano. E se lo scarico supera la merce disponibile, il sistema lo segnala con un avviso, senza però bloccare il lavoro (più avanti spiego perché).&lt;/p&gt;

&lt;h3&gt;
  
  
  I resi: la merce che torna indietro
&lt;/h3&gt;

&lt;p&gt;La merce non viaggia mai in una sola direzione. A volte un cliente restituisce qualcosa, a volte siamo noi a rispedire merce a un fornitore. La schermata dei &lt;strong&gt;resi&lt;/strong&gt; gestisce entrambi i casi tenendoli ben distinti: il reso &lt;em&gt;da&lt;/em&gt; cliente fa rientrare la merce in magazzino, il reso &lt;em&gt;verso&lt;/em&gt; fornitore la fa uscire. Anche qui ogni movimento resta tracciato con il suo motivo, così l'inventario riflette sempre la situazione reale e non un'approssimazione.&lt;/p&gt;

&lt;h3&gt;
  
  
  La ricerca: trovare un articolo in un istante
&lt;/h3&gt;

&lt;p&gt;Cercare un prodotto è l'azione più frequente in assoluto. Per questo la ricerca funziona sia per &lt;strong&gt;codice&lt;/strong&gt; (incluso il codice a barre) sia per &lt;strong&gt;descrizione&lt;/strong&gt;, ed è una ricerca testuale vera, che trova anche con parole parziali. Restituisce subito ciò che serve davvero a chi è in magazzino: dove si trova l'articolo, quanti pezzi sono disponibili e qual è il fornitore. Niente filtri complicati: si scrive e si trova. Da lì si apre la &lt;strong&gt;scheda di dettaglio&lt;/strong&gt; dell'articolo con tutte le informazioni.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creare un articolo "al volo", senza bloccare la merce
&lt;/h3&gt;

&lt;p&gt;Capita spessissimo: arriva un bancale, l'operatore scansiona il codice e… quell'articolo non esiste ancora a sistema. La reazione naturale sarebbe mettere tutto in pausa, chiamare il responsabile, far creare la scheda — e nel frattempo la merce resta lì e il lavoro si ferma.&lt;/p&gt;

&lt;p&gt;Con questo gestionale, se la funzione è abilitata, l'operatore può &lt;strong&gt;creare l'articolo sul momento&lt;/strong&gt;, direttamente dalla schermata di carico, con un piccolo modulo veloce. L'articolo nasce subito ed è immediatamente disponibile per essere caricato. &lt;strong&gt;La merce entra, il lavoro non si ferma, e il supervisore completerà con calma i dettagli più tardi.&lt;/strong&gt; È il supervisore stesso a decidere se concedere o meno questa possibilità, tramite un'impostazione.&lt;/p&gt;

&lt;p&gt;Premessa: ogni articolo ha un codice EAN, pertanto scansionando il codice tramite fotocamera o tramite la pistola, è possibile riconoscere subito l'articolo. Questa funzionalità, infatti, permette di inserire articoli nuovi, mai arrivati in magazzino, per poter svolgere il lavoro con precisione e non avere duplicati, il software non permettere di inserire articoli con codice EAN duplicati.&lt;/p&gt;

&lt;h3&gt;
  
  
  L'inventario si conta "alla cieca"
&lt;/h3&gt;

&lt;p&gt;Il momento dell'inventario fisico è quello in cui i conti dovrebbero finalmente tornare — ed è proprio quello in cui, spesso senza volerlo, si bara di più. Se l'operatore vede a schermo &lt;em&gt;"a sistema risultano 100 pezzi"&lt;/em&gt;, è umano che, contandone 98, finisca per scrivere 100 "tanto è quello giusto".&lt;/p&gt;

&lt;p&gt;Qui durante la conta l'operatore &lt;strong&gt;non vede mai la quantità attesa&lt;/strong&gt;: inserisce soltanto ciò che conta davvero, scansionando gli articoli uno a uno. Se prova a contare due volte lo stesso articolo nella stessa sessione, il sistema lo avvisa in modo chiaro. Il confronto con i dati di sistema avviene dopo, e solo dal lato del supervisore.&lt;/p&gt;

&lt;p&gt;È una conta più onesta, perché elimina alla radice la tentazione di "aggiustare" il numero.&lt;/p&gt;




&lt;h2&gt;
  
  
  Il cruscotto del supervisore: governo e controllo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  La dashboard: la fotografia del magazzino
&lt;/h3&gt;

&lt;p&gt;Aprendo il cruscotto, il supervisore trova subito una &lt;strong&gt;dashboard&lt;/strong&gt; con gli indicatori che contano: quanti articoli sono gestiti, quanti sono sotto la soglia minima e rischiano di esaurirsi, quanti movimenti ci sono stati nella giornata, quanti avvisi sono aperti. È la fotografia immediata dello stato di salute del magazzino, prima ancora di entrare nel dettaglio.&lt;/p&gt;

&lt;h3&gt;
  
  
  L'anagrafica articoli
&lt;/h3&gt;

&lt;p&gt;Il cuore dei dati è l'&lt;strong&gt;anagrafica articoli&lt;/strong&gt;, dove il supervisore gestisce tutto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;descrizione.&lt;/li&gt;
&lt;li&gt;codice.&lt;/li&gt;
&lt;li&gt;unità di misura.&lt;/li&gt;
&lt;li&gt;ubicazione.&lt;/li&gt;
&lt;li&gt;fornitore.&lt;/li&gt;
&lt;li&gt;categoria di appartenenza e &lt;strong&gt;soglia minima&lt;/strong&gt; (la scorta sotto la quale far scattare un avviso).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Qui si trovano anche le informazioni riservate, come prezzo di costo e prezzo di vendita, &lt;strong&gt;che gli operatori non vedono&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Etichettatura.
&lt;/h3&gt;

&lt;p&gt;Dall'anagrafica è anche possibile &lt;strong&gt;generare e stampare le etichette con il codice a barre&lt;/strong&gt;, così ogni articolo può essere scansionato in fase di carico, scarico e inventario. Un dettaglio pratico che chiude il cerchio tra dato digitale e merce fisica.&lt;/p&gt;

&lt;h3&gt;
  
  
  Le giacenze e i movimenti
&lt;/h3&gt;

&lt;p&gt;La vista &lt;strong&gt;giacenze&lt;/strong&gt; mostra tutte le scorte in un colpo d'occhio, con la possibilità di filtrare ed evidenziare gli articoli sotto soglia. È il "quanto ho" di tutto il magazzino.&lt;/p&gt;

&lt;p&gt;La vista &lt;strong&gt;movimenti&lt;/strong&gt; è invece il "cosa è successo": il registro completo e filtrabile di ogni carico, scarico, reso e rettifica, con data, operatore e articolo. È qui che, in caso di dubbio, si ricostruisce la storia esatta di un prodotto — chi lo ha toccato, quando e perché. È la memoria del magazzino.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gli inventari
&lt;/h3&gt;

&lt;p&gt;Le sessioni di &lt;strong&gt;inventario&lt;/strong&gt; vengono aperte dal supervisore; gli operatori contano dal terminale, alla cieca come dicevo sopra. Quando la conta è completa, il supervisore confronta i numeri raccolti con quelli a sistema, vede le differenze e decide cosa fare. Se approva, è il sistema stesso a generare in automatico le &lt;strong&gt;rettifiche&lt;/strong&gt; necessarie per allineare le giacenze — e ogni rettifica resta collegata all'inventario che l'ha prodotta. Niente correzioni "a mano" non tracciate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gli alert e le giacenze negative
&lt;/h3&gt;

&lt;p&gt;Qui c'è una delle scelte più controcorrente dell'applicazione. Molti gestionali &lt;strong&gt;bloccano&lt;/strong&gt; lo scarico se a sistema "non c'è abbastanza merce". Sembra prudente, ma nella pratica è il contrario: spesso la merce è già uscita fisicamente e semplicemente non è ancora stata registrata. Bloccare l'operazione costringe le persone a trovare scorciatoie pur di andare avanti, e il dato diventa ancora &lt;em&gt;meno&lt;/em&gt; affidabile.&lt;/p&gt;

&lt;p&gt;Questo sistema permette alla giacenza di scendere sotto lo zero, perché preferisce &lt;strong&gt;registrare la verità&lt;/strong&gt; piuttosto che una finzione ordinata. Però, appena succede, fa scattare un &lt;strong&gt;avviso per il supervisore&lt;/strong&gt; — esattamente come fa quando un articolo scende sotto la soglia minima. E gli avvisi sono intelligenti: non ripetono lo stesso allarme all'infinito, ma segnalano una sola volta finché la situazione non cambia davvero. Così le notifiche restano utili, invece di diventare rumore di fondo da ignorare.&lt;/p&gt;

&lt;h3&gt;
  
  
  Le anagrafiche di base e la gestione multi-sede
&lt;/h3&gt;

&lt;p&gt;Attorno agli articoli ruotano le anagrafiche di supporto, tutte gestibili dal cruscotto: &lt;strong&gt;clienti&lt;/strong&gt;, &lt;strong&gt;fornitori&lt;/strong&gt; e &lt;strong&gt;ubicazioni&lt;/strong&gt; (le posizioni fisiche dentro il magazzino). C'è inoltre la gestione delle &lt;strong&gt;sedi&lt;/strong&gt;, pensata per chi ha più di un magazzino o deposito: le ubicazioni appartengono a una sede, così la stessa applicazione può seguire scorte distribuite su luoghi diversi.&lt;/p&gt;

&lt;h3&gt;
  
  
  Utenti, PIN e permessi
&lt;/h3&gt;

&lt;p&gt;Il supervisore crea e gestisce gli &lt;strong&gt;utenti&lt;/strong&gt; — nome, cognome, ruolo e PIN. Può assegnare un PIN, rigenerarlo in modo casuale, e il sistema lo aiuta a evitare doppioni suggerendo automaticamente un codice libero quando ne rileva uno già in uso.&lt;/p&gt;

&lt;p&gt;Ma la parte più potente è la &lt;strong&gt;matrice dei permessi&lt;/strong&gt;. Le regole di un magazzino cambiano nel tempo: oggi un certo ruolo può fare una cosa, domani no. Di solito modificare "chi può fare cosa" significa chiamare lo sviluppatore e aspettare un aggiornamento. Qui il supervisore ha una tabella che può modificare da solo, con qualche clic: decide quali ruoli possono creare articoli, approvare inventari, gestire utenti e così via. Le regole si adattano all'organizzazione senza bisogno di toccare il codice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Le impostazioni e il diario delle attività
&lt;/h3&gt;

&lt;p&gt;Dalle &lt;strong&gt;impostazioni&lt;/strong&gt; il supervisore regola i comportamenti del sistema: i tempi di scadenza del PIN e della sessione, e se concedere agli operatori la creazione di articoli al volo. Sono le manopole che permettono di adattare l'app al ritmo del proprio magazzino.&lt;/p&gt;

&lt;p&gt;Infine, ogni modifica importante — agli articoli, ai fornitori, ai PIN degli utenti — viene registrata in un &lt;strong&gt;diario delle attività&lt;/strong&gt;: chi, cosa, quando. Una rete di sicurezza per quando serve capire come si è arrivati a una certa situazione. E quando i dati servono altrove, le viste principali si possono &lt;strong&gt;esportare in Excel&lt;/strong&gt; per analisi, report o controlli.&lt;/p&gt;




&lt;h2&gt;
  
  
  Il filo conduttore di tutte queste scelte
&lt;/h2&gt;

&lt;p&gt;Mettendo in fila queste decisioni, emerge una logica precisa. L'identificazione col PIN invece del login completo, la classificazione automatica dello scarico in base al ruolo, l'inventario alla cieca, le giacenze che possono andare in negativo invece di bloccare il lavoro: sono tutte facce della stessa idea.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;La tecnologia deve adattarsi al modo in cui si lavora davvero in magazzino, non il contrario.&lt;/strong&gt; Niente passaggi inutili imposti all'operatore, niente dati "puliti" ma falsi, niente regole rigide che costringono a inventarsi scorciatoie. Un gestionale che riduce gli errori non perché controlla di più le persone, ma perché chiede loro di pensare di meno alle cose che la macchina può capire da sola — e lascia il controllo, quello vero, a chi deve averlo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sotto il cofano, in breve
&lt;/h2&gt;

&lt;p&gt;Senza entrare nel tecnico: l'applicazione gira interamente nel &lt;strong&gt;browser&lt;/strong&gt;, quindi funziona da computer, tablet o smartphone senza installare nulla. La scansione dei codici a barre può usare sia un lettore fisico sia la &lt;strong&gt;fotocamera&lt;/strong&gt; del telefono o del tablet. È costruita con tecnologie web moderne e ampiamente collaudate (l'ecosistema Laravel lato server, un'interfaccia reattiva lato utente), pensate per restare veloci e fluide anche con molti operatori che lavorano contemporaneamente sulla stessa postazione.&lt;/p&gt;

&lt;p&gt;In sintesi: un software che mette d'accordo due esigenze che di solito litigano — la velocità di chi sta in mezzo alla merce e il controllo di chi deve rispondere dei numeri.&lt;/p&gt;

&lt;p&gt;Il software è di proprietà del cliente. Pertanto ogni singolo software che produco sarà unico. Quest'articolo descrive un esempio di cosa è possibile costruire come software funzionali avanzati per la tua azienda.&lt;/p&gt;

&lt;p&gt;Se sei interessato ad introdurre nuove tecnologie all'avanguardia, personalizzate e su misura per il tuo flusso di lavoro, contattami per capire come dovrà essere il tuo software, la struttura e tutto ciò che desideri che il software svolga.&lt;/p&gt;




&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://iadicola.it/articoli/gestionale-magazzino-un-software-che-puo-farti-risparmiare-soldi-e-tempo-ed-errori?utm_source=devto&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Leggi l'articolo completo su iadicola.it&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>excel</category>
      <category>crm</category>
      <category>erp</category>
      <category>react</category>
    </item>
    <item>
      <title>Monolite modulare: la potenza del monolite con la struttura dei microservizi</title>
      <dc:creator>Dev-Iadicola</dc:creator>
      <pubDate>Wed, 08 Jul 2026 17:00:12 +0000</pubDate>
      <link>https://dev.to/dev_iadicola/monolite-modulare-la-potenza-del-monolite-con-la-struttura-dei-microservizi-3kc2</link>
      <guid>https://dev.to/dev_iadicola/monolite-modulare-la-potenza-del-monolite-con-la-struttura-dei-microservizi-3kc2</guid>
      <description>&lt;h2&gt;
  
  
  Il falso dilemma: monolite o microservizi
&lt;/h2&gt;

&lt;p&gt;Il dibattito "monolite vs microservizi" presenta una falsa dicotomia. Un monolite non deve essere per forza un Big Ball of Mud dove tutto dipende da tutto. E i microservizi non sono l'unico modo per avere separazione e modularita. Il &lt;strong&gt;monolite modulare&lt;/strong&gt; e la terza via: un'applicazione deployata come un singolo artefatto, ma organizzata internamente in moduli con confini espliciti.&lt;/p&gt;

&lt;p&gt;Shopify — una delle piattaforme e-commerce più grandi del mondo — ha scelto il monolite modulare con Rails. GitHub ha un monolite modulare Ruby. Basecamp idem. Non e una scelta per principianti: e una scelta architetturale consapevole che privilegia la semplicità operativa senza sacrificare la struttura.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cos'e un modulo
&lt;/h2&gt;

&lt;p&gt;Un modulo e una porzione dell'applicazione con:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Confini espliciti&lt;/strong&gt;: un namespace dedicato, una directory propria. &lt;code&gt;App\Modules\Orders\&lt;/code&gt;, &lt;code&gt;App\Modules\Catalog\&lt;/code&gt;, &lt;code&gt;App\Modules\Users\&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API pubblica&lt;/strong&gt;: ogni modulo espone un'interfaccia limitata (un Service, un Facade) che gli altri moduli possono usare. Le classi interne sono private al modulo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database isolato&lt;/strong&gt; (logicamente): ogni modulo possiede le proprie tabelle. Il modulo Orders non accede direttamente alle tabelle del modulo Catalog — passa attraverso l'API pubblica.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comunicazione esplicita&lt;/strong&gt;: i moduli comunicano tramite interfacce definite o eventi, non tramite import diretti di classi interne.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Esempio: un gestionale e-commerce modulare
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modulo Catalog&lt;/strong&gt;: gestisce prodotti, categorie, prezzi. Espone &lt;code&gt;CatalogService::getProduct(int $id)&lt;/code&gt; e &lt;code&gt;CatalogService::checkAvailability(int $productId, int $qty)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modulo Orders&lt;/strong&gt;: gestisce ordini, carrello, checkout. Chiama &lt;code&gt;CatalogService&lt;/code&gt; per verificare disponibilita, non accede alle tabelle prodotti direttamente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modulo Payments&lt;/strong&gt;: gestisce pagamenti e fatturazione. Riceve eventi &lt;code&gt;OrderPlaced&lt;/code&gt; dal modulo Orders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modulo Users&lt;/strong&gt;: gestisce registrazione, profili, permessi. Gli altri moduli lo usano per autenticazione e autorizzazione.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ogni modulo può evolvere indipendentemente. Il team che lavora sul Catalog non rischia di rompere gli Orders. Le dipendenze sono esplicite e unidirezionali.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vantaggi rispetto al monolite classico
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Confini chiari&lt;/strong&gt;: sai dove finisce un modulo e dove inizia un altro. I refactoring sono localizzati.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dipendenze visibili&lt;/strong&gt;: se un modulo importa classi da un altro, e un code smell visibile — non un accoppiamento nascosto in una query SQL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team scaling&lt;/strong&gt;: team diversi possono lavorare su moduli diversi con meno conflitti.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Migrazione futura&lt;/strong&gt;: se un modulo diventa un collo di bottiglia, estrarlo in un microservizio e fattibile perché i confini sono già definiti.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Vantaggi rispetto ai microservizi
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deploy singolo&lt;/strong&gt;: un artefatto, un server, un deploy. Nessun orchestratore, nessun service mesh, nessun distributed tracing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transazioni atomiche&lt;/strong&gt;: le operazioni cross-modulo possono usare transazioni database. Nei microservizi servono saga e compensazioni.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging semplice&lt;/strong&gt;: un processo, uno stack trace, un log. Niente chiamate di rete da debuggare.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Costo operativo basso&lt;/strong&gt;: un VPS da 20 EUR/mese invece di un cluster Kubernetes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quando scegliere il monolite modulare
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scegli il monolite modulare&lt;/strong&gt; quando il team e piccolo-medio (2-10 sviluppatori) e la complessità e nel dominio, non nell'infrastruttura&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scegli il monolite modulare&lt;/strong&gt; quando vuoi struttura e separazione senza il costo operativo dei microservizi&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scegli il monolite modulare&lt;/strong&gt; come punto di partenza: puoi sempre estrarre un microservizio dopo, ma non puoi facilmente tornare indietro&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scegli i microservizi&lt;/strong&gt; solo quando hai team grandi (50+), requisiti di scalabilità asimmetrica reali, e budget operativo adeguato&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il monolite modulare e la scelta pragmatica per la maggior parte dei progetti reali. Non e meno sofisticato dei microservizi — e più disciplinato: richiede la stessa cura nella definizione dei confini, senza la complessità della rete distribuita.&lt;/p&gt;




&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://iadicola.it/articoli/monolite-modulare-potenza-monolite-struttura-microservizi?utm_source=devto&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Leggi l'articolo completo su iadicola.it&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>monolith</category>
      <category>modulare</category>
      <category>pragmatico</category>
    </item>
    <item>
      <title>Da 11 a 4 secondi: come ho ottimizzato la velocità di un sito con render free tier</title>
      <dc:creator>Dev-Iadicola</dc:creator>
      <pubDate>Tue, 07 Jul 2026 17:00:20 +0000</pubDate>
      <link>https://dev.to/dev_iadicola/da-11-a-4-secondi-come-ho-ottimizzato-la-velocita-di-un-sito-con-render-free-tier-32a6</link>
      <guid>https://dev.to/dev_iadicola/da-11-a-4-secondi-come-ho-ottimizzato-la-velocita-di-un-sito-con-render-free-tier-32a6</guid>
      <description>&lt;h2&gt;
  
  
  Primi aspetti.
&lt;/h2&gt;

&lt;p&gt;Lunedì mattina. Apro il mio sito da una connessione 4G normale. Cronometro mentale. Uno, due, tre… nove… undici secondi. &lt;strong&gt;Undici secondi prima che la home sia utilizzabile.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Che dire*&lt;em&gt;, potrei battere qualsiasi record.&lt;/em&gt;*&lt;/p&gt;

&lt;p&gt;Dopotutto sto utilizzando render piano free e un database gratuito. Perché insomma, la qualità si paga. Si sa.&lt;/p&gt;

&lt;p&gt;Il problema non è la pazienza dei nerd come me, abituati a tutto. Il problema è il cliente che cerca su Google "software gestionale su misura", clicca sul mio sito, e nei primi tre secondo decide se sono affidabile o meno. Se il sito è lento, la risposta è no. Chiude la tab. Apre quello dopo. E io ho perso un'opportunità senza nemmeno saperlo.&lt;/p&gt;

&lt;p&gt;Il cliente giustamente non sa per quale motivo è lento. Io si, dietro a questa web app c'è un sistema di page building (simile a wix, quindi il DB non sta caricando quattro stringhe in croce con qualche FK, bensì un intero payload complesso).&lt;/p&gt;

&lt;p&gt;Sappiamo dalle ricerche di Google che &lt;strong&gt;oltre il 50% degli utenti abbandona una pagina che impiega più di tre secondi a caricare.&lt;/strong&gt; Sappiamo che &lt;strong&gt;la velocità è un fattore di ranking confermato&lt;/strong&gt;. Eppure abbiamo tutti almeno un sito, da qualche parte, che fa undici secondi. Il mio era uno di quelli.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cosa ho deciso di fare
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Non un redesign. Non una nuova grafica. Non un cambio di tecnologia.
&lt;/h3&gt;

&lt;p&gt;Volevo capire una cosa molto specifica: perché un sito relativamente semplice, scritto bene, riesce a essere così lento.&lt;/p&gt;

&lt;p&gt;Qualcuno prenderebbe che per tirchieria non voglio spendere 7 o 24 euro al mese. (In effetti sì, tantovale che compro una VPS e ho tutto).&lt;/p&gt;

&lt;p&gt;Ma non è solo questo il punto. &lt;strong&gt;Per me è diventata una sfida.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Voler ottimizzare un sistema che ha un database gratuito e un server con CPU 0.1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;È questo quello che fa venire lo stimolo di sfida e dire "Sono bravo, perché sono riuscito ad ottimizzare l'impossibile"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mi sono dato una regola. Niente intuizioni. Solo numeri.&lt;/p&gt;

&lt;p&gt;Ho aperto gli strumenti di sviluppo del browser, ho misurato ogni richiesta, ho calcolato quanto tempo passava a scaricare cosa. Ho fatto la stessa misura prima di toccare anche solo una riga di codice, e l'ho ripetuta dopo ogni intervento. Senza misura prima e dopo non si ottimizza: si tira a indovinare.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quello che ho trovato
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Tre colpevoli, ognuno indipendente.
&lt;/h3&gt;

&lt;p&gt;Il primo è il modo in cui il computer del server interpreta il codice. Per default, ogni richiesta ricomincia da zero come se fosse la prima della giornata. Esiste una scorciatoia che permette al server di ricordare il lavoro già fatto, ma è spenta nella configurazione standard. È un po' come avere un'auto e tenere il freno a mano tirato ad ogni semaforo verde.&lt;/p&gt;

&lt;p&gt;Il secondo riguarda come il sito chiedeva al database le informazioni da mostrare. Per costruire un menu con tre livelli di profondità, il sito faceva una domanda al database per ogni voce, poi una per ogni sotto-voce, poi una per ogni sotto-sotto-voce. Risultato: decine di domande dove sarebbe bastata una sola, ben formulata, all'inizio.&lt;/p&gt;

&lt;p&gt;Il terzo era il bagaglio del browser. Il sito caricava il codice di tutti i pulsanti, le icone, gli editor di testo che esistono nell'applicazione, anche se la pagina che stavi vedendo ne usava una decima parte. È come se andassi a fare la spesa portandoti dietro il barbecue, la moto del cuoco e l'intera collezione di pentole, ogni volta che esci di casa per prendere il latte.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tre problemi, tre interventi.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Cosa ho cambiato, raccontato in italiano
&lt;/h3&gt;

&lt;p&gt;Ho acceso la "memoria a breve termine" del server, ho implemtato &lt;strong&gt;un sistema di caching compesso&lt;/strong&gt;. La prima volta che il sito risponde a una richiesta, ricorda il lavoro fatto. Le richieste successive partono già al 60% del percorso.&lt;/p&gt;

&lt;p&gt;Ho ridotto il bagaglio del browser: il sito ora carica solo quello che serve alla pagina che stai vedendo, esattamente come quando entri in un'app sul telefono e si caricano solo le schermate che apri. In numeri, sono passato da 519 a 247 file caricati per visita. Più della metà in meno.&lt;/p&gt;

&lt;p&gt;E ho aggiunto piccole cose collaterali. Le immagini ora viaggiano in un formato moderno che pesa il 40% in meno a parità di qualità visibile. Il browser viene istruito a tenere in cache locale tutto quello che non cambia, così alla seconda visita di un utente molti file non vengono nemmeno richiesti al server.&lt;/p&gt;

&lt;p&gt;I risultati, senza retorica&lt;/p&gt;

&lt;p&gt;Prima: 11,5 secondi di caricamento. 519 richieste. 1,84 megabyte di traffico.&lt;/p&gt;

&lt;p&gt;Dopo: 4 secondi di caricamento. 247 richieste. 1,6 megabyte di traffico.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Il caricamento è sceso del 65%&lt;/em&gt;&lt;/strong&gt;. Le richieste del 52%. Sono numeri misurati su un articolo reale del blog, con il browser pulito da cache, in produzione. Non sono il "best case" da slide commerciale: sono la realtà di un visitatore qualsiasi.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quattro secondi non sono ancora il valore che voglio.&lt;/strong&gt; L'obiettivo è sotto il secondo e mezzo. Ma sono già un altro mondo rispetto a undici secondi, e l'effetto sul tasso di rimbalzo si vedrà nei prossimi trenta giorni di analytics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Perché un sito veloce non è una pignoleria tecnica
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Tre motivi, uno per ogni stakeholder.
&lt;/h3&gt;

&lt;p&gt;Per chi vende, il sito veloce è una promessa implicita: dice "questa azienda lavora con cura". Se hai due fornitori sulla stessa fascia di prezzo e uno carica in tre secondi e l'altro in dieci, su quale clicchi il pulsante "richiedi preventivo"?&lt;/p&gt;

&lt;p&gt;Per chi guarda le metriche di marketing, la velocità è una leva diretta su due numeri. Il primo è la posizione su Google: i Core Web Vitals, da anni, sono parte del ranking factor ufficiale. Un sito veloce sale, un sito lento scende. Il secondo è il tasso di conversione: ogni secondo guadagnato sui tempi di caricamento si traduce, sui dati pubblici di Amazon e Walmart, in qualche punto percentuale di vendite in più.&lt;/p&gt;

&lt;p&gt;Per chi gestisce l'infrastruttura, &lt;strong&gt;&lt;em&gt;ottimizzare significa anche pagare meno.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Server che lavorano meno, traffico che pesa meno, immagini che occupano meno spazio.
&lt;/h2&gt;

&lt;p&gt;È una linea di costo che non si vede sul P&amp;amp;L finché non la guardi, e quando la guardi capisci che potevi risparmiare.&lt;/p&gt;

&lt;p&gt;Il bottleneck che resta&lt;/p&gt;

&lt;p&gt;Onestà: dei 4 secondi attuali, circa 3 sono tempo che il server impiega a generare la risposta. Solo 1 secondo è effettivo download e visualizzazione. Significa che il prossimo round di ottimizzazione non passa più dal frontend: passa da capire perché il backend ci mette 3 secondi.&lt;/p&gt;

&lt;p&gt;Ho già installato gli strumenti per misurarlo. Quando avrò i numeri, scriverò il secondo episodio di questa cronaca, con prima e dopo, esattamente come questo.&lt;/p&gt;

&lt;p&gt;Cosa porti via da questo articolo&lt;/p&gt;

&lt;p&gt;Se la velocità del tuo sito non l'hai mai misurata, fallo oggi. Apri &lt;a href="http://pagespeed.web.dev" rel="noopener noreferrer"&gt;pagespeed.web.dev&lt;/a&gt;, incolla l'URL della home, leggi il punteggio. Se è verde, congratulazioni. Se è giallo o rosso, hai uno strumento concreto in mano: un punto di partenza misurabile, e una conversazione da aprire con chi gestisce il tuo sito.&lt;/p&gt;

&lt;p&gt;Se i numeri non ti piacciono e vuoi un audit indipendente che ti dica con onestà cosa si può migliorare, dove, e con quanto sforzo, scrivimi tramite il &lt;a href="https://iadicola.it/contatti" rel="noopener noreferrer"&gt;form contatti&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Lavoro per progetti su misura, partendo sempre dai numeri reali e mai dalle metriche di vanity.&lt;/p&gt;

&lt;p&gt;Il secondo episodio arriva quando avrò abbattuto i tre secondi di backend. Stay tuned.&lt;/p&gt;




&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://iadicola.it/articoli/da-11-a-4-secondi-come-ho-ottimizzato-la-velocita-di-un-sito-con-render-free-tier?utm_source=devto&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Leggi l'articolo completo su iadicola.it&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>database</category>
      <category>performance</category>
    </item>
    <item>
      <title>Event Sourcing: la storia completa del tuo sistema</title>
      <dc:creator>Dev-Iadicola</dc:creator>
      <pubDate>Mon, 06 Jul 2026 17:00:22 +0000</pubDate>
      <link>https://dev.to/dev_iadicola/event-sourcing-la-storia-completa-del-tuo-sistema-81m</link>
      <guid>https://dev.to/dev_iadicola/event-sourcing-la-storia-completa-del-tuo-sistema-81m</guid>
      <description>&lt;h2&gt;
  
  
  Il problema: lo stato corrente cancella la storia
&lt;/h2&gt;

&lt;p&gt;Un conto corrente bancario ha un saldo di 1.500 EUR. Questo e lo &lt;strong&gt;stato corrente&lt;/strong&gt;. Ma come ci e arrivato? Stipendio di 2.000, affitto di 800, spesa di 200, rimborso di 500. In un sistema tradizionale, il database contiene solo il saldo — la storia e persa. Se un'operazione e stata applicata per errore, non puoi ricostruire la sequenza. Se vuoi sapere qual era il saldo il 15 del mese scorso, devi averlo salvato esplicitamente.&lt;/p&gt;

&lt;p&gt;L'&lt;strong&gt;Event Sourcing&lt;/strong&gt; inverte il modello: invece di salvare lo stato corrente e aggiornarlo, salvi ogni &lt;strong&gt;evento&lt;/strong&gt; che ha modificato lo stato. Lo stato corrente si ricostruisce riproducendo (replaying) gli eventi in sequenza. Il saldo e il risultato di: &lt;code&gt;Deposited(2000) → Withdrawn(800) → Withdrawn(200) → Deposited(500) = 1500&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Come funziona: Event Store e Proiezioni
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Event Store
&lt;/h3&gt;

&lt;p&gt;Gli eventi vengono salvati in un &lt;strong&gt;event store&lt;/strong&gt; — una tabella append-only dove ogni riga e un evento immutabile con: ID, aggregate ID, tipo evento, payload (dati dell'evento), timestamp, versione. Gli eventi non vengono mai modificati o cancellati. Sono fatti storici: "e successo questo, in questo momento, con questi dati".&lt;/p&gt;

&lt;h3&gt;
  
  
  Proiezioni (Read Models)
&lt;/h3&gt;

&lt;p&gt;Lo stato corrente viene costruito da &lt;strong&gt;proiezioni&lt;/strong&gt;: funzioni che ascoltano gli eventi e aggiornano viste materializzate ottimizzate per la lettura. Una proiezione "saldo corrente" somma depositi e sottrae prelievi. Una proiezione "movimenti mensili" raggruppa gli eventi per mese. Una proiezione "clienti con saldo negativo" filtra e aggrega.&lt;/p&gt;

&lt;p&gt;Il potere delle proiezioni e che puoi &lt;strong&gt;crearle retroattivamente&lt;/strong&gt;. Se domani serve un report che non esisteva ieri, crei una nuova proiezione che riproduce tutti gli eventi storici e costruisce il report dall'inizio dei tempi. Con un database tradizionale, i dati storici sono persi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Esempio teorico: gestione ordini
&lt;/h2&gt;

&lt;p&gt;Un ordine e-commerce attraversa molti stati. Con Event Sourcing, ogni transizione e un evento:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OrderCreated { items: [...], customer_id: 42 }&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PaymentReceived { amount: 150.00, method: "card" }&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OrderShipped { tracking: "IT123456", carrier: "GLS" }&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OrderDelivered { signed_by: "Mario Rossi" }&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lo stato corrente dell'ordine si ricostruisce riproducendo gli eventi. Ma hai anche: audit trail completo (chi ha fatto cosa e quando), la possibilita di ricostruire lo stato a qualsiasi punto nel tempo, e proiezioni dedicate per dashboard, analytics e reporting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Event Sourcing + CQRS: la combinazione naturale
&lt;/h2&gt;

&lt;p&gt;Event Sourcing si combina naturalmente con CQRS: i Command scrivono eventi nell'event store. Le Query leggono dalle proiezioni. I due percorsi sono completamente separati e ottimizzati indipendentemente. Le proiezioni possono usare strutture dati diverse (tabelle SQL, documenti MongoDB, indici Elasticsearch) a seconda delle esigenze di lettura.&lt;/p&gt;

&lt;h2&gt;
  
  
  I costi reali
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Complessità&lt;/strong&gt;: il modello mentale e radicalmente diverso dal CRUD. Il team deve pensare in termini di eventi, non di stato.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eventual consistency&lt;/strong&gt;: le proiezioni non sono aggiornate istantaneamente. Tra la scrittura dell'evento e l'aggiornamento della proiezione c'e un ritardo (spesso millisecondi, ma non zero).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema evolution&lt;/strong&gt;: gli eventi sono immutabili. Se il formato di un evento cambia, servono strategie di versioning (upcasting).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage&lt;/strong&gt;: gli eventi si accumulano nel tempo. Un sistema con milioni di transazioni al giorno genera terabyte di eventi. Servono strategie di archiviazione e snapshot.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quando usare Event Sourcing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Usa Event Sourcing&lt;/strong&gt; quando l'audit trail completo e un requisito di business (finanza, sanita, legale)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa Event Sourcing&lt;/strong&gt; quando devi poter ricostruire lo stato a qualsiasi punto nel tempo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usa Event Sourcing&lt;/strong&gt; quando le proiezioni retroattive hanno valore di business&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non usare Event Sourcing&lt;/strong&gt; per CRUD semplici: il costo di complessità non si giustifica&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non usare Event Sourcing&lt;/strong&gt; se il team non ha esperienza con sistemi event-driven: la curva di apprendimento e ripida&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Event Sourcing non e un'architettura per tutti i progetti: e una strategia di persistenza per domini dove la &lt;strong&gt;storia&lt;/strong&gt; ha valore. Quando lo stato corrente non basta e serve sapere come ci sei arrivato, Event Sourcing trasforma il database da una fotografia a un film completo.&lt;/p&gt;




&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://iadicola.it/articoli/event-sourcing-storia-completa-del-tuo-sistema?utm_source=devto&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Leggi l'articolo completo su iadicola.it&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>eventsourcing</category>
      <category>proiezione</category>
    </item>
  </channel>
</rss>
