{"id":65304,"date":"2023-02-14T09:21:35","date_gmt":"2023-02-14T08:21:35","guid":{"rendered":"https:\/\/kinsta.com\/it\/?p=65304&#038;preview=true&#038;preview_id=65304"},"modified":"2023-03-02T10:21:21","modified_gmt":"2023-03-02T09:21:21","slug":"pattern-javascript-design","status":"publish","type":"post","link":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/","title":{"rendered":"Guida Completa ai Design Pattern di JavaScript"},"content":{"rendered":"<p>Quando si sviluppano applicazioni <a href=\"https:\/\/kinsta.com\/it\/blog\/cosa-e-javascript\/\">JavaScript<\/a>, si potrebbe aver bisogno di creare oggetti in un certo modo predefinito o di riutilizzare una classe modificandola o adattandola a diversi casi d&#8217;uso.<\/p>\n<p>Naturalmente non \u00e8 conveniente risolvere questi problemi pi\u00f9 volte.<\/p>\n<p>\u00c8 qui che i design pattern di JavaScript vengono in aiuto.<\/p>\n\n<p>I design pattern JavaScript vi forniscono un modo strutturato e ripetibile per affrontare i problemi pi\u00f9 comuni nello sviluppo di JavaScript.<\/p>\n<p>In questa guida vedremo cosa sono i design pattern JavaScript e come usarli nelle vostre applicazioni JavaScript.<div><\/div><kinsta-auto-toc heading=\"Table of Contents\" exclude=\"last\" list-style=\"arrow\" selector=\"h2\" count-number=\"-1\"><\/kinsta-auto-toc><\/p>\n<h2>Cos&#8217;\u00c8 un Design Pattern JavaScript?<\/h2>\n<p>I design pattern JavaScript sono soluzioni template ripetibili per i problemi pi\u00f9 frequenti nello sviluppo di applicazioni JavaScript.<\/p>\n<p>L&#8217;idea \u00e8 semplice: programmatrici e programmatori di tutto il mondo, fin dagli albori dello sviluppo, hanno affrontato una serie di problemi ricorrenti durante lo <a href=\"https:\/\/kinsta.com\/it\/blog\/application-developer\/\">sviluppo di applicazioni<\/a>. Nel corso del tempo, alcuni sviluppatori hanno scelto di documentare i modi collaudati per affrontare questi problemi, in modo che altri potessero fare riferimento alle soluzioni con facilit\u00e0.<\/p>\n<p>Man mano che un numero sempre maggiore di professionisti sceglieva di usare queste soluzioni e ne riconosceva l&#8217;efficacia, queste sono state accettate come modalit\u00e0 standard di risoluzione dei problemi e hanno preso il nome di &#8220;design pattern&#8221;.<\/p>\n<p>Man mano che l&#8217;importanza dei design pattern \u00e8 stata compresa, questi sono stati ulteriormente sviluppati e standardizzati. Oggi la maggior parte dei design pattern moderni ha una struttura definita, \u00e8 organizzata in pi\u00f9 categorie e viene insegnata nei corsi di laurea in informatica come argomento indipendente.<\/p>\n<h2>Tipi di Design Pattern JavaScript<\/h2>\n<p>Ecco alcune delle classificazioni pi\u00f9 popolari dei design pattern JavaScript.<\/p>\n<h3>Creativi<\/h3>\n<p>I design pattern creativi sono quelli che aiutano a risolvere i problemi legati alla creazione e alla gestione di nuove istanze di oggetti in JavaScript. Pu\u00f2 trattarsi di questioni semplici come limitare una classe a un solo oggetto o complesse come definire un metodo intricato per selezionare e aggiungere ogni caratteristica di un oggetto JavaScript.<\/p>\n<p>Alcuni esempi di design pattern creativi sono Singleton, Factory, Abstract Factory e Builder, tra gli altri.<\/p>\n<h3>Strutturali<\/h3>\n<p>I design pattern strutturali sono quelli che aiutano a risolvere i problemi di gestione della struttura (o schema) degli oggetti JavaScript. Questi problemi possono includere la creazione di una relazione tra due oggetti diversi o l&#8217;astrazione di alcune caratteristiche di un oggetto per utenti specifici.<\/p>\n<p>Alcuni esempi di design pattern strutturali sono Adapter, Bridge, Composite e Facade.<\/p>\n<h3>Comportamentali<\/h3>\n<p>I design pattern comportamentali sono quelli che aiutano a risolvere i problemi relativi al passaggio del controllo (e della responsabilit\u00e0) tra vari oggetti. Questi problemi possono riguardare il controllo dell&#8217;accesso a una lista collegata o la creazione di un&#8217;unica entit\u00e0 in grado di controllare l&#8217;accesso a pi\u00f9 tipi di oggetti.<\/p>\n<p>Alcuni esempi di design pattern comportamentali sono Command, Iterator, Memento e Observer.<\/p>\n<h3>Concurrency<\/h3>\n<p>I design pattern concurrency sono quelli che aiutano a risolvere i problemi legati al multi-threading e al multitasking. Questi problemi possono riguardare il mantenimento di un oggetto attivo tra pi\u00f9 oggetti disponibili o la gestione di eventi multipli forniti a un sistema, applicando un demultiplexing degli input in arrivo e gestendoli pezzo per pezzo.<\/p>\n<p>Alcuni esempi di design pattern concurrency sono gli oggetti attivi, il nuclear react e lo scheduler.<\/p>\n<h3>Architetturali<\/h3>\n<p>I design pattern architetturali sono quelli che aiutano a risolvere i problemi di <a href=\"https:\/\/kinsta.com\/it\/blog\/architettura-applicazioni-web\/\">progettazione del software<\/a> in senso lato. In genere sono legati a come progettare il sistema per garantire un&#8217;elevata disponibilit\u00e0, mitigare i rischi ed <a href=\"https:\/\/kinsta.com\/it\/blog\/monitoraggio-prestazioni-applicazioni\/\">evitare i colli di bottiglia delle prestazioni<\/a>.<\/p>\n<p>Due esempi di design pattern architetturali sono MVC e MVVM.<\/p>\n<h2>Elementi di un Design Pattern<\/h2>\n<p>Quasi tutti i design pattern possono essere suddivisi in un insieme di quattro importanti componenti. Essi sono:<\/p>\n<ul>\n<li><strong>Nome del pattern<\/strong>: si usa per identificare un design pattern durante la comunicazione con gli altri utenti. Alcuni esempi sono &#8220;singleton&#8221;, &#8220;prototype&#8221; e altri ancora.<\/li>\n<li><strong>Problema<\/strong>: descrive l&#8217;obiettivo del design pattern. Si tratta di una piccola descrizione del problema che il design pattern sta cercando di risolvere. Pu\u00f2 anche includere uno scenario di esempio per spiegare meglio il problema. Pu\u00f2 anche contenere un elenco di condizioni da soddisfare affinch\u00e9 il pattern risolva completamente il problema.<\/li>\n<li><strong>Soluzione<\/strong>: \u00e8 la soluzione al problema in questione, composta da elementi come classi, metodi, interfacce, ecc. \u00c8 la parte pi\u00f9 importante di un design pattern: comporta relazioni, responsabilit\u00e0 e collaboratori di vari elementi che sono chiaramente definiti.<\/li>\n<li><strong>Risultati<\/strong>: si tratta di un&#8217;analisi di quanto il pattern sia stato in grado di risolvere il problema. Vengono discussi aspetti come l&#8217;utilizzo dello spazio e del tempo e gli approcci alternativi per risolvere lo stesso problema.<\/li>\n<\/ul>\n<p>Se volete saperne di pi\u00f9 sui design pattern e sulla loro nascita, la MSU offre del <a href=\"https:\/\/www.cse.msu.edu\/~cse870\/Lectures\/SS2005\/08-design-patterns.ppt\">materiale di studio sintetico<\/a> a cui fare riferimento.<\/p>\n<h2>Perch\u00e9 Usare i Design Pattern?<\/h2>\n<p>I motivi per cui dovresti usare i design pattern sono molteplici:<\/p>\n<ul>\n<li><strong>Sono collaudati e testati<\/strong>: con un design pattern, avete una soluzione collaudata al vostro problema (a patto che il design pattern corrisponda alla descrizione del problema). Non dovete perdere tempo a cercare soluzioni alternative e potete essere certi di avere una soluzione che si occupa dell&#8217;ottimizzazione delle prestazioni di base.<\/li>\n<li><strong>Sono facili da capire<\/strong>: i design pattern sono pensati per essere piccoli, semplici e facili da capire. Non dovete avere un\u2019esperienza decennale in un settore specifico per capire quale design pattern usare. Sono volutamente generici (non sono limitati a un particolare linguaggio di programmazione) e possono essere compresi da chiunque abbia sufficienti capacit\u00e0 di risoluzione dei problemi. Questo \u00e8 utile anche quando c&#8217;\u00e8 un cambio di guardia nel vostro team tecnico: un frammento di codice che si basa su un design pattern \u00e8 pi\u00f9 facile da capire per chiunque stia iniziando nel settore dello sviluppo software.<\/li>\n<\/ul>\n<ul>\n<li><strong>Sono semplici da implementare<\/strong>: la maggior parte dei design pattern sono molto semplici, come vedrete pi\u00f9 avanti nel nostro articolo. Non \u00e8 necessario conoscere molti <a href=\"https:\/\/kinsta.com\/it\/blog\/programmazione-orientata-agli-oggetti-python\/\">concetti di programmazione<\/a> per implementarli nel vostro codice.<\/li>\n<\/ul>\n<ul>\n<li><strong>Propongono un&#8217;architettura del codice facilmente riutilizzabile<\/strong>: la riusabilit\u00e0 e la <a href=\"https:\/\/kinsta.com\/it\/blog\/best-practice-html\/\">pulizia del codice sono molto incoraggiate<\/a> nell&#8217;industria tecnologica e i design pattern possono aiutarvi a raggiungere questo obiettivo. Poich\u00e9 questi schemi rappresentano un modo standard di risolvere i problemi, i loro progettisti si sono preoccupati di garantire che l&#8217;architettura dell&#8217;app rimanga riutilizzabile, flessibile e compatibile con la maggior parte delle forme di scrittura del codice.<\/li>\n<\/ul>\n<ul>\n<li><strong>Risparmiano tempo e dimensioni dell&#8217;app<\/strong>: uno dei maggiori vantaggi di affidarsi a un insieme di soluzioni standard \u00e8 che vi aiutano a risparmiare tempo durante l&#8217;implementazione. \u00c8 molto probabile che tutto il vostro team di sviluppo conosca bene i design pattern, quindi sar\u00e0 pi\u00f9 facile per loro <a href=\"https:\/\/kinsta.com\/it\/blog\/microsoft-teams-contro-slack\/\">pianificare, comunicare e collaborare<\/a> durante l&#8217;implementazione. Le soluzioni sperimentate e testate significano che \u00e8 molto probabile che non perderete risorse o che non farete una deviazione durante la creazione di alcune funzionalit\u00e0, risparmiando tempo e spazio. Inoltre, la maggior parte dei <a href=\"https:\/\/kinsta.com\/it\/blog\/miglior-linguaggio-di-programmazione\/\">linguaggi di programmazione<\/a> offre librerie di template standard che implementano gi\u00e0 alcuni design pattern comuni come Iterator e Observer.<\/li>\n<\/ul>\n<h2>I 20 Migliori Design Pattern JavaScript da Padroneggiare<\/h2>\n<p>Ora che avete capito in cosa consiste un design pattern e perch\u00e9 ne avete bisogno, approfondiamo il modo in cui alcuni dei design pattern JavaScript pi\u00f9 utilizzati possono essere implementati in un&#8217;<a href=\"https:\/\/kinsta.com\/it\/blog\/app-node-js\/\">applicazione JavaScript<\/a>.<\/p>\n<h3>Creativi<\/h3>\n<p>Iniziamo la discussione con alcuni design pattern fondamentali e facili da imparare.<\/p>\n<h4>1. Singleton<\/h4>\n<p>Il pattern Singleton \u00e8 uno dei design pattern pi\u00f9 utilizzati nel settore dello sviluppo software. Il problema che si propone di risolvere \u00e8 quello di mantenere una sola istanza di una classe. Questo pu\u00f2 essere utile quando si istanziano oggetti che richiedono molte risorse, come i gestori (handler) di database.<\/p>\n<p>Ecco come potete implementarlo in JavaScript:<\/p>\n<pre><code class=\"language-js\">function SingletonFoo() {\n\n   let fooInstance = null;\n\n   \/\/ For our reference, let's create a counter that will track the number of active instances\n   let count = 0;\n\n   function printCount() {\n   \tconsole.log(\"Number of instances: \" + count);\n   }\n\n   function init() {\n   \t\/\/ For our reference, we'll increase the count by one whenever init() is called\n   \tcount++;\n\n   \t\/\/ Do the initialization of the resource-intensive object here and return it\n   \treturn {}\n   }\n\n   function createInstance() {\n   \tif (fooInstance == null) {\n       \tfooInstance = init();\n   \t}\n   \treturn fooInstance;\n   }\n\n   function closeInstance() {\n   \tcount--;\n   \tfooInstance = null;\n   }\n\n   return {\n   \tinitialize: createInstance,\n   \tclose: closeInstance,\n   \tprintCount: printCount\n   }\n}\n\nlet foo = SingletonFoo();\n\nfoo.printCount() \/\/ Prints 0\nfoo.initialize()\nfoo.printCount() \/\/ Prints 1\nfoo.initialize()\nfoo.printCount() \/\/ Still prints 1\nfoo.initialize()\nfoo.printCount() \/\/ Still 1\nfoo.close()\nfoo.printCount() \/\/ Prints 0<\/code><\/pre>\n<p>Sebbene serva allo scopo, lo schema Singleton \u00e8 noto per complicare il debugging, poich\u00e9 maschera le dipendenze e controlla l&#8217;accesso all&#8217;inizializzazione o alla distruzione delle istanze di una classe.<\/p>\n<h4>2. Factory<\/h4>\n<p>Anche il metodo Factory \u00e8 uno dei design pattern pi\u00f9 popolari. Il problema che il metodo Factory mira a risolvere \u00e8 la creazione di oggetti senza utilizzare il costruttore convenzionale. Al contrario, il metodo accetta la configurazione (o descrizione) dell&#8217;oggetto che si desidera e restituisce l&#8217;oggetto appena creato.<\/p>\n<p>Ecco come potete implementarlo in JavaScript:<\/p>\n<pre><code class=\"language-js\">function Factory() {\n   this.createDog = function (breed) {\n   \tlet dog;\n\n   \tif (breed === \"labrador\") {\n       \tdog = new Labrador();\n   \t} else if (breed === \"bulldog\") {\n       \tdog = new Bulldog();\n   \t} else if (breed === \"golden retriever\") {\n       \tdog = new GoldenRetriever();\n   \t} else if (breed === \"german shepherd\") {\n       \tdog = new GermanShepherd();\n   \t}\n\n   \tdog.breed = breed;\n   \tdog.printInfo = function () {\n       \tconsole.log(\"nnBreed: \" + dog.breed + \"nShedding Level (out of 5): \" + dog.sheddingLevel + \"nCoat Length: \" + dog.coatLength + \"nCoat Type: \" + dog.coatType)\n   \t}\n\n   \treturn dog;\n   }\n}\n\nfunction Labrador() {\n   this.sheddingLevel = 4\n   this.coatLength = \"short\"\n   this.coatType = \"double\"\n}\n\nfunction Bulldog() {\n   this.sheddingLevel = 3\n   this.coatLength = \"short\"\n   this.coatType = \"smooth\"\n}\n\nfunction GoldenRetriever() {\n   this.sheddingLevel = 4\n   this.coatLength = \"medium\"\n   this.coatType = \"double\"\n}\n\nfunction GermanShepherd() {\n   this.sheddingLevel = 4\n   this.coatLength = \"medium\"\n   this.coatType = \"double\"\n}\n\nfunction run() {\n\n   let dogs = [];\n   let factory = new Factory();\n\n   dogs.push(factory.createDog(\"labrador\"));\n   dogs.push(factory.createDog(\"bulldog\"));\n   dogs.push(factory.createDog(\"golden retriever\"));\n   dogs.push(factory.createDog(\"german shepherd\"));\n\n   for (var i = 0, len = dogs.length; i &lt; len; i++) {\n   \tdogs[i].printInfo();\n   }\n}\n\nrun()\n\n\/**\nOutput:\n\nBreed: labrador\nShedding Level (out of 5): 4\nCoat Length: short\nCoat Type: double\n\n\nBreed: bulldog\nShedding Level (out of 5): 3\nCoat Length: short\nCoat Type: smooth\n\n\nBreed: golden retriever\nShedding Level (out of 5): 4\nCoat Length: medium\nCoat Type: double\n\n\nBreed: german shepherd\nShedding Level (out of 5): 4\nCoat Length: medium\nCoat Type: double\n*\/<\/code><\/pre>\n<p>Il design pattern Factory controlla il modo in cui gli oggetti verranno creati e vi fornisce un modo rapido per creare nuovi oggetti, oltre a un&#8217;interfaccia uniforme che definisce le propriet\u00e0 che gli oggetti avranno. Potete aggiungere tutte le razze di cani che volete, ma finch\u00e9 i metodi e le propriet\u00e0 esposti dai tipi di razza rimangono gli stessi, funzioneranno perfettamente.<\/p>\n<p>Tuttavia, tenete presente che il pattern Factory pu\u00f2 spesso portare a un gran numero di classi che possono essere difficili da gestire.<\/p>\n<h4>3. Abstract Factory<\/h4>\n<p>Il metodo Abstract Factory porta il metodo Factory a un livello superiore, rendendo le factory astratte e quindi sostituibili senza che l&#8217;ambiente chiamante conosca l&#8217;esatta factory utilizzata o il suo funzionamento interno. L&#8217;ambiente chiamante sa solo che tutte le factory hanno un insieme di metodi comuni che pu\u00f2 chiamare per eseguire l&#8217;azione di istanziazione.<\/p>\n<p>Ecco come pu\u00f2 essere implementato l&#8217;esempio precedente:<\/p>\n<pre><code class=\"language-js\">\/\/ A factory to create dogs\nfunction DogFactory() {\n   \/\/ Notice that the create function is now createPet instead of createDog, since we need\n   \/\/ it to be uniform across the other factories that will be used with this\n   this.createPet = function (breed) {\n   \tlet dog;\n\n   \tif (breed === \"labrador\") {\n       \tdog = new Labrador();\n   \t} else if (breed === \"pug\") {\n       \tdog = new Pug();\n   \t}\n\n   \tdog.breed = breed;\n   \tdog.printInfo = function () {\n       \tconsole.log(\"nnType: \" + dog.type + \"nBreed: \" + dog.breed + \"nSize: \" + dog.size)\n   \t}\n\n   \treturn dog;\n   }\n}\n\n\/\/ A factory to create cats\nfunction CatFactory() {\n   this.createPet = function (breed) {\n   \tlet cat;\n\n   \tif (breed === \"ragdoll\") {\n       \tcat = new Ragdoll();\n   \t} else if (breed === \"singapura\") {\n       \tcat = new Singapura();\n   \t}\n\n   \tcat.breed = breed;\n   \tcat.printInfo = function () {\n       \tconsole.log(\"nnType: \" + cat.type + \"nBreed: \" + cat.breed + \"nSize: \" + cat.size)\n   \t}\n\n   \treturn cat;\n   }\n}\n\n\/\/ Dog and cat breed definitions\nfunction Labrador() {\n   this.type = \"dog\"\n   this.size = \"large\"\n}\n\nfunction Pug() {\n   this.type = \"dog\"\n   this.size = \"small\"\n}\n\nfunction Ragdoll() {\n   this.type = \"cat\"\n   this.size = \"large\"\n}\n\nfunction Singapura() {\n   this.type = \"cat\"\n   this.size = \"small\"\n}\n\nfunction run() {\n\n   let pets = [];\n\n   \/\/ Initialize the two factories\n   let catFactory = new CatFactory();\n   let dogFactory = new DogFactory();\n\n   \/\/ Create a common petFactory that can produce both cats and dogs\n   \/\/ Set it to produce dogs first\n   let petFactory = dogFactory;\n\n   pets.push(petFactory.createPet(\"labrador\"));\n   pets.push(petFactory.createPet(\"pug\"));\n\n   \/\/ Set the petFactory to produce cats\n   petFactory = catFactory;\n\n   pets.push(petFactory.createPet(\"ragdoll\"));\n   pets.push(petFactory.createPet(\"singapura\"));\n\n   for (var i = 0, len = pets.length; i &lt; len; i++) {\n   \tpets[i].printInfo();\n   }\n}\n\nrun()\n\n\/**\nOutput:\n\nType: dog\nBreed: labrador\nSize: large\n\n\nType: dog\nBreed: pug\nSize: small\n\n\nType: cat\nBreed: ragdoll\nSize: large\n\n\nType: cat\nBreed: singapura\nSize: small\n\n*\/<\/code><\/pre>\n<p>Il pattern Abstract Factory consente di scambiare facilmente le factory concrete e aiuta a promuovere l&#8217;uniformit\u00e0 tra le factory e i prodotti creati. Tuttavia, pu\u00f2 diventare difficile introdurre nuovi tipi di prodotti, poich\u00e9 \u00e8 necessario apportare modifiche a pi\u00f9 classi per inserire nuovi metodi\/propriet\u00e0.<\/p>\n<h4>4. Builder<\/h4>\n<p>Il modello Builder \u00e8 uno dei design pattern JavaScript creativi pi\u00f9 complessi ma flessibili. Vi permette di costruire una per una tutte le caratteristiche del vostro prodotto, offrendovi il pieno controllo su come viene costruito il vostro oggetto, pur astraendo dai dettagli interni.<\/p>\n<p>Nell&#8217;intricato esempio che segue, vedrete il design pattern Builder in azione insieme a Director che vi aiuter\u00e0 a preparare le pizze!<\/p>\n<pre><code class=\"language-js\">\/\/ Here's the PizzaBuilder (you can also call it the chef)\nfunction PizzaBuilder() {\n   let base\n   let sauce\n   let cheese\n   let toppings = []\n\n   \/\/ The definition of pizza is hidden from the customers\n   function Pizza(base, sauce, cheese, toppings) {\n   \tthis.base = base\n   \tthis.sauce = sauce\n   \tthis.cheese = cheese\n   \tthis.toppings = toppings\n\n   \tthis.printInfo = function() {\n       \tconsole.log(\"This pizza has \" + this.base + \" base with \" + this.sauce + \" sauce \"\n       \t+ (this.cheese !== undefined ? \"with cheese. \" : \"without cheese. \")\n       \t+ (this.toppings.length !== 0 ? \"It has the following toppings: \" + toppings.toString() : \"\"))\n   \t}\n   }\n\n   \/\/ You can request the PizzaBuilder (\/chef) to perform any of the following actions on your pizza\n   return {\n   \taddFlatbreadBase: function() {\n       \tbase = \"flatbread\"\n       \treturn this;\n   \t},\n   \taddTomatoSauce: function() {\n       \tsauce = \"tomato\"\n       \treturn this;\n   \t},\n   \taddAlfredoSauce: function() {\n       \tsauce = \"alfredo\"\n       \treturn this;\n   \t},\n   \taddCheese: function() {\n       \tcheese = \"parmesan\"\n       \treturn this;\n   \t},\n   \taddOlives: function() {\n       \ttoppings.push(\"olives\")\n       \treturn this\n   \t},\n   \taddJalapeno: function() {\n       \ttoppings.push(\"jalapeno\")\n       \treturn this\n   \t},\n   \tcook: function() {\n       \tif (base === null){\n           \tconsole.log(\"Can't make a pizza without a base\")\n           \treturn\n       \t}\n       \treturn new Pizza(base, sauce, cheese, toppings)\n   \t}\n   }\n\n}\n\n\/\/ This is the Director for the PizzaBuilder, aka the PizzaShop.\n\/\/ It contains a list of preset steps that can be used to prepare common pizzas (aka recipes!)\nfunction PizzaShop() {\n   return {\n   \tmakePizzaMargherita: function() {\n       \tpizzaBuilder = new PizzaBuilder()\n       \tpizzaMargherita = pizzaBuilder.addFlatbreadBase().addTomatoSauce().addCheese().addOlives().cook()\n       \treturn pizzaMargherita\n   \t},\n   \tmakePizzaAlfredo: function() {\n       \tpizzaBuilder = new PizzaBuilder()\n       \tpizzaAlfredo = pizzaBuilder.addFlatbreadBase().addAlfredoSauce().addCheese().addJalapeno().cook()\n       \treturn pizzaAlfredo\n   \t},\n   \tmakePizzaMarinara: function() {\n       \tpizzaBuilder = new PizzaBuilder()\n       \tpizzaMarinara = pizzaBuilder.addFlatbreadBase().addTomatoSauce().addOlives().cook()\n       \treturn pizzaMarinara\n   \t}\n   }\n}\n\n\/\/ Here's where the customer can request pizzas from\nfunction run() {\n\n   let pizzaShop = new PizzaShop()\n\n   \/\/ You can ask for one of the popular pizza recipes...\n   let pizzaMargherita = pizzaShop.makePizzaMargherita()\n   pizzaMargherita.printInfo()\n   \/\/ Output: This pizza has flatbread base with tomato sauce with cheese. It has the following toppings: olives\n\n   let pizzaAlfredo = pizzaShop.makePizzaAlfredo()\n   pizzaAlfredo.printInfo()\n   \/\/ Output: This pizza has flatbread base with alfredo sauce with cheese. It has the following toppings: jalapeno\n\n   let pizzaMarinara = pizzaShop.makePizzaMarinara()\n   pizzaMarinara.printInfo()\n   \/\/ Output: This pizza has flatbread base with tomato sauce without cheese. It has the following toppings: olives\n\n   \/\/ Or send your custom request directly to the chef!\n   let chef = PizzaBuilder()\n   let customPizza = chef.addFlatbreadBase().addTomatoSauce().addCheese().addOlives().addJalapeno().cook()\n   customPizza.printInfo()\n   \/\/ Output: This pizza has flatbread base with tomato sauce with cheese. It has the following toppings: olives,jalapeno\n\n}\n\nrun()<\/code><\/pre>\n<p>Potete abbinare il Builder a un Director, come mostra la classe <code>PizzaShop<\/code> nell&#8217;esempio precedente, per predefinire una serie di passaggi da seguire ogni volta per costruire una variante standard del vostro prodotto, per esempio una ricetta specifica per le vostre pizze.<\/p>\n<p>L&#8217;unico problema di questo design pattern \u00e8 che \u00e8 piuttosto complesso da configurare e mantenere. Tuttavia, aggiungere nuove funzionalit\u00e0 in questo modo \u00e8 pi\u00f9 semplice rispetto al metodo Factory.<\/p>\n<h4>5. Prototype<\/h4>\n<p>Il design pattern Prototype \u00e8 un modo semplice e veloce per creare nuovi oggetti a partire da oggetti esistenti, clonandoli.<\/p>\n<p>Viene prima creato un oggetto prototipo che pu\u00f2 essere clonato pi\u00f9 volte per creare nuovi oggetti. \u00c8 utile quando l&#8217;istanziazione diretta di un oggetto \u00e8 un&#8217;operazione che richiede pi\u00f9 risorse rispetto alla creazione di una copia di un oggetto esistente.<\/p>\n<p>Nell&#8217;esempio che segue, vedrete come usare il pattern Prototype per creare nuovi documenti basati su un template di documento prestabilito:<\/p>\n<pre><code class=\"language-js\">\/\/ Defining how a document would look like\nfunction Document() {\n   this.header = \"Acme Co\"\n   this.footer = \"For internal use only\"\n   this.pages = 2\n   this.text = \"\"\n \n   this.addText = function(text) {\n   \tthis.text += text\n   }\n\n   \/\/ Method to help you see the contents of the object\n   this.printInfo = function() {\n   \tconsole.log(\"nnHeader: \" + this.header + \"nFooter: \" + this.footer + \"nPages: \" + this.pages + \"nText: \" + this.text)\n   }\n\n \n}\n\n\/\/ A protype (or template) for creating new blank documents with boilerplate information\nfunction DocumentPrototype(baseDocument) {\n   this.baseDocument = baseDocument\n \n   \/\/ This is where the magic happens. A new document object is created and is assigned the values of the current object\n   this.clone = function() {\n   \tlet document = new Document();\n\n   \tdocument.header = this.baseDocument.header\n   \tdocument.footer = this.baseDocument.footer\n   \tdocument.pages = this.baseDocument.pages\n   \tdocument.text = this.baseDocument.text\n\n   \treturn document\n   }\n}\n\nfunction run() {\n   \/\/ Create a document to use as the base for the prototype\n   let baseDocument = new Document()\n\n   \/\/ Make some changes to the prototype\n   baseDocument.addText(\"This text was added before cloning and will be common in both documents. \")\n\n   let prototype = new DocumentPrototype(baseDocument)\n\n   \/\/ Create two documents from the prototype\n   let doc1 = prototype.clone()\n   let doc2 = prototype.clone()\n\n   \/\/ Make some changes to both objects\n   doc1.pages = 3\n\n   doc1.addText(\"This is document 1\")\n   doc2.addText(\"This is document 2\")\n\n   \/\/ Print their values\n   doc1.printInfo()\n   \/* Output:\n   \tHeader: Acme Co\n   \tFooter: For internal use only\n   \tPages: 3\n   \tText: This text was added before cloning and will be common in both documents. This is document 1\n\t*\/\n\n   doc2.printInfo()\n   \/** Output:\n   \tHeader: Acme Co\n   \tFooter: For internal use only\n   \tPages: 2\n   \tText: This text was added before cloning and will be common in both documents. This is document 2\n\t*\/\n}\n\nrun()<\/code><\/pre>\n<p>Il metodo Prototype \u00e8 ottimo nei casi in cui gran parte degli oggetti condividono gli stessi valori o quando la creazione di un nuovo oggetto \u00e8 piuttosto costosa. Tuttavia, sembra eccessivo nei casi in cui non avete bisogno di pi\u00f9 di qualche istanza della classe.<\/p>\n<h3>Strutturali<\/h3>\n<p>I design pattern strutturali vi aiutano a organizzare la vostra logica di business fornendovi metodi collaudati di strutturare le classi. Esistono diversi design pattern strutturali che si adattano a casi d&#8217;uso specifici.<\/p>\n<h4>6. Adapter<\/h4>\n<p>Un problema comune nella creazione di applicazioni \u00e8 quello di consentire la collaborazione tra classi incompatibili.<\/p>\n<p>Un buon esempio per capire questo aspetto \u00e8 il mantenimento della compatibilit\u00e0 all&#8217;indietro. Se scrivete una nuova versione di una classe, \u00e8 naturale volere che sia facilmente utilizzabile in tutti i punti in cui funzionava la vecchia versione. Tuttavia, se apportate delle modifiche di rottura, come la rimozione o l&#8217;aggiornamento di metodi che erano fondamentali per il funzionamento della vecchia versione, potreste ritrovarvi con una classe che necessita dell&#8217;aggiornamento di tutti i suoi client per poter essere eseguita.<\/p>\n<p>In questi casi, il design pattern Adapter pu\u00f2 essere d&#8217;aiuto.<\/p>\n<p>Il design pattern Adapter fornisce un&#8217;astrazione che colma il divario tra i metodi e le propriet\u00e0 della nuova classe e i metodi e le propriet\u00e0 della vecchia classe. Ha la stessa interfaccia della vecchia classe, ma contiene la logica per mappare i vecchi metodi con quelli nuovi per eseguire operazioni simili. \u00c8 simile al modo in cui una presa di corrente funge da adattatore tra una spina di tipo americano e una di tipo europeo.<\/p>\n<p>Ecco un esempio:<\/p>\n<pre><code class=\"language-js\">\/\/ Old bot\nfunction Robot() {\n\n   this.walk = function(numberOfSteps) {\n   \t\/\/ code to make the robot walk\n   \tconsole.log(\"walked \" + numberOfSteps + \" steps\")\n   }\n\n   this.sit = function() {\n   \t\/\/ code to make the robot sit\n   \tconsole.log(\"sit\")\n   }\n\n}\n\n\/\/ New bot that does not have the walk function anymore\n\/\/ but instead has functions to control each step independently\nfunction AdvancedRobot(botName) {\n   \/\/ the new bot has a name as well\n   this.name = botName\n\n   this.sit = function() {\n   \t\/\/ code to make the robot sit\n   \tconsole.log(\"sit\")\n   }\n\n   this.rightStepForward = function() {\n   \t\/\/ code to take 1 step from right leg forward\n   \tconsole.log(\"right step forward\")\n   }\n\n   this.leftStepForward = function () {\n   \t\/\/ code to take 1 step from left leg forward\n   \tconsole.log(\"left step forward\")\n   }\n}\n\nfunction RobotAdapter(botName) {\n   \/\/ No references to the old interfact since that is usually\n   \/\/ phased out of development\n   const robot = new AdvancedRobot(botName)\n\n   \/\/ The adapter defines the walk function by using the\n   \/\/ two step controls. You now have room to choose which leg to begin\/end with,\n   \/\/ and do something at each step.\n   this.walk = function(numberOfSteps) {\n   \tfor (let i=0; i&lt;numberOfSteps; i++) {\n     \t \n       \tif (i % 2 === 0) {\n           \trobot.rightStepForward()\n       \t} else {\n           \trobot.leftStepForward()\n       \t}\n   \t}\n   }\n\n   this.sit = robot.sit\n\n}\n\nfunction run() {\n\n   let robot = new Robot()\n\n   robot.sit()\n   \/\/ Output: sit\n   robot.walk(5)\n   \/\/ Output: walked 5 steps\n\n   robot = new RobotAdapter(\"my bot\")\n\n   robot.sit()\n   \/\/ Output: sit\n   robot.walk(5)\n   \/\/ Output:\n   \/\/ right step forward\n   \/\/ left step forward\n   \/\/ right step forward\n   \/\/ left step forward\n   \/\/ right step forward\n\n}\n\nrun()<\/code><\/pre>\n<p>Il problema principale di questo design pattern \u00e8 che aggiunge complessit\u00e0 al vostro codice sorgente. Dovevate gi\u00e0 gestire due classi diverse e ora avete un&#8217;altra classe, l\u2019adapter, da gestire.<\/p>\n<h4>7. Bridge<\/h4>\n<p>Espandendo il pattern Adapter, il pattern Bridge fornisce sia alla classe che al client interfacce separate in modo che entrambi possano funzionare anche in caso di interfacce native incompatibili.<\/p>\n<p>Aiuta a sviluppare un&#8217;interfaccia molto libera tra i due tipi di oggetti. Questo aiuta anche a migliorare l&#8217;estensibilit\u00e0 delle interfacce e delle loro implementazioni per ottenere la massima flessibilit\u00e0.<\/p>\n<p>Ecco come potete usarlo:<\/p>\n<pre><code class=\"language-js\">\/\/ The TV and speaker share the same interface\nfunction TV() {\n   this.increaseVolume = function() {\n   \t\/\/ logic to increase TV volume\n   }\n\n   this.decreaseVolume = function() {\n   \t\/\/ logic to decrease TV volume\n   }\n\n   this.mute = function() {\n   \t\/\/ logic to mute TV audio\n   }\n}\n\nfunction Speaker() {\n   this.increaseVolume = function() {\n   \t\/\/ logic to increase speaker volume\n   }\n\n   this.decreaseVolume = function() {\n   \t\/\/ logic to decrease speaker volume\n   }\n\n   this.mute() = function() {\n   \t\/\/ logic to mute speaker audio\n   }\n}\n\n\/\/ The two remotes make use of the same common interface\n\/\/ that supports volume up and volume down features\nfunction SimpleRemote(device) {\n   this.pressVolumeDownKey = function() {\n   \tdevice.decreaseVolume()\n   }\n\n   this.pressVolumeUpKey = function() {\n   \tdevice.increaseVolume()\n   }\n}\n\nfunction AdvancedRemote(device) {\n\n   this.pressVolumeDownKey = function() {\n   \tdevice.decreaseVolume()\n   }\n\n   this.pressVolumeUpKey = function() {\n   \tdevice.increaseVolume()\n   }\n\n   this.pressMuteKey = function() {\n   \tdevice.mute()\n   }\n}\n\nfunction run() {\n\n   let tv = new TV()\n   let speaker = new Speaker()\n\n   let tvSimpleRemote = new SimpleRemote(tv)\n   let tvAdvancedRemote = new AdvancedRemote(tv)\n\n   let speakerSimpleRemote = new SimpleRemote(speaker)\n   let speakerAdvancedRemote = new AdvancedRemote(speaker)\n\n   \/\/ The methods listed in pair below will have the same effect\n   \/\/ on their target devices\n   tvSimpleRemote.pressVolumeDownKey()\n   tvAdvancedRemote.pressVolumeDownKey()\n\n   tvSimpleRemote.pressVolumeUpKey()\n   tvAdvancedRemote.pressVolumeUpKey()\n\n   \/\/ The advanced remote has additional functionality\n   tvAdvancedRemote.pressMuteKey()\n\n   speakerSimpleRemote.pressVolumeDownKey()\n   speakerAdvancedRemote.pressVolumeDownKey()\n\n   speakerSimpleRemote.pressVolumeUpKey()\n   speakerAdvancedRemote.pressVolumeUpKey()\n\n   speakerAdvancedRemote.pressMuteKey()\n}<\/code><\/pre>\n<p>Come avrete gi\u00e0 intuito, il pattern Bridge aumenta notevolmente la complessit\u00e0 della codebase. Inoltre, la maggior parte delle interfacce finisce per avere una sola implementazione nei casi d&#8217;uso reali, per cui la riusabilit\u00e0 del codice non \u00e8 molto vantaggiosa.<\/p>\n<h4>8. Composite<\/h4>\n<p>Il design pattern Composite vi aiuta a strutturare e gestire facilmente oggetti ed entit\u00e0 simili. L&#8217;idea di base del pattern Composite \u00e8 che gli oggetti e i loro contenitori logici possono essere rappresentati utilizzando un&#8217;unica classe astratta (che pu\u00f2 memorizzare dati\/metodi relativi all&#8217;oggetto e riferimenti a se stessa per il contenitore).<\/p>\n<p>L&#8217;utilizzo del pattern Composite \u00e8 pi\u00f9 sensato quando il vostro modello di dati assomiglia a una struttura ad albero. Tuttavia, non dovreste cercare di trasformare un modello di dati non ad albero in un modello di dati ad albero solo per il gusto di usare il pattern Composite, perch\u00e9 cos\u00ec facendo spesso si perde molta flessibilit\u00e0.<\/p>\n<p>Nell&#8217;esempio che segue, vedrete come utilizzare il design pattern Composite per costruire un sistema di imballaggio per i prodotti di un ecommerce che pu\u00f2 anche calcolare il valore totale dell&#8217;ordine per ogni confezione:<\/p>\n<pre><code class=\"language-js\">\/\/ A product class, that acts as a Leaf node\nfunction Product(name, price) {\n   this.name = name\n   this.price = price\n\n   this.getTotalPrice = function() {\n   \treturn this.price\n   }\n}\n\n\/\/ A box class, that acts as a parent\/child node\nfunction Box(name) {\n   this.contents = []\n   this.name = name\n\n   \/\/ Helper function to add an item to the box\n   this.add = function(content){\n   \tthis.contents.push(content)\n   }\n\n   \/\/ Helper function to remove an item from the box\n   this.remove = function() {\n   \tvar length = this.contents.length;\n   \tfor (var i = 0; i &lt; length; i++) {\n       \tif (this.contents[i] === child) {\n           \tthis.contents.splice(i, 1);\n           \treturn;\n       \t}\n   \t}\n   }\n\n   \/\/ Helper function to get one item from the box\n   this.getContent = function(position) {\n   \treturn this.contents[position]\n   }\n\n   \/\/ Helper function to get the total count of the items in the box\n   this.getTotalCount = function() {\n   \treturn this.contents.length\n   }\n\n   \/\/ Helper function to calculate the total price of all items in the box\n   this.getTotalPrice = function() {\n   \tlet totalPrice = 0;\n\n   \tfor (let i=0; i &lt; this.getTotalCount(); i++){\n       \ttotalPrice += this.getContent(i).getTotalPrice()\n   \t}\n\n   \treturn totalPrice\n   }\n}\n\nfunction run() {\n\n   \/\/ Let's create some electronics\n   const mobilePhone = new Product(\"mobile phone,\" 1000)\n   const phoneCase = new Product(\"phone case,\" 30)\n   const screenProtector = new Product(\"screen protector,\" 20)\n\n   \/\/ and some stationery products\n   const pen = new Product(\"pen,\" 2)\n   const pencil = new Product(\"pencil,\" 0.5)\n   const eraser = new Product(\"eraser,\" 0.5)\n   const stickyNotes = new Product(\"sticky notes,\" 10)\n\n   \/\/ and put them in separate boxes\n   const electronicsBox = new Box(\"electronics\")\n   electronicsBox.add(mobilePhone)\n   electronicsBox.add(phoneCase)\n   electronicsBox.add(screenProtector)\n \n   const stationeryBox = new Box(\"stationery\")\n   stationeryBox.add(pen)\n   stationeryBox.add(pencil)\n   stationeryBox.add(eraser)\n   stationeryBox.add(stickyNotes)\n\n   \/\/ and finally, put them into one big box for convenient shipping\n   const package = new Box('package')\n   package.add(electronicsBox)\n   package.add(stationeryBox)\n\n   \/\/ Here's an easy way to calculate the total order value\n   console.log(\"Total order price: USD \" + package.getTotalPrice())\n   \/\/ Output: USD 1063\n}\n\nrun()<\/code><\/pre>\n<p>L&#8217;aspetto pi\u00f9 negativo dell&#8217;utilizzo del pattern Composite \u00e8 che le modifiche alle interfacce dei componenti possono farsi molto impegnative in futuro. La progettazione delle interfacce richiede tempo e fatica e la natura ad albero del modello di dati pu\u00f2 rendere molto difficile apportare modifiche a piacimento.<\/p>\n<h4>9. Decorator<\/h4>\n<p>Il pattern Decorator vi aiuta ad aggiungere nuove funzionalit\u00e0 agli oggetti esistenti semplicemente avvolgendole all&#8217;interno di un nuovo oggetto. \u00c8 simile al modo in cui potete avvolgere un pacco regalo gi\u00e0 confezionato con nuova carta da regalo tutte le volte che volete: ogni impacchettamento vi permette di aggiungere tutte le funzionalit\u00e0 che desiderate, quindi \u00e8 un&#8217;ottima soluzione in termini di flessibilit\u00e0.<\/p>\n<p>Da un punto di vista tecnico, non \u00e8 prevista l&#8217;ereditariet\u00e0, quindi c&#8217;\u00e8 una maggiore libert\u00e0 nella progettazione della logica aziendale.<\/p>\n<p>Nell&#8217;esempio che segue, vedrete come il pattern Decorator vi aiuta ad aggiungere altre funzionalit\u00e0 a una classe standard <code>Customer<\/code>:<\/p>\n<pre><code class=\"language-js\">function Customer(name, age) {\n   this.name = name\n   this.age = age\n\n   this.printInfo = function() {\n   \tconsole.log(\"Customer:nName : \" + this.name + \" | Age: \" + this.age)\n   }\n}\n\nfunction DecoratedCustomer(customer, location) {\n   this.customer = customer\n   this.name = customer.name\n   this.age = customer.age\n   this.location = location\n\n   this.printInfo = function() {\n   \tconsole.log(\"Decorated Customer:nName: \" + this.name + \" | Age: \" + this.age + \" | Location: \" + this.location)\n   }\n}\n\nfunction run() {\n   let customer = new Customer(\"John,\" 25)\n   customer.printInfo()\n   \/\/ Output:\n   \/\/ Customer:\n   \/\/ Name : John | Age: 25\n\n   let decoratedCustomer = new DecoratedCustomer(customer, \"FL\")\n   decoratedCustomer.printInfo()\n   \/\/ Output:\n   \/\/ Customer:\n   \/\/ Name : John | Age: 25 | Location: FL\n}\n\nrun()<\/code><\/pre>\n<p>Gli svantaggi di questo pattern includono un&#8217;elevata complessit\u00e0 del codice, poich\u00e9 non esiste uno schema standard definito per aggiungere nuove funzionalit\u00e0 utilizzando i decorator. Alla fine del ciclo di vita del software potreste ritrovarvi con molti decorator non uniformi e\/o simili.<\/p>\n<p>Se non fate attenzione durante la progettazione dei decorator, potreste finire per progettare alcuni decorator in modo che siano logicamente dipendenti da altri. Se non si risolve questo problema, la rimozione o la ristrutturazione dei decorator in un secondo momento pu\u00f2 compromettere la stabilit\u00e0 dell&#8217;applicazione.<\/p>\n<h4>10. Facade<\/h4>\n<p>Quando si costruisce la maggior parte delle applicazioni del mondo reale, la logica di business risulta di solito piuttosto complessa. Potreste ritrovarvi con pi\u00f9 oggetti e metodi coinvolti nell&#8217;esecuzione delle operazioni principali della vostra applicazione. Tenere traccia delle loro inizializzazioni, delle dipendenze, dell&#8217;ordine corretto di esecuzione dei metodi e cos\u00ec via, pu\u00f2 essere piuttosto complicato e soggetto a errori se non viene fatto correttamente.<\/p>\n<p>Il design pattern Facade vi aiuta a creare un&#8217;astrazione tra l&#8217;ambiente che invoca le operazioni di cui sopra e gli oggetti e i metodi coinvolti nel completamento di tali operazioni. Questa astrazione ospita la logica per inizializzare gli oggetti, tracciare le loro dipendenze e altre attivit\u00e0 importanti. L&#8217;ambiente chiamante non ha informazioni su come viene eseguita un&#8217;operazione. Potete aggiornare liberamente la logica senza apportare modifiche al client chiamante.<\/p>\n<p>Ecco come potete utilizzarlo in un&#8217;applicazione:<\/p>\n<pre><code class=\"language-js\">\/**\n* Let's say you're trying to build an online store. It will have multiple components and\n* complex business logic. In the example below, you will find a tiny segment of an online\n* store composed together using the Facade design pattern. The various manager and helper\n* classes are defined first of all.\n*\/\n\n\nfunction CartManager() {\n   this.getItems = function() {\n   \t\/\/ logic to return items\n   \treturn []\n   }\n \n   this.clearCart = function() {\n   \t\/\/ logic to clear cart\n   }\n}\n\nfunction InvoiceManager() {\n   this.createInvoice = function(items) {\n   \t\/\/ logic to create invoice\n   \treturn {}\n   }\n\n   this.notifyCustomerOfFailure = function(invoice) {\n   \t\/\/ logic to notify customer\n   }\n\n   this.updateInvoicePaymentDetails = function(paymentResult) {\n   \t\/\/ logic to update invoice after payment attempt\n   }\n}\n\nfunction PaymentProcessor() {\n   this.processPayment = function(invoice) {\n   \t\/\/ logic to initiate and process payment\n   \treturn {}\n   }\n}\n\nfunction WarehouseManager() {\n   this.prepareForShipping = function(items, invoice) {\n   \t\/\/ logic to prepare the items to be shipped\n   }\n}\n\n\/\/ This is where facade comes in. You create an additional interface on top of your\n\/\/ existing interfaces to define the business logic clearly. This interface exposes\n\/\/ very simple, high-level methods for the calling environment.\nfunction OnlineStore() {\n   this.name = \"Online Store\"\n \n   this.placeOrder = function() {\n   \tlet cartManager = new CartManager()\n   \tlet items = cartManager.getItems()\n\n   \tlet invoiceManager = new InvoiceManager()\n   \tlet invoice = invoiceManager.createInvoice(items)\n \t \n   \tlet paymentResult = new PaymentProcessor().processPayment(invoice)\n   \tinvoiceManager.updateInvoicePaymentDetails(paymentResult)\n\n   \tif (paymentResult.status === 'success') {\n       \tnew WarehouseManager().prepareForShipping(items, invoice)\n       \tcartManager.clearCart()\n   \t} else {\n       \tinvoiceManager.notifyCustomerOfFailure(invoice)\n   \t}\n \t \n   }\n}\n\n\/\/ The calling environment is unaware of what goes on when somebody clicks a button to\n\/\/ place the order. You can easily change the underlying business logic without breaking\n\/\/ your calling environment.\nfunction run() {\n   let onlineStore = new OnlineStore()\n\n   onlineStore.placeOrder()\n}<\/code><\/pre>\n<p>Un aspetto negativo dell&#8217;utilizzo del pattern Facade \u00e8 che aggiunge un ulteriore livello di astrazione tra la logica aziendale e il client, richiedendo cos\u00ec una manutenzione aggiuntiva. Spesso questo aumenta la complessit\u00e0 complessiva della base di codice.<\/p>\n<p>Inoltre, la classe <code>Facade<\/code> diventa una dipendenza obbligatoria per il funzionamento della vostra applicazione: ci\u00f2 significa che qualsiasi errore nella classe <code>Facade<\/code> ha un impatto diretto sul funzionamento della vostra applicazione.<\/p>\n<h4>11. Flyweight<\/h4>\n<p>Il pattern Flyweight vi aiuta a risolvere i problemi che coinvolgono oggetti con componenti ripetuti in modo efficiente dal punto di vista della memoria, aiutandovi a riutilizzare i componenti comuni del vostro pool di oggetti. Questo aiuta a ridurre il carico sulla memoria e a velocizzare i tempi di esecuzione.<\/p>\n<p>Nell&#8217;esempio che segue, una frase di grandi dimensioni viene memorizzata utilizzando il design pattern Flyweight. Invece di memorizzare ogni carattere nel momento in cui si presenta, il programma identifica l&#8217;insieme dei caratteri distinti che sono stati utilizzati per scrivere il paragrafo e i loro tipi (numero o alfabeto) e costruisce dei flyweight riutilizzabili per ogni carattere che contengono i dettagli del carattere e del tipo memorizzati.<\/p>\n<p>In seguito, l&#8217;array principale si limita a memorizzare un elenco di riferimenti a questi pesi volanti nell&#8217;ordine in cui si presentano nella frase, invece di memorizzare un&#8217;istanza dell&#8217;oggetto carattere ogni volta che si presenta.<\/p>\n<p>In questo modo la memoria occupata dalla frase si riduce della met\u00e0. Tenete presente che questa \u00e8 una spiegazione molto elementare di come i processori di testo memorizzano il testo.<\/p>\n<pre><code class=\"language-js\">\/\/ A simple Character class that stores the value, type, and position of a character\nfunction Character(value, type, position) {\n   this.value = value\n   this.type = type\n   this.position = position\n}\n\n\/\/ A Flyweight class that stores character value and type combinations\nfunction CharacterFlyweight(value, type) {\n   this.value = value\n   this.type = type\n}\n\n\/\/ A factory to automatically create the flyweights that are not present in the list,\n\/\/ and also generate a count of the total flyweights in the list\nconst CharacterFlyweightFactory = (function () {\n   const flyweights = {}\n\n   return {\n   \tget: function (value, type) {\n       \tif (flyweights[value + type] === undefined)\n           \tflyweights[value + type] = new CharacterFlyweight(value, type)\n\n       \treturn flyweights[value + type]\n   \t},\n   \tcount: function () {\n       \tlet count = 0;\n       \tfor (var f in flyweights) count++;\n       \treturn count;\n   \t}\n   }\n})()\n\n\/\/ An enhanced Character class that uses flyweights to store references\n\/\/ to recurring value and type combinations\nfunction CharacterWithFlyweight(value, type, position) {\n   this.flyweight = CharacterFlyweightFactory.get(value, type)\n   this.position = position\n}\n\n\/\/ A helper function to define the type of a character\n\/\/ It identifies numbers as N and everything as A (for alphabets)\nfunction getCharacterType(char) {\n   switch (char) {\n   \tcase \"0\":\n   \tcase \"1\":\n   \tcase \"2\":\n   \tcase \"3\":\n   \tcase \"4\":\n   \tcase \"5\":\n   \tcase \"6\":\n   \tcase \"7\":\n   \tcase \"8\":\n   \tcase \"9\": return \"N\"\n   \tdefault:\n       \treturn \"A\"\n\n   }\n}\n\n\/\/ A list class to create an array of Characters from a given string\nfunction CharactersList(str) {\n   chars = []\n   for (let i = 0; i &lt; str.length; i++) {\n   \tconst char = str[i]\n   \tchars.push(new Character(char, getCharacterType(char), i))\n   }\n\n   return chars\n}\n\n\/\/ A list class to create an array of CharacterWithFlyweights from a given string\nfunction CharactersWithFlyweightsList(str) {\n   chars = []\n   for (let i = 0; i  \" + charactersList.length)\n   \/\/ Output: Character count -&gt; 656\n\n   \/\/ The number of flyweights created is only 31, since only 31 characters are used to write the\n   \/\/ entire paragraph. This means that to store 656 characters, a total of\n   \/\/ (31 * 2 + 656 * 1 = 718) memory blocks are used instead of (656 * 3 = 1968) which would have\n   \/\/ used by the standard array.\n   \/\/ (We have assumed each variable to take up one memory block for simplicity. This\n   \/\/ may vary in real-life scenarios)\n   console.log(\"Flyweights created -&gt; \" + CharacterFlyweightFactory.count())\n   \/\/ Output: Flyweights created -&gt; 31\n\n}\n\nrun()<\/code><\/pre>\n<p>Come avrete gi\u00e0 notato, il pattern Flyweight aumenta la complessit\u00e0 del progetto del vostro software e non \u00e8 particolarmente intuitivo. Quindi, se il risparmio di memoria non \u00e8 un problema urgente per la vostra applicazione, la complessit\u00e0 aggiuntiva di Flyweight pu\u00f2 essere pi\u00f9 dannosa che positiva.<\/p>\n<p>Inoltre, i flyweight scambiano la memoria con l&#8217;efficienza di elaborazione, quindi se siete a corto di cicli di CPU, Flyweight non \u00e8 una buona soluzione per voi.<\/p>\n<h4>12. Proxy<\/h4>\n<p>Lo schema Proxy vi aiuta a sostituire un oggetto con un altro. In altre parole, gli oggetti proxy possono prendere il posto degli oggetti reali (di cui sono un proxy) e controllare l&#8217;accesso all&#8217;oggetto. Questi oggetti proxy possono essere utilizzati per eseguire alcune azioni prima o dopo che la richiesta di invocazione sia passata all&#8217;oggetto reale.<\/p>\n<p>Nell&#8217;esempio che segue, vedrete come l&#8217;accesso a un&#8217;istanza di database viene controllato tramite un proxy che esegue alcuni controlli di convalida di base sulle richieste prima di lasciarle passare:<\/p>\n<pre><code class=\"language-js\">function DatabaseHandler() {\n   const data = {}\n\n   this.set = function (key, val) {\n   \tdata[key] = val;\n   }\n   this.get = function (key, val) {\n   \treturn data[key]\n   }\n   this.remove = function (key) {\n   \tdata[key] = null;\n   }\n\n\n}\n\nfunction DatabaseProxy(databaseInstance) {\n\n   this.set = function (key, val) {\n   \tif (key === \"\") {\n       \tconsole.log(\"Invalid input\")\n       \treturn\n   \t}\n\n   \tif (val === undefined) {\n       \tconsole.log(\"Setting value to undefined not allowed!\")\n       \treturn\n   \t}\n\n   \tdatabaseInstance.set(key, val)\n   }\n\n   this.get = function (key) {\n   \tif (databaseInstance.get(key) === null) {\n       \tconsole.log(\"Element deleted\")\n   \t}\n\n   \tif (databaseInstance.get(key) === undefined) {\n       \tconsole.log(\"Element not created\")\n   \t}\n\n   \treturn databaseInstance.get(key)\n   }\n\n   this.remove = function (key) {\n   \tif (databaseInstance.get(key) === undefined) {\n       \tconsole.log(\"Element not added\")\n       \treturn\n   \t}\n\n   \tif (databaseInstance.get(key) === null) {\n       \tconsole.log(\"Element removed already\")\n       \treturn\n   \t}\n\n   \treturn databaseInstance.remove(key)\n   }\n\n}\n\nfunction run() {\n   let databaseInstance = new DatabaseHandler()\n\n   databaseInstance.set(\"foo,\" \"bar\")\n   databaseInstance.set(\"foo,\" undefined)\n   console.log(\"#1: \" + databaseInstance.get(\"foo\"))\n   \/\/ #1: undefined\n\n   console.log(\"#2: \" + databaseInstance.get(\"baz\"))\n   \/\/ #2: undefined\n\n   databaseInstance.set(\",\" \"something\")\n\n   databaseInstance.remove(\"foo\")\n   console.log(\"#3: \" + databaseInstance.get(\"foo\"))\n   \/\/ #3: null\n\n   databaseInstance.remove(\"foo\")\n   databaseInstance.remove(\"baz\")\n\n   \/\/ Create a fresh database instance to try the same operations\n   \/\/ using the proxy\n   databaseInstance = new DatabaseHandler()\n   let proxy = new DatabaseProxy(databaseInstance)\n\n   proxy.set(\"foo,\" \"bar\")\n   proxy.set(\"foo,\" undefined)\n   \/\/ Proxy jumps in:\n   \/\/ Output: Setting value to undefined not allowed!\n\n   console.log(\"#1: \" + proxy.get(\"foo\"))\n   \/\/ Original value is retained:\n   \/\/ Output: #1: bar\n\n   console.log(\"#2: \" + proxy.get(\"baz\"))\n   \/\/ Proxy jumps in again\n   \/\/ Output:\n   \/\/ Element not created\n   \/\/ #2: undefined\n\n\n   proxy.set(\",\" \"something\")\n   \/\/ Proxy jumps in again\n   \/\/ Output: Invalid input\n\n   proxy.remove(\"foo\")\n\n   console.log(\"#3: \" + proxy.get(\"foo\"))\n   \/\/ Proxy jumps in again\n   \/\/ Output:\n   \/\/ Element deleted\n   \/\/ #3: null\n\n   proxy.remove(\"foo\")\n   \/\/ Proxy output: Element removed already\n   proxy.remove(\"baz\")\n   \/\/ Proxy output: Element not added\n\n}\n\nrun()<\/code><\/pre>\n<p>Questo design pattern \u00e8 comunemente utilizzato in tutto il settore e aiuta a implementare facilmente le operazioni di pre-esecuzione e post-esecuzione. Tuttavia, come ogni altro design pattern, aggiunge complessit\u00e0 alla vostra codebase, quindi cercate di non usarlo se non ne avete davvero bisogno.<\/p>\n<p>Dovrete anche tenere presente che, poich\u00e9 viene coinvolto un oggetto aggiuntivo quando si effettuano le chiamate al vostro oggetto reale, potrebbe esserci una certa latenza dovuta alle operazioni di elaborazione aggiunte. L&#8217;ottimizzazione delle prestazioni dell&#8217;oggetto principale comporta anche l&#8217;ottimizzazione dei metodi del proxy.<\/p>\n<h3>Comportamentali<\/h3>\n<p>I design pattern comportamentali aiutano a risolvere i problemi legati all&#8217;interazione tra gli oggetti. Questo pu\u00f2 comportare la condivisione o il passaggio di responsabilit\u00e0\/controllo tra gli oggetti per completare le operazioni. Pu\u00f2 anche riguardare il passaggio\/condivisione di dati tra pi\u00f9 oggetti nel modo pi\u00f9 efficiente possibile.<\/p>\n<h4>13. Chain of Responsibility<\/h4>\n<p>Il pattern Chain of Responsibility \u00e8 uno dei design pattern comportamentali pi\u00f9 semplici. Si rivela utile quando si progetta la logica per operazioni che possono essere gestite da pi\u00f9 gestori.<\/p>\n<p>In modo simile a come funziona l&#8217;escalation dei problemi nei team di assistenza, il controllo passa attraverso una catena di gestori e il gestore responsabile dell&#8217;azione completa l&#8217;operazione. Questo schema di progettazione \u00e8 spesso utilizzato nella progettazione delle interfacce utente, dove pi\u00f9 livelli di componenti possono gestire un evento di input dell&#8217;utente, come un tocco o uno scorrimento.<\/p>\n<p>Qui di seguito potete vedere un esempio di escalation di un reclamo che utilizza il modello della Chain of Responsibility. Il reclamo verr\u00e0 gestito dai gestori in base alla sua gravit\u00e0:<\/p>\n<pre><code class=\"language-js\">\/\/ Complaint class that stores title and severity of a complaint\n\/\/ Higher value of severity indicates a more severe complaint\nfunction Complaint (title, severity) {\n\tthis.title = title\n\tthis.severity = severity\n}\n\n\/\/ Base level handler that receives all complaints\nfunction Representative () {\n\t\/\/ If this handler can not handle the complaint, it will be forwarded to the next level\n\tthis.nextLevel = new Management()\n\n\tthis.handleComplaint = function (complaint) {\n    \tif (complaint.severity === 0)\n        \tconsole.log(\"Representative resolved the following complaint: \" + complaint.title)\n    \telse\n        \tthis.nextLevel.handleComplaint(complaint)\n\t}\n}\n\n\/\/ Second level handler to handle complaints of severity 1\nfunction Management() {\n\t\/\/ If this handler can not handle the complaint, it will be forwarded to the next level\n\tthis.nextLevel = new Leadership()\n\n\tthis.handleComplaint = function (complaint) {\n    \tif (complaint.severity === 1)\n        \tconsole.log(\"Management resolved the following complaint: \" + complaint.title)\n    \telse\n        \tthis.nextLevel.handleComplaint(complaint)\n\t}\n}\n\n\/\/ Highest level handler that handles all complaints unhandled so far\nfunction Leadership() {\n\tthis.handleComplaint = function (complaint) {\n    \tconsole.log(\"Leadership resolved the following complaint: \" + complaint.title)\n\t}\n}\n\nfunction run() {\n\t\/\/ Create an instance of the base level handler\n\tlet customerSupport = new Representative()\n\n\t\/\/ Create multiple complaints of varying severity and pass them to the base handler\n\n\tlet complaint1 = new Complaint(\"Submit button doesn't work,\" 0)\n\tcustomerSupport.handleComplaint(complaint1)\n\t\/\/ Output: Representative resolved the following complaint: Submit button doesn't work\n\n\tlet complaint2 = new Complaint(\"Payment failed,\" 1)\n\tcustomerSupport.handleComplaint(complaint2)\n\t\/\/ Output: Management resolved the following complaint: Payment failed\n\n\tlet complaint3 = new Complaint(\"Employee misdemeanour,\" 2)\n\tcustomerSupport.handleComplaint(complaint3)\n\t\/\/ Output: Leadership resolved the following complaint: Employee misdemeanour\n}\n\nrun()<\/code><\/pre>\n<p>L&#8217;ovvio problema di questa struttura \u00e8 che \u00e8 lineare, quindi pu\u00f2 esserci una certa latenza nella gestione di un&#8217;operazione quando un gran numero di gestori sono concatenati l&#8217;uno all&#8217;altro.<\/p>\n<p>Tenere traccia di tutti i gestori pu\u00f2 essere un altro punto dolente, perch\u00e9 dopo un certo numero le cose possono farsi molto disordinate. Il debug \u00e8 un altro grattacapo, perch\u00e9 ogni richiesta pu\u00f2 terminare con un gestore diverso, rendendo difficile standardizzare il <a href=\"https:\/\/kinsta.com\/it\/blog\/debug-node\/\">processo di log e debug<\/a>.<\/p>\n<h4>14. Iterator<\/h4>\n<p>Il pattern Iterator \u00e8 piuttosto semplice ed \u00e8 molto utilizzato in quasi tutti i moderni linguaggi orientati agli oggetti. Se vi trovate a dover scorrere un elenco di oggetti che non sono tutti dello stesso tipo, i normali metodi di iterazione, come i loop for, possono diventare piuttosto complicati, soprattutto se al loro interno scrivete anche della logica aziendale.<\/p>\n<p>Il pattern Iterator pu\u00f2 aiutarvi a isolare la logica di iterazione e di elaborazione degli elenchi dalla logica aziendale principale.<\/p>\n<p>Ecco come potete usarlo per un elenco di base con pi\u00f9 tipi di elementi:<\/p>\n<pre><code class=\"language-js\">\/\/ Iterator for a complex list with custom methods\nfunction Iterator(list) {\n   this.list = list\n   this.index = 0\n\n   \/\/ Fetch the current element\n   this.current = function() {\n   \treturn this.list[this.index]\n   }\n\n   \/\/ Fetch the next element in the list\n   this.next = function() {\n   \treturn this.list[this.index++]\n   }\n\n   \/\/ Check if there is another element in the list\n   this.hasNext = function() {\n   \treturn this.index &lt; this.list.length\n   }\n\n   \/\/ Reset the index to point to the initial element\n   this.resetIndex = function() {\n   \tthis.index = 0\n   }\n\n   \/\/ Run a forEach loop over the list\n   this.forEach = function(callback) {\n   \tfor (let element = this.next(); this.index &lt;= this.list.length; element = this.next()) {\n       \tcallback(element)\n   \t}\n   }\n}\n\nfunction run() {\n   \/\/ A complex list with elements of multiple data types\n   let list = [\"Lorem ipsum,\" 9, [\"lorem ipsum dolor,\" true], false]\n\n   \/\/ Create an instance of the iterator and pass it the list\n   let iterator = new Iterator(list)\n\n   \/\/ Log the first element\n   console.log(iterator.current())\n   \/\/ Output: Lorem ipsum\n\n   \/\/ Print all elements of the list using the iterator's methods\n   while (iterator.hasNext()) {\n   \tconsole.log(iterator.next())\n   \t\/**\n    \t* Output:\n    \t* Lorem ipsum\n    \t* 9\n    \t* [ 'lorem ipsum dolor', true ]\n    \t* false\n    \t*\/\n   }\n\n   \/\/ Reset the iterator's index to the first element\n   iterator.resetIndex()\n\n   \/\/ Use the custom iterator to pass an effect that will run for each element of the list\n   iterator.forEach(function (element) {\n   \tconsole.log(element)\n   })\n   \/**\n\t* Output:\n\t* Lorem ipsum\n\t* 9\n\t* [ 'lorem ipsum dolor', true ]\n\t* false\n\t*\/\n}\n\nrun()<\/code><\/pre>\n<p>Inutile dire che questo schema pu\u00f2 essere inutilmente complesso per gli elenchi senza pi\u00f9 tipi di elementi. Inoltre, se ci sono troppi tipi di elementi in un elenco, pu\u00f2 diventare difficile da gestire.<\/p>\n<p>Il segreto \u00e8 capire se avete davvero bisogno di un iteratore in base alla vostra lista e alle sue possibilit\u00e0 di modifica futura. Inoltre, lo schema dell&#8217;iteratore \u00e8 utile solo per gli elenchi e gli elenchi possono talvolta limitarvi alla loro modalit\u00e0 di accesso lineare. Altre strutture di dati possono offrire maggiori vantaggi in termini di prestazioni.<\/p>\n<h4>15. Mediator<\/h4>\n<p>Il progetto della vostra applicazione pu\u00f2 richiedere di giocare con un gran numero di oggetti distinti che ospitano vari tipi di logica aziendale e che spesso dipendono l&#8217;uno dall&#8217;altro. La gestione delle dipendenze pu\u00f2 essere a volte complicata perch\u00e9 dovete tenere traccia di come questi oggetti si scambiano dati e controlli tra loro.<\/p>\n<p>Il design pattern Mediator vi aiuta a risolvere questo problema isolando la logica di interazione di questi oggetti in un oggetto separato.<\/p>\n<p>Questo oggetto separato \u00e8 noto come mediatore ed \u00e8 responsabile del lavoro svolto dalle classi di livello inferiore. Anche il vostro cliente o l&#8217;ambiente chiamante interagir\u00e0 con il mediatore invece che con le classi di livello inferiore.<\/p>\n<p>Ecco un esempio del design pattern Mediator in azione:<\/p>\n<pre><code class=\"language-js\">\/\/ Writer class that receives an assignment, writes it in 2 seconds, and marks it as finished\nfunction Writer(name, manager) {\n    \n\t\/\/ Reference to the manager, writer's name, and a busy flag that the manager uses while assigning the article\n\tthis.manager = manager\n\tthis.name = name\n\tthis.busy = false\n\n\tthis.startWriting = function (assignment) {\n    \tconsole.log(this.name + \" started writing \"\" + assignment + \"\"\")\n    \tthis.assignment = assignment\n    \tthis.busy = true\n\n    \t\/\/ 2 s timer to replicate manual action\n    \tsetTimeout(() =&gt; { this.finishWriting() }, 2000)\n\t}\n\n\tthis.finishWriting = function () {\n    \tif (this.busy === true) {\n        \tconsole.log(this.name + \" finished writing \"\" + this.assignment + \"\"\")\n        \tthis.busy = false\n        \treturn this.manager.notifyWritingComplete(this.assignment)\n    \t} else {\n        \tconsole.log(this.name + \" is not writing any article\")\n    \t}\n\t}\n}\n\n\/\/ Editor class that receives an assignment, edits it in 3 seconds, and marks it as finished\nfunction Editor(name, manager) {\n    \n\t\/\/ Reference to the manager, writer's name, and a busy flag that the manager uses while assigning the article\n\tthis.manager = manager\n\tthis.name = name\n\tthis.busy = false\n\n\tthis.startEditing = function (assignment) {\n    \tconsole.log(this.name + \" started editing \"\" + assignment + \"\"\")\n    \tthis.assignment = assignment\n    \tthis.busy = true\n\n    \t\/\/ 3 s timer to replicate manual action\n    \tsetTimeout(() =&gt; { this.finishEditing() }, 3000)\n\t}\n\n\tthis.finishEditing = function () {\n    \tif (this.busy === true) {\n        \tconsole.log(this.name + \" finished editing \"\" + this.assignment + \"\"\")\n        \tthis.manager.notifyEditingComplete(this.assignment)\n        \tthis.busy = false\n    \t} else {\n        \tconsole.log(this.name + \" is not editing any article\")\n    \t}\n\t}\n}\n\n\/\/ The mediator class\nfunction Manager() {\n\t\/\/ Store arrays of workers\n\tthis.editors = []\n\tthis.writers = []\n\n\tthis.setEditors = function (editors) {\n    \tthis.editors = editors\n\t}\n\tthis.setWriters = function (writers) {\n    \tthis.writers = writers\n\t}\n\n\t\/\/ Manager receives new assignments via this method\n\tthis.notifyNewAssignment = function (assignment) {\n    \tlet availableWriter = this.writers.find(function (writer) {\n        \treturn writer.busy === false\n    \t})\n    \tavailableWriter.startWriting(assignment)\n    \treturn availableWriter\n\t}\n\n\t\/\/ Writers call this method to notify they're done writing\n\tthis.notifyWritingComplete = function (assignment) {\n    \tlet availableEditor = this.editors.find(function (editor) {\n        \treturn editor.busy === false\n    \t})\n    \tavailableEditor.startEditing(assignment)\n    \treturn availableEditor\n\t}\n\n\t\/\/ Editors call this method to notify they're done editing\n\tthis.notifyEditingComplete = function (assignment) {\n    \tconsole.log(\"\"\" + assignment + \"\" is ready to publish\")\n\t}\n\n}\n\nfunction run() {\n\t\/\/ Create a manager\n\tlet manager = new Manager()\n\n\t\/\/ Create workers\n\tlet editors = [\n    \tnew Editor(\"Ed,\" manager),\n    \tnew Editor(\"Phil,\" manager),\n\t]\n\n\tlet writers = [\n    \tnew Writer(\"Michael,\" manager),\n    \tnew Writer(\"Rick,\" manager),\n\t]\n\n\t\/\/ Attach workers to manager\n\tmanager.setEditors(editors)\n\tmanager.setWriters(writers)\n\n\t\/\/ Send two assignments to manager\n\tmanager.notifyNewAssignment(\"var vs let in JavaScript\")\n\tmanager.notifyNewAssignment(\"JS promises\")\n\n\t\/**\n \t* Output:\n \t* Michael started writing \"var vs let in JavaScript\"\n \t* Rick started writing \"JS promises\"\n \t*\n \t* After 2s, output:\n \t* Michael finished writing \"var vs let in JavaScript\"\n \t* Ed started editing \"var vs let in JavaScript\"\n \t* Rick finished writing \"JS promises\"\n \t* Phil started editing \"JS promises\"\n \t*\n \t* After 3s, output:\n \t* Ed finished editing \"var vs let in JavaScript\"\n \t* \"var vs let in JavaScript\" is ready to publish\n \t* Phil finished editing \"JS promises\"\n \t* \"JS promises\" is ready to publish\n \t*\/\n\n}\n\nrun()<\/code><\/pre>\n<p>Sebbene il mediatore fornisca al progetto della vostra applicazione un disaccoppiamento e una grande flessibilit\u00e0, alla fine fine \u00e8 un&#8217;altra classe che dovete mantenere. Dovete valutare se il vostro progetto pu\u00f2 davvero trarre beneficio da un mediatore prima di scriverne uno, in modo da non finire per aggiungere inutili complessit\u00e0 alla vostra code base.<\/p>\n<p>Inoltre, \u00e8 importante tenere presente che anche se la classe del mediatore non contiene alcuna logica aziendale diretta, contiene comunque molto codice fondamentale per il funzionamento della vostra applicazione e pu\u00f2 quindi complicarsi rapidamente.<\/p>\n<h4>16. Memento<\/h4>\n<p>Il versioning degli oggetti \u00e8 un altro problema comune che si incontra quando si sviluppano applicazioni. Ci sono molti casi d&#8217;uso in cui \u00e8 necessario mantenere la cronologia di un oggetto, supportare un facile rollback e, a volte, anche il ripristino di tali rollback. Scrivere la logica per queste applicazioni pu\u00f2 essere complicato.<\/p>\n<p>Il design pattern Memento \u00e8 pensato per risolvere facilmente questo problema.<\/p>\n<p>Un memento \u00e8 un&#8217;istantanea di un oggetto in un determinato momento. Il design pattern Memento utilizza questi memento per conservare le istantanee dell&#8217;oggetto mentre viene modificato nel tempo. Quando avete bisogno di tornare a una vecchia versione, potete semplicemente recuperare il memento.<\/p>\n<p>Ecco come implementarlo in un&#8217;applicazione per l&#8217;elaborazione del testo:<\/p>\n<pre><code class=\"language-js\">\/\/ The memento class that can hold one snapshot of the Originator class - document\nfunction Text(contents) {\n\t\/\/ Contents of the document\n\tthis.contents = contents\n\n\t\/\/ Accessor function for contents\n\tthis.getContents = function () {\n    \treturn this.contents\n\t}\n\n\t\/\/ Helper function to calculate word count for the current document\n\tthis.getWordCount = function () {\n    \treturn this.contents.length\n\t}\n}\n\n\/\/ The originator class that holds the latest version of the document\nfunction Document(contents) {\n\t\/\/ Holder for the memento, i.e., the text of the document\n\tthis.text = new Text(contents)\n\n\t\/\/ Function to save new contents as a memento\n\tthis.save = function (contents) {\n    \tthis.text = new Text(contents)\n    \treturn this.text\n\t}\n\n\t\/\/ Function to revert to an older version of the text using a memento\n\tthis.restore = function (text) {\n    \tthis.text = new Text(text.getContents())\n\t}\n\n\t\/\/ Helper function to get the current memento\n\tthis.getText = function () {\n    \treturn this.text\n\t}\n\n\t\/\/ Helper function to get the word count of the current document\n\tthis.getWordCount = function () {\n    \treturn this.text.getWordCount()\n\t}\n}\n\n\/\/ The caretaker class that providers helper functions to modify the document\nfunction DocumentManager(document) {\n\t\/\/ Holder for the originator, i.e., the document\n\tthis.document = document\n\n\t\/\/ Array to maintain a list of mementos\n\tthis.history = []\n\n\t\/\/ Add the initial state of the document as the first version of the document\n\tthis.history.push(document.getText())\n\n\t\/\/ Helper function to get the current contents of the documents\n\tthis.getContents = function () {\n    \treturn this.document.getText().getContents()\n\t}\n\n\t\/\/ Helper function to get the total number of versions available for the document\n\tthis.getVersionCount = function () {\n    \treturn this.history.length\n\t}\n\n\t\/\/ Helper function to get the complete history of the document\n\tthis.getHistory = function () {\n    \treturn this.history.map(function (element) {\n        \treturn element.getContents()\n    \t})\n\n\t}\n\n\t\/\/ Function to overwrite the contents of the document\n\tthis.overwrite = function (contents) {\n    \tlet newVersion = this.document.save(contents)\n    \tthis.history.push(newVersion)\n\t}\n\n\t\/\/ Function to append new content to the existing contents of the document\n\tthis.append = function (contents) {\n    \tlet currentVersion = this.history[this.history.length - 1]\n    \tlet newVersion\n    \tif (currentVersion === undefined)\n        \tnewVersion = this.document.save(contents)\n    \telse\n        \tnewVersion = this.document.save(currentVersion.getContents() + contents)\n    \tthis.history.push(newVersion)\n\t}\n\n\t\/\/ Function to delete all the contents of the document\n\tthis.delete = function () {\n    \tthis.history.push(this.document.save(\"\"))\n\t}\n\n\t\/\/ Function to get a particular version of the document\n\tthis.getVersion = function (versionNumber) {\n    \treturn this.history[versionNumber - 1]\n\t}\n\n\t\/\/ Function to undo the last change\n\tthis.undo = function () {\n    \tlet previousVersion = this.history[this.history.length - 2]\n    \tthis.document.restore(previousVersion)\n    \tthis.history.push(previousVersion)\n\t}\n\n\t\/\/ Function to revert the document to a previous version\n\tthis.revertToVersion = function (version) {\n    \tlet previousVersion = this.history[version - 1]\n    \tthis.document.restore(previousVersion)\n    \tthis.history.push(previousVersion)\n\t}\n\n\t\/\/ Helper function to get the total word count of the document\n\tthis.getWordCount = function () {\n    \treturn this.document.getWordCount()\n\t}\n\n}\n\nfunction run() {\n\t\/\/ Create a document\n\tlet blogPost = new Document(\"\")\n\n\t\/\/ Create a caretaker for the document\n\tlet blogPostManager = new DocumentManager(blogPost)\n\n\t\/\/ Change #1: Add some text\n\tblogPostManager.append(\"Hello World!\")\n\tconsole.log(blogPostManager.getContents())\n\t\/\/ Output: Hello World!\n\n\t\/\/ Change #2: Add some more text\n\tblogPostManager.append(\" This is the second entry in the document\")\n\tconsole.log(blogPostManager.getContents())\n\t\/\/ Output: Hello World! This is the second entry in the document\n\n\t\/\/ Change #3: Overwrite the document with some new text\n\tblogPostManager.overwrite(\"This entry overwrites everything in the document\")\n\tconsole.log(blogPostManager.getContents())\n\t\/\/ Output: This entry overwrites everything in the document\n\n\t\/\/ Change #4: Delete the contents of the document\n\tblogPostManager.delete()\n\tconsole.log(blogPostManager.getContents())\n\t\/\/ Empty output\n\n\t\/\/ Get an old version of the document\n\tconsole.log(blogPostManager.getVersion(2).getContents())\n\t\/\/ Output: Hello World!\n\n\t\/\/ Change #5: Go back to an old version of the document\n\tblogPostManager.revertToVersion(3)\n\tconsole.log(blogPostManager.getContents())\n\t\/\/ Output: Hello World! This is the second entry in the document\n\n\t\/\/ Get the word count of the current document\n\tconsole.log(blogPostManager.getWordCount())\n\t\/\/ Output: 53\n\n\t\/\/ Change #6: Undo the last change\n\tblogPostManager.undo()\n\tconsole.log(blogPostManager.getContents())\n\t\/\/ Empty output\n\n\t\/\/ Get the total number of versions for the document\n\tconsole.log(blogPostManager.getVersionCount())\n\t\/\/ Output: 7\n\n\t\/\/ Get the complete history of the document\n\tconsole.log(blogPostManager.getHistory())\n\t\/**\n \t* Output:\n \t* [\n \t*   '',\n \t*   'Hello World!',\n \t*   'Hello World! This is the second entry in the document',\n \t*   'This entry overwrites everything in the document',\n \t*   '',\n \t*   'Hello World! This is the second entry in the document',\n \t*   ''\n \t* ]\n \t*\/\n}\n\nrun()<\/code><\/pre>\n<p>Sebbene il design pattern Memento sia un&#8217;ottima soluzione per gestire la cronologia di un oggetto, pu\u00f2 richiedere molte risorse. Dal momento che ogni memento \u00e8 quasi una copia dell&#8217;oggetto, pu\u00f2 appesantire la memoria dell&#8217;applicazione molto rapidamente se non viene usato con moderazione.<\/p>\n<p>Con un gran numero di oggetti, anche la gestione del loro ciclo di vita pu\u00f2 diventare un compito piuttosto noioso. Inoltre, le classi <code>Originator<\/code> e <code>Caretaker<\/code> sono di solito strettamente accoppiate, il che aumenta la complessit\u00e0 della vostra codebase.<\/p>\n<h4>17. Observer<\/h4>\n<p>Il pattern Observer fornisce una soluzione alternativa al problema dell&#8217;interazione tra pi\u00f9 oggetti (gi\u00e0 visto nel pattern Mediator).<\/p>\n<p>Invece di permettere a ogni oggetto di comunicare tra loro attraverso un mediatore designato, il pattern Observer permette agli oggetti di osservarsi a vicenda. Gli oggetti sono progettati per emettere eventi quando cercano di inviare dati o controlli e gli altri oggetti che sono in &#8220;ascolto&#8221; di questi eventi possono riceverli e interagire in base al loro contenuto.<\/p>\n<p>Ecco una semplice dimostrazione dell&#8217;invio di newsletter a pi\u00f9 persone attraverso il pattern Observer:<\/p>\n<pre><code class=\"language-js\">\/\/ The newsletter class that can send out posts to its subscribers\nfunction Newsletter() {\n   \/\/ Maintain a list of subscribers\n   this.subscribers = []\n\n   \/\/ Subscribe a reader by adding them to the subscribers' list\n   this.subscribe = function(subscriber) {\n   \tthis.subscribers.push(subscriber)\n   }\n\n   \/\/ Unsubscribe a reader by removing them from the subscribers' list\n   this.unsubscribe = function(subscriber) {\n   \tthis.subscribers = this.subscribers.filter(\n       \tfunction (element) {\n           \tif (element !== subscriber) return element\n       \t}\n   \t)\n   }\n\n   \/\/ Publish a post by calling the receive function of all subscribers\n   this.publish = function(post) {\n   \tthis.subscribers.forEach(function(element) {\n       \telement.receiveNewsletter(post)\n   \t})\n   }\n}\n\n\/\/ The reader class that can subscribe to and receive updates from newsletters\nfunction Reader(name) {\n   this.name = name\n\n   this.receiveNewsletter = function(post) {\n   \tconsole.log(\"Newsletter received by \" + name + \"!: \" + post)\n   }\n\n}\n\nfunction run() {\n   \/\/ Create two readers\n   let rick = new Reader(\"ed\")\n   let morty = new Reader(\"morty\")\n\n   \/\/ Create your newsletter\n   let newsletter = new Newsletter()\n\n   \/\/ Subscribe a reader to the newsletter\n   newsletter.subscribe(rick)\n\n   \/\/ Publish the first post\n   newsletter.publish(\"This is the first of the many posts in this newsletter\")\n   \/**\n\t* Output:\n\t* Newsletter received by ed!: This is the first of the many posts in this newsletter\n\t*\/\n\n   \/\/ Subscribe another reader to the newsletter\n   newsletter.subscribe(morty)\n\n   \/\/ Publish the second post\n   newsletter.publish(\"This is the second of the many posts in this newsletter\")\n   \/**\n\t* Output:\n\t* Newsletter received by ed!: This is the second of the many posts in this newsletter\n\t* Newsletter received by morty!: This is the second of the many posts in this newsletter\n\t*\/\n\n   \/\/ Unsubscribe the first reader\n   newsletter.unsubscribe(rick)\n\n   \/\/ Publish the third post\n   newsletter.publish(\"This is the third of the many posts in this newsletter\")\n   \/**\n\t* Output:\n\t* Newsletter received by morty!: This is the third of the many posts in this newsletter\n\t*\/\n\n}\n\nrun()<\/code><\/pre>\n<p>Sebbene il pattern Observer sia un modo elegante di trasmettere controllo e dati, \u00e8 pi\u00f9 adatto a situazioni in cui ci sono molti mittenti e destinatari che interagiscono tra loro attraverso un numero limitato di connessioni. Se gli oggetti dovessero tutti effettuare connessioni uno a uno, perdereste il vantaggio che si ottiene pubblicando e sottoscrivendo eventi, poich\u00e9 ci sar\u00e0 sempre un solo sottoscrittore per ogni editore (mentre sarebbe stato meglio gestire una linea di comunicazione diretta tra di loro).<\/p>\n<p>Inoltre, il design pattern Observer pu\u00f2 causare problemi di prestazioni se gli eventi di sottoscrizione non vengono gestiti correttamente. Se un oggetto continua a sottoscrivere un altro oggetto anche quando non ne ha bisogno, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Lapsed_listener_problem\">non potr\u00e0 essere sottoposto a garbage collection<\/a> e aumenter\u00e0 il consumo di memoria dell&#8217;applicazione.<\/p>\n<h4>18. State<\/h4>\n<p>Il design pattern State \u00e8 uno dei pi\u00f9 utilizzati nel settore dello sviluppo software. I <a href=\"https:\/\/kinsta.com\/it\/blog\/librerie-javascript\/\">framework JavaScript<\/a> pi\u00f9 diffusi, come <a href=\"https:\/\/reactjs.org\/docs\/state-and-lifecycle.html\">React<\/a> e <a href=\"https:\/\/medium.com\/olricdigital\/introduction-to-state-management-in-angular-v2-ef6f5144bade\">Angular<\/a>, si basano molto sul pattern State per gestire i dati e il comportamento dell&#8217;applicazione in base a tali dati.<\/p>\n<p>In parole povere, il design pattern State \u00e8 utile nelle situazioni in cui \u00e8 possibile definire gli stati definitivi di un&#8217;entit\u00e0 (che pu\u00f2 essere un componente, una pagina, un&#8217;applicazione o una macchina) e l&#8217;entit\u00e0 ha una reazione predefinita al cambiamento di stato.<\/p>\n<p>Supponiamo che stiate cercando di creare un processo di richiesta di un prestito. Ogni fase del processo di richiesta pu\u00f2 essere definita come uno stato.<\/p>\n<p>Mentre il cliente di solito vede un piccolo elenco di stati semplificati della sua domanda (in attesa, in revisione, accettata e rifiutata), ci possono essere altri passaggi coinvolti internamente. In ognuna di queste fasi, la domanda viene assegnata a una persona diversa e pu\u00f2 avere requisiti unici.<\/p>\n<p>Il sistema \u00e8 progettato in modo tale che al termine dell&#8217;elaborazione di uno stato, questo venga aggiornato a quello successivo e venga avviata la successiva serie di passaggi.<\/p>\n<p>Ecco come potete costruire un sistema di gestione delle attivit\u00e0 utilizzando il design pattern State:<\/p>\n<pre><code class=\"language-js\">\/\/ Create titles for all states of a task\nconst STATE_TODO = \"TODO\"\nconst STATE_IN_PROGRESS = \"IN_PROGRESS\"\nconst STATE_READY_FOR_REVIEW = \"READY_FOR_REVIEW\"\nconst STATE_DONE = \"DONE\"\n\n\/\/ Create the task class with a title, assignee, and duration of the task\nfunction Task(title, assignee) {\n\tthis.title = title\n\tthis.assignee = assignee\n\n\t\/\/ Helper function to update the assignee of the task\n\tthis.setAssignee = function (assignee) {\n    \tthis.assignee = assignee\n\t}\n\n\t\/\/ Function to update the state of the task\n\tthis.updateState = function (state) {\n\n    \tswitch (state) {\n        \tcase STATE_TODO:\n            \tthis.state = new TODO(this)\n            \tbreak\n        \tcase STATE_IN_PROGRESS:\n            \tthis.state = new IN_PROGRESS(this)\n            \tbreak\n        \tcase STATE_READY_FOR_REVIEW:\n            \tthis.state = new READY_FOR_REVIEW(this)\n            \tbreak\n        \tcase STATE_DONE:\n            \tthis.state = new DONE(this)\n            \tbreak\n        \tdefault:\n            \treturn\n    \t}\n    \t\/\/ Invoke the callback function for the new state after it is set\n    \tthis.state.onStateSet()\n\t}\n\n\t\/\/ Set the initial state of the task as TODO\n\tthis.updateState(STATE_TODO)\n}\n\n\/\/ TODO state\nfunction TODO(task) {\n\n\tthis.onStateSet = function () {\n    \tconsole.log(task.assignee + \" notified about new task \"\" + task.title + \"\"\")\n\t}\n}\n\n\/\/ IN_PROGRESS state\nfunction IN_PROGRESS(task) {\n\n\tthis.onStateSet = function () {\n    \tconsole.log(task.assignee + \" started working on the task \"\" + task.title + \"\"\")\n\t}\n}\n\n\/\/ READY_FOR_REVIEW state that updates the assignee of the task to be the manager of the developer\n\/\/ for the review\nfunction READY_FOR_REVIEW(task) {\n\tthis.getAssignee = function () {\n    \treturn \"Manager 1\"\n\t}\n\n\tthis.onStateSet = function () {\n    \ttask.setAssignee(this.getAssignee())\n    \tconsole.log(task.assignee + \" notified about completed task \"\" + task.title + \"\"\")\n\t}\n}\n\n\/\/ DONE state that removes the assignee of the task since it is now completed\nfunction DONE(task) {\n\tthis.getAssignee = function () {\n    \treturn \"\"\n\t}\n\n\tthis.onStateSet = function () {\n    \ttask.setAssignee(this.getAssignee())\n    \tconsole.log(\"Task \"\" + task.title + \"\" completed\")\n\t}\n}\n\nfunction run() {\n\t\/\/ Create a task\n\tlet task1 = new Task(\"Create a login page,\" \"Developer 1\")\n\t\/\/ Output: Developer 1 notified about new task \"Create a login page\"\n\n\t\/\/ Set it to IN_PROGRESS\n\ttask1.updateState(STATE_IN_PROGRESS)\n\t\/\/ Output: Developer 1 started working on the task \"Create a login page\"\n\n\t\/\/ Create another task\n\tlet task2 = new Task(\"Create an auth server,\" \"Developer 2\")\n\t\/\/ Output: Developer 2 notified about new task \"Create an auth server\"\n\n\n\t\/\/ Set it to IN_PROGRESS as well\n\ttask2.updateState(STATE_IN_PROGRESS)\n\t\/\/ Output: Developer 2 started working on the task \"Create an auth server\"\n\n\t\/\/ Update the states of the tasks until they are done\n\ttask2.updateState(STATE_READY_FOR_REVIEW)\n\t\/\/ Output: Manager 1 notified about completed task \"Create an auth server\"\n\ttask1.updateState(STATE_READY_FOR_REVIEW)\n\t\/\/ Output: Manager 1 notified about completed task \"Create a login page\"\n\n\n\ttask1.updateState(STATE_DONE)\n\t\/\/ Output: Task \"Create a login page\" completed\n\ttask2.updateState(STATE_DONE)\n\t\/\/ Output: Task \"Create an auth server\" completed\n\n}\n\nrun()<\/code><\/pre>\n<p>Sebbene il pattern State faccia un ottimo lavoro di separazione delle fasi di un processo, pu\u00f2 diventare estremamente difficile da mantenere in applicazioni di grandi dimensioni che hanno pi\u00f9 stati.<\/p>\n<p>Inoltre, se il design del vostro processo non prevede solo un movimento lineare attraverso tutti gli stati, dovrete scrivere e mantenere pi\u00f9 codice, poich\u00e9 ogni transizione di stato deve essere gestita separatamente.<\/p>\n<h4>19. Strategy<\/h4>\n<p>Conosciuto anche come pattern Policy, il pattern Strategy ha lo scopo di aiutarvi a incapsulare e scambiare liberamente le classi utilizzando un&#8217;interfaccia comune. Questo aiuta a mantenere un basso accoppiamento tra il client e le classi e vi permette di aggiungere tutte le implementazioni che desiderate.<\/p>\n<p>Il pattern Strategy \u00e8 noto per essere di grande aiuto nelle situazioni in cui \u00e8 necessario eseguire la stessa operazione con metodi\/algoritmi diversi o in cui \u00e8 necessario sostituire blocchi di commutazione massicci con codice pi\u00f9 semplice da utilizzare.<\/p>\n<p>Ecco un esempio del pattern Strategy:<\/p>\n<pre><code class=\"language-js\">\/\/ The strategy class that can encapsulate all hosting providers\nfunction HostingProvider() {\n   \/\/ store the provider\n   this.provider = \"\"\n\n   \/\/ set the provider\n   this.setProvider = function(provider) {\n   \tthis.provider = provider\n   }\n\n   \/\/ set the website configuration for which each hosting provider would calculate costs\n   this.setConfiguration = function(configuration) {\n   \tthis.configuration = configuration\n   }\n\n   \/\/ the generic estimate method that calls the provider's unique methods to calculate the costs\n   this.estimateMonthlyCost = function() {\n   \treturn this.provider.estimateMonthlyCost(this.configuration)\n   }\n}\n\n\/\/ Foo Hosting charges for each second and KB of hosting usage\nfunction FooHosting (){\n   this.name = \"FooHosting\"\n   this.rate = 0.0000027\n\n   this.estimateMonthlyCost = function(configuration){\n   \treturn configuration.duration * configuration.workloadSize * this.rate\n   }\n}\n\n\/\/ Bar Hosting charges per minute instead of seconds\nfunction BarHosting (){\n   this.name = \"BarHosting\"\n   this.rate = 0.00018\n\n   this.estimateMonthlyCost = function(configuration){\n   \treturn configuration.duration \/ 60 * configuration.workloadSize * this.rate\n   }\n}\n\n\/\/ Baz Hosting assumes the average workload to be of 10 MB in size\nfunction BazHosting (){\n   this.name = \"BazHosting\"\n   this.rate = 0.032\n\n   this.estimateMonthlyCost = function(configuration){\n   \treturn configuration.duration * this.rate\n   }\n}\n\nfunction run() {\n\n   \/\/ Create a website configuration for a website that is up for 24 hours and takes 10 MB of hosting space\n   let workloadConfiguration = {\n   \tduration: 84700,\n   \tworkloadSize: 10240\n   }\n\n   \/\/ Create the hosting provider instances\n   let fooHosting = new FooHosting()\n   let barHosting = new BarHosting()\n   let bazHosting = new BazHosting()\n\n   \/\/ Create the instance of the strategy class\n   let hostingProvider = new HostingProvider()\n\n   \/\/ Set the configuration against which the rates have to be calculated\n   hostingProvider.setConfiguration(workloadConfiguration)\n\n   \/\/ Set each provider one by one and print the rates\n   hostingProvider.setProvider(fooHosting)\n   console.log(\"FooHosting cost: \" + hostingProvider.estimateMonthlyCost())\n   \/\/ Output: FooHosting cost: 2341.7856\n\n   hostingProvider.setProvider(barHosting)\n   console.log(\"BarHosting cost: \" + hostingProvider.estimateMonthlyCost())\n   \/\/ Output: BarHosting cost: 2601.9840\n\n   hostingProvider.setProvider(bazHosting)\n   console.log(\"BarHosting cost: \" + hostingProvider.estimateMonthlyCost())\n   \/\/ Output: BarHosting cost: 2710.4000\n\n}\n\nrun()<\/code><\/pre>\n<p>Il pattern Strategy \u00e8 ottimo quando si tratta di introdurre nuove varianti di un&#8217;entit\u00e0 senza modificare pi\u00f9 di tanto i client. Tuttavia, pu\u00f2 sembrare eccessivo se avete solo una manciata di varianti da implementare.<\/p>\n<p>Inoltre, l&#8217;incapsulamento elimina i dettagli pi\u00f9 fini della logica interna di ogni variante, per cui il cliente non sa come si comporter\u00e0 una variante.<\/p>\n<h4>20. Visitor<\/h4>\n<p>Il pattern Visitor vi aiuta a rendere il vostro codice estensibile.<\/p>\n<p>L&#8217;idea \u00e8 quella di fornire un metodo nella classe che permetta agli oggetti di altre classi di apportare facilmente modifiche agli oggetti della classe corrente. Gli altri oggetti <em>visitano<\/em> l&#8217;oggetto corrente (chiamato anche oggetto luogo), oppure la classe corrente <em>accetta<\/em> gli oggetti visitatori e l&#8217;oggetto luogo gestisce la visita di ogni oggetto esterno in modo appropriato.<\/p>\n<p>Ecco come usarlo:<\/p>\n<pre><code class=\"language-js\">\/\/ Visitor class that defines the methods to be called when visiting each place\nfunction Reader(name, cash) {\n\tthis.name = name\n\tthis.cash = cash\n\n\t\/\/ The visit methods can access the place object and invoke available functions\n\tthis.visitBookstore = function(bookstore) {\n    \tconsole.log(this.name + \" visited the bookstore and bought a book\")\n    \tbookstore.purchaseBook(this)\n\t}\n\n\tthis.visitLibrary = function() {\n    \tconsole.log(this.name + \" visited the library and read a book\")\n\t}\n\n\t\/\/ Helper function to demonstrate a transaction\n\tthis.pay = function(amount) {\n    \tthis.cash -= amount\n\t}\n}\n\n\/\/ Place class for a library\nfunction Library () {\n\tthis.accept = function(reader) {\n    \treader.visitLibrary()\n\t}\n}\n\n\/\/ Place class for a bookstore that allows purchasing book\nfunction Bookstore () {\n\tthis.accept = function(reader) {\n    \treader.visitBookstore(this)\n\t}\n\n\tthis.purchaseBook = function (visitor) {\n    \tconsole.log(visitor.name + \" bought a book\")\n    \tvisitor.pay(8)\n\t}\n}\n\n\nfunction run() {\n\t\/\/ Create a reader (the visitor)\n\tlet reader = new Reader(\"Rick,\" 30)\n\n\t\/\/ Create the places\n\tlet booksInc = new Bookstore()\n\tlet publicLibrary = new Library()\n\n\t\/\/ The reader visits the library\n\tpublicLibrary.accept(reader)\n\t\/\/ Output: Rick visited the library and read a book\n\tconsole.log(reader.name + \" has $\" + reader.cash)\n\t\/\/ Output: Rick has $30\n\n\t\/\/ The reader visits the bookstore\n\tbooksInc.accept(reader)\n\t\/\/ Output: Rick visited the bookstore and bought a book\n\tconsole.log(reader.name + \" has $\" + reader.cash)\n\t\/\/ Output: Rick has $22\n}\n\nrun()<\/code><\/pre>\n<p>L&#8217;unico difetto di questo design \u00e8 che ogni classe visitatore deve essere aggiornata ogni volta che viene aggiunto o modificato un nuovo luogo. Nei casi in cui esistono pi\u00f9 visitatori e oggetti luogo insieme, pu\u00f2 essere difficile da mantenere.<\/p>\n<p>A parte questo, il metodo funziona benissimo per migliorare la funzionalit\u00e0 delle classi in modo dinamico.<\/p>\n<h2>Le Migliori Pratiche per Implementare i Design Pattern<\/h2>\n<p>Ora che avete visto i design pattern pi\u00f9 comuni in JavaScript, ecco alcuni consigli che dovreste tenere a mente quando li implementate.<\/p>\n<h3>Prestare Particolare Attenzione a Capire Se un Modello Si Adatta alla Soluzione<\/h3>\n<p>Questo consiglio va applicato prima di implementare un design pattern nel vostro codice sorgente. Anche se pu\u00f2 sembrare che un design pattern sia la fine di tutte le vostre preoccupazioni, prendetevi un momento per analizzare criticamente se questo \u00e8 vero.<\/p>\n<p>Ci sono molti modelli che risolvono lo stesso problema ma con approcci diversi e conseguenze diverse. Quindi il criterio di selezione di un design pattern non dovrebbe essere solo se risolve o meno il vostro problema, ma anche quanto bene lo risolve e se c&#8217;\u00e8 qualche altro pattern che pu\u00f2 presentare una soluzione pi\u00f9 efficiente.<\/p>\n<h3>Comprendere i Costi dell&#8217;Implementazione di un Pattern Prima di Iniziare<\/h3>\n<p>Anche se i design pattern sembrano essere la soluzione migliore per tutti i <a href=\"https:\/\/kinsta.com\/it\/blog\/errori-in-javascript\/\">problemi ingegneristici<\/a>, non dovreste lanciarvi subito nell&#8217;implementazione nel vostro codice sorgente.<\/p>\n<p>Nel valutare le conseguenze dell&#8217;implementazione di una soluzione, dovete prendere in considerazione anche la vostra situazione. Avete un team di sviluppo software numeroso con persone esperte nella comprensione e nella manutenzione dei design pattern? Oppure siete nella fase iniziale della vostra attivit\u00e0 con un team di sviluppo minimo e volete rilasciare un MVP veloce del vostro prodotto? Se la risposta all&#8217;ultima domanda \u00e8 s\u00ec, i design pattern potrebbero non essere il metodo di sviluppo pi\u00f9 adatto a voi.<\/p>\n<p>I design pattern non portano a un riutilizzo massiccio del codice a meno che non siano pianificati in una fase molto precoce della progettazione dell&#8217;applicazione. L&#8217;utilizzo casuale dei design pattern in varie fasi pu\u00f2 portare a un&#8217;architettura dell&#8217;app inutilmente complessa che dovrete semplificare per settimane.<\/p>\n<p>L&#8217;efficacia di un design pattern non pu\u00f2 essere giudicata da alcuna forma di test. Saranno l&#8217;<a href=\"https:\/\/kinsta.com\/it\/blog\/strumenti-di-revisione-del-codice\/\">esperienza e l&#8217;introspezione del team<\/a> a farvi capire se funzionano. Se avete il tempo e le risorse da dedicare a questi aspetti, solo allora i design pattern risolveranno davvero i vostri problemi.<\/p>\n<h3>Non Trasformare Ogni Soluzione in un Modello<\/h3>\n<p>Un&#8217;altra regola da tenere a mente \u00e8 quella di non cercare di trasformare ogni piccolo problema-soluzione in un design pattern e di utilizzarlo ovunque ci sia spazio per esso.<\/p>\n<p>Anche se \u00e8 bene identificare soluzioni standard e tenerle a mente quando si incontrano problemi simili, \u00e8 molto probabile che il nuovo problema incontrato non corrisponda esattamente alla stessa descrizione di un problema precedente. In questo caso, potreste finire per implementare una soluzione non ottimale e sprecare risorse.<\/p>\n<p>I design pattern si sono affermati oggi come esempi principali di coppie problema-soluzione perch\u00e9 sono stati testati da centinaia e migliaia di programmatori nel corso del tempo e sono stati generalizzati il pi\u00f9 possibile. Se cercate di replicare questo sforzo limitandovi a esaminare un gruppo di problemi e soluzioni e a definirli simili, potreste finire per danneggiare il vostro codice molto pi\u00f9 di quanto vi sareste mai aspettati.<\/p>\n<h2>Quando Usare i Design Pattern?<\/h2>\n<p>Per riassumere, ecco alcuni spunti che dovreste tenere in considerazione per usare i design pattern. Non tutti si applicano allo sviluppo di ogni applicazione, ma dovrebbero darvi una buona idea di cosa tenere d&#8217;occhio quando pensate di usare i design pattern:<\/p>\n<ul>\n<li>Avete un team di sviluppo interno molto forte che conosce bene i design pattern.<\/li>\n<li>State seguendo un modello SDLC che lascia spazio a discussioni approfondite sull&#8217;architettura della vostra applicazione e i design pattern sono emersi in queste discussioni.<\/li>\n<li>La stessa serie di problemi \u00e8 emersa pi\u00f9 volte nelle discussioni di progettazione e voi conoscete il design pattern pi\u00f9 adatto al caso.<\/li>\n<li>Avete provato a risolvere una piccola variante del vostro problema in modo indipendente con il design pattern.<\/li>\n<li>Grazie al design pattern, il vostro codice non sembra eccessivamente complesso.<\/li>\n<\/ul>\n<p>Se un design pattern risolve il vostro problema <em>e<\/em> vi aiuta a scrivere codice semplice, riutilizzabile, modulare, con basso accoppiamento e senza &#8220;code smell&#8221;, potrebbe essere la strada giusta da percorrere.<\/p>\n<p>Un altro buon consiglio da tenere a mente \u00e8 evitare di ruotare tutto intorno ai design pattern. I design pattern servono per aiutarvi a risolvere i problemi. Non sono leggi da rispettare o regole da seguire rigorosamente. Le regole e le leggi fondamentali sono sempre le stesse: mantenere il codice pulito, semplice, leggibile e scalabile. Se un design pattern vi aiuta a raggiungere questi obiettivi e a risolvere il problema, allora potete andare tranquilli.<\/p>\n<h2>Riepilogo<\/h2>\n<p>I design pattern di JavaScript sono un modo meraviglioso di affrontare i problemi che molti programmatori hanno affrontato nel corso del tempo. Presentano soluzioni collaudate che si sforzano di mantenere la vostra codebase pulita e non vincolata.<\/p>\n<p>Oggi sono disponibili <a href=\"https:\/\/sourcemaking.com\/design-patterns-and-tips\">centinaia di design pattern<\/a> in grado di risolvere quasi tutti i problemi che si incontrano durante la creazione di applicazioni. Tuttavia, non tutti i design pattern <em>risolvono<\/em> sempre il vostro problema.<br \/>\n<\/p>\n<p>Proprio come qualsiasi <a href=\"https:\/\/kinsta.com\/it\/blog\/best-practice-react\/\">altra convenzione di programmazione<\/a>, i design pattern devono essere considerati come suggerimenti per risolvere i problemi. Non sono leggi da seguire sempre e se li trattate come tali, potreste finire per danneggiare le vostre applicazioni.<\/p>\n<p>Una volta terminata la vostra app, avrete bisogno di un luogo dove ospitarla e le <a href=\"https:\/\/sevalla.com\/application-hosting\/\">soluzioni di hosting di applicazioni di Kinsta<\/a> sono tra le pi\u00f9 veloci, affidabili e sicure. Dovete solo accedere al vostro <a href=\"https:\/\/kinsta.com\/it\/mykinsta\/\">account MyKinsta<\/a> (il cruscotto di amministrazione personalizzato di Kinsta), collegarvi al vostro <a href=\"https:\/\/kinsta.com\/it\/blog\/cosa-e-github\/\">repository GitHub<\/a> e lanciarlo! Inoltre vi verranno addebitate solo le risorse utilizzate dalla vostra applicazione.<\/p>\n<p>Quali sono i design pattern che usate regolarmente nel vostro lavoro di programmazione software? Oppure c&#8217;\u00e8 un pattern che ci \u00e8 sfuggito e andrebbe messo in elenco? Fatecelo sapere nei commenti qui sotto!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Quando si sviluppano applicazioni JavaScript, si potrebbe aver bisogno di creare oggetti in un certo modo predefinito o di riutilizzare una classe modificandola o adattandola a &#8230;<\/p>\n","protected":false},"author":238,"featured_media":65305,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kinsta_gated_content":false,"_kinsta_gated_content_redirect":"","footnotes":""},"tags":[],"topic":[25847],"class_list":["post-65304","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","topic-tutorial-javascript"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v24.6 (Yoast SEO v24.6) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Guida Completa ai Design Pattern di JavaScript<\/title>\n<meta name=\"description\" content=\"Esistono molti design pattern in JavaScript che possono farti risparmiare tempo e fatica. Leggi la nostra guida.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Guida Completa ai Design Pattern di JavaScript\" \/>\n<meta property=\"og:description\" content=\"Esistono molti design pattern in JavaScript che possono farti risparmiare tempo e fatica. Leggi la nostra guida.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/\" \/>\n<meta property=\"og:site_name\" content=\"Kinsta\u00ae\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/kinstaitalia\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-02-14T08:21:35+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-03-02T09:21:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/02\/javascript-design-patterns.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1460\" \/>\n\t<meta property=\"og:image:height\" content=\"730\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Kumar Harsh\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:description\" content=\"Esistono molti design pattern in JavaScript che possono farti risparmiare tempo e fatica. Leggi la nostra guida.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/02\/javascript-design-patterns.png\" \/>\n<meta name=\"twitter:creator\" content=\"@Kinsta_IT\" \/>\n<meta name=\"twitter:site\" content=\"@Kinsta_IT\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Kumar Harsh\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"52 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/\"},\"author\":{\"name\":\"Kumar Harsh\",\"@id\":\"https:\/\/kinsta.com\/it\/#\/schema\/person\/3a80efffa9cbb0333cc9c22b754415d9\"},\"headline\":\"Guida Completa ai Design Pattern di JavaScript\",\"datePublished\":\"2023-02-14T08:21:35+00:00\",\"dateModified\":\"2023-03-02T09:21:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/\"},\"wordCount\":5804,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/it\/#organization\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/02\/javascript-design-patterns.png\",\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/\",\"url\":\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/\",\"name\":\"Guida Completa ai Design Pattern di JavaScript\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/it\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/02\/javascript-design-patterns.png\",\"datePublished\":\"2023-02-14T08:21:35+00:00\",\"dateModified\":\"2023-03-02T09:21:21+00:00\",\"description\":\"Esistono molti design pattern in JavaScript che possono farti risparmiare tempo e fatica. Leggi la nostra guida.\",\"breadcrumb\":{\"@id\":\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#primaryimage\",\"url\":\"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/02\/javascript-design-patterns.png\",\"contentUrl\":\"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/02\/javascript-design-patterns.png\",\"width\":1460,\"height\":730},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/kinsta.com\/it\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Tutorial JavaScript\",\"item\":\"https:\/\/kinsta.com\/it\/argomenti\/tutorial-javascript\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Guida Completa ai Design Pattern di JavaScript\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/kinsta.com\/it\/#website\",\"url\":\"https:\/\/kinsta.com\/it\/\",\"name\":\"Kinsta\u00ae\",\"description\":\"Soluzioni di hosting premium, veloci e sicure\",\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/it\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/kinsta.com\/it\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/kinsta.com\/it\/#organization\",\"name\":\"Kinsta\",\"url\":\"https:\/\/kinsta.com\/it\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/kinsta.com\/it\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/12\/kinsta-logo.jpeg\",\"contentUrl\":\"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/12\/kinsta-logo.jpeg\",\"width\":500,\"height\":500,\"caption\":\"Kinsta\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/it\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/kinstaitalia\/\",\"https:\/\/x.com\/Kinsta_IT\",\"https:\/\/www.instagram.com\/kinstahosting\/\",\"https:\/\/www.linkedin.com\/company\/kinsta\/\",\"https:\/\/www.pinterest.com\/kinstahosting\/\",\"https:\/\/www.youtube.com\/c\/Kinsta\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/kinsta.com\/it\/#\/schema\/person\/3a80efffa9cbb0333cc9c22b754415d9\",\"name\":\"Kumar Harsh\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/kinsta.com\/it\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/de2d8d6273bdcc3dfa2f8270428f95b2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/de2d8d6273bdcc3dfa2f8270428f95b2?s=96&d=mm&r=g\",\"caption\":\"Kumar Harsh\"},\"description\":\"Kumar is a software developer and a technical author based in India. He specializes in JavaScript and DevOps. You can learn more about his work on his website.\",\"sameAs\":[\"https:\/\/kumarharsh.me\"],\"url\":\"https:\/\/kinsta.com\/it\/blog\/author\/kumarharsh\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Guida Completa ai Design Pattern di JavaScript","description":"Esistono molti design pattern in JavaScript che possono farti risparmiare tempo e fatica. Leggi la nostra guida.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/","og_locale":"it_IT","og_type":"article","og_title":"Guida Completa ai Design Pattern di JavaScript","og_description":"Esistono molti design pattern in JavaScript che possono farti risparmiare tempo e fatica. Leggi la nostra guida.","og_url":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/","og_site_name":"Kinsta\u00ae","article_publisher":"https:\/\/www.facebook.com\/kinstaitalia\/","article_published_time":"2023-02-14T08:21:35+00:00","article_modified_time":"2023-03-02T09:21:21+00:00","og_image":[{"width":1460,"height":730,"url":"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/02\/javascript-design-patterns.png","type":"image\/png"}],"author":"Kumar Harsh","twitter_card":"summary_large_image","twitter_description":"Esistono molti design pattern in JavaScript che possono farti risparmiare tempo e fatica. Leggi la nostra guida.","twitter_image":"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/02\/javascript-design-patterns.png","twitter_creator":"@Kinsta_IT","twitter_site":"@Kinsta_IT","twitter_misc":{"Scritto da":"Kumar Harsh","Tempo di lettura stimato":"52 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#article","isPartOf":{"@id":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/"},"author":{"name":"Kumar Harsh","@id":"https:\/\/kinsta.com\/it\/#\/schema\/person\/3a80efffa9cbb0333cc9c22b754415d9"},"headline":"Guida Completa ai Design Pattern di JavaScript","datePublished":"2023-02-14T08:21:35+00:00","dateModified":"2023-03-02T09:21:21+00:00","mainEntityOfPage":{"@id":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/"},"wordCount":5804,"commentCount":0,"publisher":{"@id":"https:\/\/kinsta.com\/it\/#organization"},"image":{"@id":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/02\/javascript-design-patterns.png","inLanguage":"it-IT","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/","url":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/","name":"Guida Completa ai Design Pattern di JavaScript","isPartOf":{"@id":"https:\/\/kinsta.com\/it\/#website"},"primaryImageOfPage":{"@id":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#primaryimage"},"image":{"@id":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/02\/javascript-design-patterns.png","datePublished":"2023-02-14T08:21:35+00:00","dateModified":"2023-03-02T09:21:21+00:00","description":"Esistono molti design pattern in JavaScript che possono farti risparmiare tempo e fatica. Leggi la nostra guida.","breadcrumb":{"@id":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/"]}]},{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#primaryimage","url":"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/02\/javascript-design-patterns.png","contentUrl":"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/02\/javascript-design-patterns.png","width":1460,"height":730},{"@type":"BreadcrumbList","@id":"https:\/\/kinsta.com\/it\/blog\/pattern-javascript-design\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/kinsta.com\/it\/"},{"@type":"ListItem","position":2,"name":"Tutorial JavaScript","item":"https:\/\/kinsta.com\/it\/argomenti\/tutorial-javascript\/"},{"@type":"ListItem","position":3,"name":"Guida Completa ai Design Pattern di JavaScript"}]},{"@type":"WebSite","@id":"https:\/\/kinsta.com\/it\/#website","url":"https:\/\/kinsta.com\/it\/","name":"Kinsta\u00ae","description":"Soluzioni di hosting premium, veloci e sicure","publisher":{"@id":"https:\/\/kinsta.com\/it\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/kinsta.com\/it\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"it-IT"},{"@type":"Organization","@id":"https:\/\/kinsta.com\/it\/#organization","name":"Kinsta","url":"https:\/\/kinsta.com\/it\/","logo":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/kinsta.com\/it\/#\/schema\/logo\/image\/","url":"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/12\/kinsta-logo.jpeg","contentUrl":"https:\/\/kinsta.com\/it\/wp-content\/uploads\/sites\/2\/2023\/12\/kinsta-logo.jpeg","width":500,"height":500,"caption":"Kinsta"},"image":{"@id":"https:\/\/kinsta.com\/it\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/kinstaitalia\/","https:\/\/x.com\/Kinsta_IT","https:\/\/www.instagram.com\/kinstahosting\/","https:\/\/www.linkedin.com\/company\/kinsta\/","https:\/\/www.pinterest.com\/kinstahosting\/","https:\/\/www.youtube.com\/c\/Kinsta"]},{"@type":"Person","@id":"https:\/\/kinsta.com\/it\/#\/schema\/person\/3a80efffa9cbb0333cc9c22b754415d9","name":"Kumar Harsh","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/kinsta.com\/it\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/de2d8d6273bdcc3dfa2f8270428f95b2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/de2d8d6273bdcc3dfa2f8270428f95b2?s=96&d=mm&r=g","caption":"Kumar Harsh"},"description":"Kumar is a software developer and a technical author based in India. He specializes in JavaScript and DevOps. You can learn more about his work on his website.","sameAs":["https:\/\/kumarharsh.me"],"url":"https:\/\/kinsta.com\/it\/blog\/author\/kumarharsh\/"}]}},"acf":[],"_links":{"self":[{"href":"https:\/\/kinsta.com\/it\/wp-json\/wp\/v2\/posts\/65304","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kinsta.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kinsta.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kinsta.com\/it\/wp-json\/wp\/v2\/users\/238"}],"replies":[{"embeddable":true,"href":"https:\/\/kinsta.com\/it\/wp-json\/wp\/v2\/comments?post=65304"}],"version-history":[{"count":15,"href":"https:\/\/kinsta.com\/it\/wp-json\/wp\/v2\/posts\/65304\/revisions"}],"predecessor-version":[{"id":65964,"href":"https:\/\/kinsta.com\/it\/wp-json\/wp\/v2\/posts\/65304\/revisions\/65964"}],"alternate":[{"embeddable":true,"hreflang":"en","title":"English","href":"https:\/\/kinsta.com\/it\/wp-json\/kinsta\/v1\/posts\/65304\/translations\/en"},{"embeddable":true,"hreflang":"it","title":"Italian","href":"https:\/\/kinsta.com\/it\/wp-json\/kinsta\/v1\/posts\/65304\/translations\/it"},{"embeddable":true,"hreflang":"pt","title":"Portuguese","href":"https:\/\/kinsta.com\/it\/wp-json\/kinsta\/v1\/posts\/65304\/translations\/pt"},{"embeddable":true,"hreflang":"fr","title":"French","href":"https:\/\/kinsta.com\/it\/wp-json\/kinsta\/v1\/posts\/65304\/translations\/fr"},{"embeddable":true,"hreflang":"de","title":"German","href":"https:\/\/kinsta.com\/it\/wp-json\/kinsta\/v1\/posts\/65304\/translations\/de"},{"embeddable":true,"hreflang":"ja","title":"Japanese","href":"https:\/\/kinsta.com\/it\/wp-json\/kinsta\/v1\/posts\/65304\/translations\/jp"},{"embeddable":true,"hreflang":"nl","title":"Dutch","href":"https:\/\/kinsta.com\/it\/wp-json\/kinsta\/v1\/posts\/65304\/translations\/nl"},{"embeddable":true,"hreflang":"es","title":"Spanish","href":"https:\/\/kinsta.com\/it\/wp-json\/kinsta\/v1\/posts\/65304\/translations\/es"},{"embeddable":true,"hreflang":"sv","title":"Swedish","href":"https:\/\/kinsta.com\/it\/wp-json\/kinsta\/v1\/posts\/65304\/translations\/se"},{"embeddable":true,"hreflang":"da","title":"Danish","href":"https:\/\/kinsta.com\/it\/wp-json\/kinsta\/v1\/posts\/65304\/translations\/dk"},{"href":"https:\/\/kinsta.com\/it\/wp-json\/kinsta\/v1\/posts\/65304\/tree"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kinsta.com\/it\/wp-json\/wp\/v2\/media\/65305"}],"wp:attachment":[{"href":"https:\/\/kinsta.com\/it\/wp-json\/wp\/v2\/media?parent=65304"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kinsta.com\/it\/wp-json\/wp\/v2\/tags?post=65304"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/kinsta.com\/it\/wp-json\/wp\/v2\/topic?post=65304"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}