{"id":26729,"date":"2020-04-29T00:00:00","date_gmt":"2020-04-28T22:00:00","guid":{"rendered":"https:\/\/blexin.com\/?p=26729"},"modified":"2021-05-21T18:58:12","modified_gmt":"2021-05-21T16:58:12","slug":"golden-master-pattern-codice-legacy-non-ti-temo","status":"publish","type":"post","link":"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/","title":{"rendered":"Golden Master Pattern: codice legacy non ti temo!"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"608\" data-attachment-id=\"26723\" data-permalink=\"https:\/\/blexin.com\/it\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?fit=1024%2C608&amp;ssl=1\" data-orig-size=\"1024,608\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"fe85ca6d-91d7-4ead-9d01-d4adddef4e5e\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?fit=1024%2C608&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?resize=1024%2C608&#038;ssl=1\" alt=\"\" class=\"wp-image-26723\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e-980x582.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e-480x285.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Chiunque lavori nel mondo dello sviluppo software avr\u00e0 avuto l\u2019esigenza di aggiungere feature al codice legacy, ereditato magari dal precedente team e su cui fare una fix urgentissima.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tra le tante definizioni di codice legacy che si trovano in letteratura, quella che preferisco \u00e8: &#8220;per&nbsp;<strong>Legacy code<\/strong>&nbsp;si intende il&nbsp;<strong>codice utile<\/strong>&nbsp;che ho&nbsp;<strong>paura<\/strong>&nbsp;di modificare&#8221;. Se ci pensate, esprime due concetti fondamentali:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Il codice deve essere utile, avere valore. Se non ha valore ci sar\u00e0 poco interesse e quindi poca volont\u00e0 di modificarlo.&nbsp;<\/li><li>Deve generare&nbsp;<em>paura di modificarlo,<\/em>&nbsp;perch\u00e9 potrebbero introdurre nuovi bug o rompere parti di codice con dipendenze nascoste.<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">La facilit\u00e0 di commettere errori aumenta quando:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Il codice non \u00e8 coperto da test.<\/li><li>Il codice \u00e8 poco pulito;&nbsp;non \u00e8 rispettato il principio di singola responsabilit\u00e0.<\/li><li>Il codice \u00e8 mal pensato&nbsp;o \u00e8 diventato mal strutturato nel tempo: modificare un pezzo di codice pu\u00f2 comportare molti side effects.<\/li><li>Non si ha a disposizione il tempo necessario per avere una conoscenza approfondita di quello che si sta modificando.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Un\u2019arma che abbiamo a disposizione come sviluppatori \u00e8 quella dei test. I test ci forniscono sicurezza sul risultato e ci danno un modo per rilevare velocemente eventuali errori commessi. Ma come possiamo testare codice che non conosciamo? Realizzare una suite di&nbsp;<em>Unit Test<\/em>&nbsp;ci fornirebbe un\u2019approfondita conoscenza del progetto, ma avrebbe anche un costo elevato. Se per\u00f2 non possiamo testare i dettagli, possiamo strutturare dei&nbsp;<strong>Characterization Test<\/strong>, ovvero dei test che descrivono il comportamento di un pezzo di software.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Un pattern che ci viene in aiuto in queste situazioni \u00e8 chiamato&nbsp;<strong>Golden Master Pattern<\/strong>. L&#8217;idea alla base \u00e8 molto semplice: non potendo entrare nei dettagli, bisogna provare a fotografare l&#8217;intera esecuzione. Catturiamo l&#8217;output (stdout, immagini, file di log, ecc.) di un\u2019esecuzione corretta e questo sar\u00e0 il nostro Golden Master, che useremo come output atteso di una esecuzione corretta del codice. Se l&#8217;output dell&#8217;esecuzione attuale corrisponde, possiamo essere fiduciosi che le modifiche non avranno introdotto errori.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Per mostrare l&#8217;applicazione del&nbsp;<strong>Golden Master Pattern,<\/strong>&nbsp;partiamo da un esempio (il codice completo lo trovate&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/ntonjeta\/GoldenMasterExample\" target=\"_blank\">qui<\/a>). La nostra compagnia sviluppa giochi per command line, tra cui il gioco del Tris (l\u2019implementazione \u00e8 presa da&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/www.c-sharpcorner.com\/UploadFile\/75a48f\/tic-tac-toe-game-in-C-Sharp\/\" target=\"_blank\">qui<\/a>), di cui ci viene chiesta una modifica per ridimensionare a piacere la griglia di gioco. Diamo uno sguardo al codice:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nnamespace Tris\n{\n\u00a0\u00a0\u00a0\u00a0public class Game\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/making array and\u00a0\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/by default I am providing 0-9 where no use of zero\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0static char&#x5B;] arr = { &#039;0&#039;, &#039;1&#039;, &#039;2&#039;, &#039;3&#039;, &#039;4&#039;, &#039;5&#039;, &#039;6&#039;, &#039;7&#039;, &#039;8&#039;, &#039;9&#039; };\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0static int player = 1; \/\/By default player 1 is set\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0static int choice; \/\/This holds the choice at which position user want to mark\u00a0\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ The flag variable checks who has won if its value is 1 then someone has won the match if -1 then Match has Draw if 0 then match is still running\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0static int flag = 0;\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0public static void run()\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0do\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.Clear();\/\/ whenever loop will be again start then screen will be clear\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;Player1:X and Player2:O&quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;\\n&quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (player % 2 == 0)\/\/checking the chance of the player\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;Player 2 Chance&quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;Player 1 Chance&quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;\\n&quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Board();\/\/ calling the board Function\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0choice = int.Parse(Console.ReadLine());\/\/Taking users choice\u00a0\u00a0 \n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ checking that position where user want to run is marked (with X or O) or not\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (arr&#x5B;choice] != &#039;X&#039; &amp;&amp; arr&#x5B;choice] != &#039;O&#039;)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (player % 2 == 0) \/\/if chance is of player 2 then mark O else mark X\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0arr&#x5B;choice] = &#039;O&#039;;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0player++;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0arr&#x5B;choice] = &#039;X&#039;;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0player++;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else \/\/If there is any position where user wants to run and that is already marked then show message and load board again\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;Sorry the row {0} is already marked with {1}&quot;, choice, arr&#x5B;choice]);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;\\n&quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;Please wait 2 second board is loading again.....&quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Thread.Sleep(2000);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0flag = CheckWin();\/\/ calling of check win\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} while (flag != 1 &amp;&amp; flag != -1);\/\/ This loof will be run until all cell of the grid is not marked with X and O or some player is not winner \n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.Clear();\/\/ clearing the console\u00a0 \n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Board();\/\/ getting filled board again\u00a0 \n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (flag == 1)\/\/ if flag value is 1 then someone has win or means who played marked last time which has win\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;Player {0} has won&quot;, (player % 2) + 1);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\/\/ if flag value is -1 the match will be drawn and no one is the winner\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;Draw&quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.ReadLine();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Board method which creats board\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0private static void Board()\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0 &quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;\u00a0 {0}\u00a0 |\u00a0 {1}\u00a0 |\u00a0 {2}&quot;, arr&#x5B;1], arr&#x5B;2], arr&#x5B;3]);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;_____|_____|_____ &quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0 &quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;\u00a0 {0}\u00a0 |\u00a0 {1}\u00a0 |\u00a0 {2}&quot;, arr&#x5B;4], arr&#x5B;5], arr&#x5B;6]);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;_____|_____|_____ &quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0 &quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;\u00a0 {0}\u00a0 |\u00a0 {1}\u00a0 |\u00a0 {2}&quot;, arr&#x5B;7], arr&#x5B;8], arr&#x5B;9]);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0 &quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0private static int CheckWin()\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0#region Horzontal Winning Condtion\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/Winning Condition For First Row\u00a0\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (arr&#x5B;1] == arr&#x5B;2] &amp;&amp; arr&#x5B;2] == arr&#x5B;3])\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/Winning Condition For Second Row\u00a0\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else if (arr&#x5B;4] == arr&#x5B;5] &amp;&amp; arr&#x5B;5] == arr&#x5B;6])\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/Winning Condition For Third Row\u00a0\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else if (arr&#x5B;6] == arr&#x5B;7] &amp;&amp; arr&#x5B;7] == arr&#x5B;8])\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0#endregion\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0#region vertical Winning Condtion\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/Winning Condition For First Column\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else if (arr&#x5B;1] == arr&#x5B;4] &amp;&amp; arr&#x5B;4] == arr&#x5B;7])\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/Winning Condition For Second Column\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else if (arr&#x5B;2] == arr&#x5B;5] &amp;&amp; arr&#x5B;5] == arr&#x5B;8])\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/Winning Condition For Third Column\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else if (arr&#x5B;3] == arr&#x5B;6] &amp;&amp; arr&#x5B;6] == arr&#x5B;9])\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0#endregion\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0#region Diagonal Winning Condition\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else if (arr&#x5B;1] == arr&#x5B;5] &amp;&amp; arr&#x5B;5] == arr&#x5B;9])\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else if (arr&#x5B;3] == arr&#x5B;5] &amp;&amp; arr&#x5B;5] == arr&#x5B;7])\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0#endregion\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0#region Checking For Draw\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ If all the cells or values filled with X or O then any player has won the match\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else if (arr&#x5B;1] != &#039;1&#039; &amp;&amp; arr&#x5B;2] != &#039;2&#039; &amp;&amp; arr&#x5B;3] != &#039;3&#039; &amp;&amp; arr&#x5B;4] != &#039;4&#039; &amp;&amp; arr&#x5B;5] != &#039;5&#039; &amp;&amp; arr&#x5B;6] != &#039;6&#039; &amp;&amp; arr&#x5B;7] != &#039;7&#039; &amp;&amp; arr&#x5B;8] != &#039;8&#039; &amp;&amp; arr&#x5B;9] != &#039;9&#039;)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return -1;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0#endregion\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 0;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Ad una lettura veloce, il codice risulta confuso, le responsabilit\u00e0 non sono ben separate e i nomi delle variabili sono poco significativi. Dopo una lettura pi\u00f9 approfondita, si riesce a vedere che la griglia di gioco viene memorizzata in un `static char[] arr&#8217;. Aggiungere semplicemente elementi all&#8217;array non \u00e8 efficace perch\u00e9 nelle funzioni PrintBoard e CheckWin vi si accede con indici costanti. Capiamo quindi che, per ridimensionare la griglia, dobbiamo modificare in pi\u00f9 parti il codice.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Creiamo un progetto e lanciamo il nostro gioco:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nclass Program\n{\n\u00a0\u00a0\u00a0\u00a0static void Main(string&#x5B;] args)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Game.run();\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Dopo aver stampato la board, il gioco resta in attesa dell&#8217;input del primo giocatore. Possiamo automatizzare l&#8217;input facendolo leggere da file.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nclass Program\n{\n\u00a0\u00a0\u00a0\u00a0private const string InputPath = &quot;input.txt&quot;;\n\u00a0\n\u00a0\u00a0\u00a0\u00a0public static void Main(string&#x5B;] args)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var input = new StreamReader(new FileStream(InputPath, FileMode.Open));\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.SetIn(input);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Game.run();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0input.Close();\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">L&#8217;insieme di tutti i possibili input \u00e8 troppo ampio per un testing brute-force. Quello che possiamo fare \u00e8 campionare i valori considerando i possibili risultati di una partita di Tris:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Vittoria giocatore 1<\/li><li>Vittoria giocatore 2<\/li><li>Pareggio<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Selezioniamo quindi il set minimo di test per coprire tutti i casi, scrivendo i tre path in file di testo nella cartella input e raccogliendo i risultati nelle cartella goldenMaster:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nclass Program\n{\n\u00a0\u00a0\u00a0\u00a0private const string InputFolderPath = &quot;input\/&quot;;\n\u00a0\u00a0\u00a0\u00a0private const string OutputFolderPath = &quot;goldenMaster\/&quot;;\n\u00a0\n\u00a0\u00a0\u00a0\u00a0public static void Main(string&#x5B;] args)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0int i = 1;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0foreach (var filePath in Directory.GetFiles(InputFolderPath)) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var input = new StreamReader(new FileStream(filePath, FileMode.Open));\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var output = new StreamWriter(new FileStream(OutputFolderPath + &quot;output&quot; + i.ToString() + &quot;.txt&quot; , FileMode.CreateNew));\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.SetIn(input);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.SetOut(output);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Game.run();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0input.Close();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0output.Close();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0i++;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">I tre file rappresentano i nostri Golden Master, da cui possiamo sviluppare dei Characterization Test:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n&#x5B;Test]\npublic void WinPlayerOne()\n{\n\u00a0\u00a0\u00a0\u00a0inputPath = InputFolderPath + &quot;input1.txt&quot;;\n\u00a0\u00a0\u00a0\u00a0outputPath = OutputFolderPath + &quot;output.txt&quot;;\n\u00a0\u00a0\u00a0\u00a0var goldenMasterOutput = GoldenMasterOutput + &quot;output1.txt&quot;;\n\u00a0\n\u00a0\u00a0\u00a0\u00a0var input = new StreamReader(new FileStream(inputPath, FileMode.Open));\n\u00a0\u00a0\u00a0\u00a0var output = new StreamWriter(new FileStream(outputPath, FileMode.CreateNew));\n\u00a0\u00a0\u00a0\u00a0Console.SetIn(input);\n\u00a0\u00a0\u00a0\u00a0Console.SetOut(output);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0Game.run();\n\u00a0\n\u00a0\u00a0\u00a0\u00a0input.Close();\n\u00a0\u00a0\u00a0\u00a0output.Close();\n\u00a0\n\u00a0\u00a0\u00a0\u00a0Assert.True(AreFileEquals(goldenMasterOutput, outputPath));\n}\n\u00a0\nprivate bool AreFileEquals(string expectedPath, string actualPath)\n{\n\u00a0\u00a0\u00a0\u00a0byte&#x5B;] bytes1 = Encoding.Convert(Encoding.ASCII, Encoding.ASCII, Encoding.ASCII.GetBytes(File.ReadAllText(expectedPath)));\n\u00a0\u00a0\u00a0\u00a0byte&#x5B;] bytes2 = Encoding.Convert(Encoding.ASCII, Encoding.ASCII, Encoding.ASCII.GetBytes(File.ReadAllText(actualPath)));\n\u00a0\n\u00a0\u00a0\u00a0\u00a0return bytes1.SequenceEqual(bytes2);\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Finch\u00e9 i test sono verdi possiamo fare refactoring senza paura di rompere qualcosa. Un possibile risultato potrebbe essere il seguente:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic static void run()\n{\n\u00a0\u00a0\u00a0\u00a0char&#x5B;] board = { &#039;0&#039;, &#039;1&#039;, &#039;2&#039;, &#039;3&#039;, &#039;4&#039;, &#039;5&#039;, &#039;6&#039;, &#039;7&#039;, &#039;8&#039;, &#039;9&#039; };\n\u00a0\u00a0\u00a0\u00a0int actualPlayer = 1;\n\u00a0\n\u00a0\u00a0\u00a0\u00a0while (CheckWin(board) == 0)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0PrintPlayerChoise(actualPlayer);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0PrintBoard(board);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var choice = ReadPlayerChoise();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (isBoardCellAlreadyTaken(board&#x5B;choice]))\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0PrintCellIsAlreadyMarketMessage(board&#x5B;choice], choice);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0continue;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0board&#x5B;choice] = GetPlayerMarker(actualPlayer);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0actualPlayer = UpdatePlayer(actualPlayer);\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0PrintResult(board, actualPlayer);\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Da questo blocco emerge pi\u00f9 chiaramente il concetto di Board e delle sue responsabilit\u00e0. Proviamo a estrarne il comportamento in una nuova classe&nbsp;<strong>Board<\/strong>. La nostra nuova Board dovrebbe essere in grado di:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Stampare la griglia.<\/li><li>Segnare la scelta del giocatore.<\/li><li>Controllare che ci sia un vincitore.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Sfruttiamo un approccio TDD (maggiori dettagli in questo&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/www.blexin.com\/it-IT\/Article\/Blog\/TDD-tutto-il-codice--colpevole-fino-a-prova-contraria-38\" target=\"_blank\">articolo di Adolfo<\/a>) per sviluppare una Board in grado di ridimensionarsi (trovate il codice dei test&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/ntonjeta\/GoldenMasterExample\/blob\/master\/test\/GoldenMasterExampleTest\/BoardShould.cs\" target=\"_blank\">qui<\/a>, mentre quello della classe&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/ntonjeta\/GoldenMasterExample\/blob\/master\/lib\/Game\/Board.cs\" target=\"_blank\">qui<\/a>) e andiamo a inserirla nel gioco, controllando che i Golden Master Test restino verdi:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nprivate const int Boardsize = 3;\n\u00a0\npublic static void run()\n{\n\u00a0\u00a0\u00a0\u00a0Board board = new Board(Boardsize);\n\u00a0\u00a0\u00a0\u00a0int actualPlayer = 1;\n\u00a0\n\u00a0\u00a0\u00a0\u00a0while (board.CheckWin() == -1)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0PrintPlayerChoise(actualPlayer);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(board.Print());\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var choice = ReadPlayerChoise();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (!board.UpdateBoard(actualPlayer, choice))\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0PrintCellIsAlreadyMarketMessage(board.GetCellValue(choice), choice);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0continue;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0actualPlayer = UpdatePlayer(actualPlayer);\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0PrintResult(board, actualPlayer);\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">A questo punto possiamo ripristinare lo stdin\/stdout e leggere la dimensione della griglia dall&#8217;utente:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nclass Program\n{\n\u00a0\u00a0\u00a0\u00a0public static void Main(string&#x5B;] args)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;Insert Diagonal dimension of Board: &quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var boardSize = int.Parse(Console.ReadLine());\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Game.run(boardSize);\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Come avete visto, grazie al Golden Master Pattern siamo riusciti a dominare il codice legacy e abbiamo potuto fare refactoring senza paure. Ma non \u00e8 tutto oro quel che luccica: applicare il Golden Master pu\u00f2 risultare ostico in caso di \u201c<em>noise output<\/em>\u201d, l&#8217;output, cio\u00e8, che \u00e8 inutile ai fini dell&#8217;esecuzione e che varia nel tempo (es. timestamp, thread name, ecc.). In questi casi bisogna filtrare l&#8217;output e considerare solo la parte significativa.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Spero possa tornarvi utile la prossima volta che erediterete un progetto legacy: in fondo ci fa paura solo quello che non possiamo controllare!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Alla prossima<\/p>\n\n\n\n\n","protected":false},"excerpt":{"rendered":"<p>Vediamo insieme come modificare codice legacy garantendone il funzionamento grazie al Golden Master Pattern<\/p>\n","protected":false},"author":196716249,"featured_media":26723,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"","_et_gb_content_width":"","_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_crdt_document":"","inline_featured_image":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false},"categories":[688637374],"tags":[688637541,688637382],"class_list":["post-26729","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-dotnetcore","tag-c"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Golden Master Pattern: codice legacy non ti temo! - Blexin<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Golden Master Pattern: codice legacy non ti temo! - Blexin\" \/>\n<meta property=\"og:description\" content=\"Vediamo insieme come modificare codice legacy garantendone il funzionamento grazie al Golden Master Pattern\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/\" \/>\n<meta property=\"og:site_name\" content=\"Blexin\" \/>\n<meta property=\"article:published_time\" content=\"2020-04-28T22:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-05-21T16:58:12+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i1.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?fit=1024%2C608&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"608\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Antonio Tammaro\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Antonio Tammaro\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/golden-master-pattern-codice-legacy-non-ti-temo\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/golden-master-pattern-codice-legacy-non-ti-temo\\\/\"},\"author\":{\"name\":\"Antonio Tammaro\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/6e574a2e13d47c9167c5cfb475d9bfc5\"},\"headline\":\"Golden Master Pattern: codice legacy non ti temo!\",\"datePublished\":\"2020-04-28T22:00:00+00:00\",\"dateModified\":\"2021-05-21T16:58:12+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/golden-master-pattern-codice-legacy-non-ti-temo\\\/\"},\"wordCount\":825,\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/golden-master-pattern-codice-legacy-non-ti-temo\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?fit=1024%2C608&ssl=1\",\"keywords\":[\".NetCore\",\"C#\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"it-IT\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/golden-master-pattern-codice-legacy-non-ti-temo\\\/\",\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/golden-master-pattern-codice-legacy-non-ti-temo\\\/\",\"name\":\"Golden Master Pattern: codice legacy non ti temo! - Blexin\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/golden-master-pattern-codice-legacy-non-ti-temo\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/golden-master-pattern-codice-legacy-non-ti-temo\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?fit=1024%2C608&ssl=1\",\"datePublished\":\"2020-04-28T22:00:00+00:00\",\"dateModified\":\"2021-05-21T16:58:12+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/6e574a2e13d47c9167c5cfb475d9bfc5\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/golden-master-pattern-codice-legacy-non-ti-temo\\\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/golden-master-pattern-codice-legacy-non-ti-temo\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/golden-master-pattern-codice-legacy-non-ti-temo\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?fit=1024%2C608&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?fit=1024%2C608&ssl=1\",\"width\":1024,\"height\":608},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/golden-master-pattern-codice-legacy-non-ti-temo\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/blexin.com\\\/it\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Golden Master Pattern: codice legacy non ti temo!\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#website\",\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/\",\"name\":\"Blexin\",\"description\":\"Con noi \u00e8 semplice\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/blexin.com\\\/it\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/6e574a2e13d47c9167c5cfb475d9bfc5\",\"name\":\"Antonio Tammaro\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ddb88ac3dfb067ae6f1592d451eab3587e41bbbe98325961161cc286844e8d0d?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ddb88ac3dfb067ae6f1592d451eab3587e41bbbe98325961161cc286844e8d0d?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ddb88ac3dfb067ae6f1592d451eab3587e41bbbe98325961161cc286844e8d0d?s=96&d=identicon&r=g\",\"caption\":\"Antonio Tammaro\"},\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/author\\\/antonio-tammaroblexin-com\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Golden Master Pattern: codice legacy non ti temo! - Blexin","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:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/","og_locale":"it_IT","og_type":"article","og_title":"Golden Master Pattern: codice legacy non ti temo! - Blexin","og_description":"Vediamo insieme come modificare codice legacy garantendone il funzionamento grazie al Golden Master Pattern","og_url":"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/","og_site_name":"Blexin","article_published_time":"2020-04-28T22:00:00+00:00","article_modified_time":"2021-05-21T16:58:12+00:00","og_image":[{"width":1024,"height":608,"url":"https:\/\/i1.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?fit=1024%2C608&ssl=1","type":"image\/png"}],"author":"Antonio Tammaro","twitter_card":"summary_large_image","twitter_misc":{"Scritto da":"Antonio Tammaro","Tempo di lettura stimato":"8 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/#article","isPartOf":{"@id":"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/"},"author":{"name":"Antonio Tammaro","@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/6e574a2e13d47c9167c5cfb475d9bfc5"},"headline":"Golden Master Pattern: codice legacy non ti temo!","datePublished":"2020-04-28T22:00:00+00:00","dateModified":"2021-05-21T16:58:12+00:00","mainEntityOfPage":{"@id":"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/"},"wordCount":825,"image":{"@id":"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?fit=1024%2C608&ssl=1","keywords":[".NetCore","C#"],"articleSection":["Blog"],"inLanguage":"it-IT"},{"@type":"WebPage","@id":"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/","url":"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/","name":"Golden Master Pattern: codice legacy non ti temo! - Blexin","isPartOf":{"@id":"https:\/\/blexin.com\/it\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/#primaryimage"},"image":{"@id":"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?fit=1024%2C608&ssl=1","datePublished":"2020-04-28T22:00:00+00:00","dateModified":"2021-05-21T16:58:12+00:00","author":{"@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/6e574a2e13d47c9167c5cfb475d9bfc5"},"breadcrumb":{"@id":"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/"]}]},{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/#primaryimage","url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?fit=1024%2C608&ssl=1","contentUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?fit=1024%2C608&ssl=1","width":1024,"height":608},{"@type":"BreadcrumbList","@id":"https:\/\/blexin.com\/it\/blog\/golden-master-pattern-codice-legacy-non-ti-temo\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blexin.com\/it\/"},{"@type":"ListItem","position":2,"name":"Golden Master Pattern: codice legacy non ti temo!"}]},{"@type":"WebSite","@id":"https:\/\/blexin.com\/it\/#website","url":"https:\/\/blexin.com\/it\/","name":"Blexin","description":"Con noi \u00e8 semplice","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blexin.com\/it\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"it-IT"},{"@type":"Person","@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/6e574a2e13d47c9167c5cfb475d9bfc5","name":"Antonio Tammaro","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/secure.gravatar.com\/avatar\/ddb88ac3dfb067ae6f1592d451eab3587e41bbbe98325961161cc286844e8d0d?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/ddb88ac3dfb067ae6f1592d451eab3587e41bbbe98325961161cc286844e8d0d?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/ddb88ac3dfb067ae6f1592d451eab3587e41bbbe98325961161cc286844e8d0d?s=96&d=identicon&r=g","caption":"Antonio Tammaro"},"url":"https:\/\/blexin.com\/it\/author\/antonio-tammaroblexin-com\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/fe85ca6d-91d7-4ead-9d01-d4adddef4e5e.png?fit=1024%2C608&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/pcyUBx-6X7","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/26729","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/users\/196716249"}],"replies":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/comments?post=26729"}],"version-history":[{"count":4,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/26729\/revisions"}],"predecessor-version":[{"id":27794,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/26729\/revisions\/27794"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/media\/26723"}],"wp:attachment":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/media?parent=26729"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/categories?post=26729"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/tags?post=26729"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}