tag:blogger.com,1999:blog-3596672569615208272024-02-27T11:19:27.521+01:00www lifeUnknownnoreply@blogger.comBlogger81125tag:blogger.com,1999:blog-359667256961520827.post-83323382960701781392023-12-26T06:10:00.001+01:002023-12-26T06:10:52.959+01:00Amortized time complexity · YourBasic<div dir="auto">"Amortized analysis is used for algorithms that have expensive operations that happen only rarely."<br> <a href="https://yourbasic.org/algorithms/amortized-time-complexity-analysis/#:~:text=Amortized%20analysis%20is%20used%20for%20algo%C2%ADrithms%20that%20have%20expensive%20opera%C2%ADtions%20that%20happen%20only%C2%A0rarely">https://yourbasic.org/algorithms/amortized-time-complexity-analysis/#:~:text=Amortized%20analysis%20is%20used%20for%20algo%C2%ADrithms%20that%20have%20expensive%20opera%C2%ADtions%20that%20happen%20only%C2%A0rarely</a>. </div> Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-63229964885441112782018-07-30T18:11:00.001+02:002018-07-30T18:11:10.039+02:00The Universe of the Very Small - Astronomy - OpenStax CNX<a href="https://cnx.org/contents/LnN76Opl@14.4:FfqQvtot@4/The-Universe-of-the-Very-Small">The Universe of the Very Small - Astronomy - OpenStax CNX</a>: "The air we breathe has about 1019 atoms in each cubic centimeter—and we usually think of air as empty space. In the interstellar gas of the Galaxy, there is about one atom in every cubic centimeter"Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-4861374284619512352018-03-20T18:36:00.001+01:002018-03-20T18:36:54.649+01:00PragPub September 2009 | Responsive Design<a href="https://pragprog.com/magazines/2009-09/responsive-design">PragPub September 2009 | Responsive Design | The Pragmatic Bookshelf</a>: "The challenge is to embrace responsibility and at the same time take an appropriate role in designing. Learning to achieve this balance is the next goal of the Responsive Design Project."Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-38599290184214598752018-03-20T16:09:00.001+01:002018-03-20T16:09:52.278+01:00Responsive Design<a href="https://pragprog.com/magazines/2009-09/responsive-design">PragPub September 2009 | Responsive Design | The Pragmatic Bookshelf</a>: "But design has a dark side. While there isn’t a single best design for any system, there are many poor designs for that same system. The more experience a programmer has, the more design ideas he knows. The temptation is to put these design ideas in the system now because you just know you’ll need them eventually."Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-28128288069069786342017-11-15T15:56:00.001+01:002017-11-15T15:56:09.008+01:00The Twelve-Factor App (Questo testo è una traduzione della versione originale in Inglese.)<a href="https://12factor.net/it/">The Twelve-Factor App (Questo testo è una traduzione della versione originale in Inglese.)</a>: <br />
<br />Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-60807011311650229102017-09-15T06:59:00.001+02:002017-09-15T06:59:45.324+02:00Procedural vs OOP — Sandi Metz<a href="https://www.sandimetz.com/blog/2017/9/13/breaking-up-the-behemoth">Breaking Up the Behemoth — Sandi Metz</a>: "Sticking with procedures too long is just as bad as doing design too soon. If important classes in your domain change often, get bigger every time they change, and are accumulating conditionals, stop adding to them right now. Use every new request as an opportunity to do a bit of design. Implement the change using small, well-designed classes that collaborate with the existing object."Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-78772373502149492532017-08-17T12:38:00.001+02:002017-08-17T12:38:08.256+02:00Code Smells – Part I | Codurance<a href="https://codurance.com/software-creation/2016/03/17/code-smells-part-I/">Code Smells – Part I | Codurance</a>: "a code smell is something that makes your developer instinct cry out to you, and you just know that something is wrong."Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-75411710810221852862017-07-13T15:22:00.001+02:002017-07-13T15:22:08.272+02:00Open/Closed principle<a href="https://dotnetcodr.com/2015/09/30/design-patterns-and-practices-in-net-the-strategy-pattern/">Design patterns and practices in .NET</a>: "the Open/Closed principle of SOLID: a class is open for extensions but closed for modifications."Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-47235062451813857782017-07-06T17:04:00.001+02:002017-07-06T17:04:54.476+02:00Demystifying Conway's Law<a href="https://www.thoughtworks.com/insights/blog/demystifying-conways-law">Demystifying Conway's Law | ThoughtWorks</a>: ""Any organization that designs a system (defined more broadly here than just information systems) will inevitably produce a design whose structure is a copy of the organization's communication structure.""Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-8504883274927311692017-06-20T12:31:00.001+02:002017-06-20T12:31:31.919+02:00The Three Laws of Test-Driven Development<a href="http://programmer.97things.oreilly.com/wiki/index.php/The_Three_Laws_of_Test-Driven_Development">The Three Laws of Test-Driven Development - Programmer 97-things</a>:<br />
<br />
"There are three simple laws:<br />
<ol>
<li>You can't write any production code until you have first written a failing unit test. </li>
<li>You can't write more of a unit test than is sufficient to fail, and not compiling is failing. </li>
<li>You can't write more production code than is sufficient to pass the currently failing unit test. If</li>
</ol>
If you follow the three laws every module will be testable by definition. And another word for testable is decoupled. "<br />
<br />
<br />Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-83227255878803473202017-06-20T12:07:00.001+02:002017-06-20T12:07:50.452+02:00[Clean Coder Blog] Tests need to be designed<a href="http://blog.cleancoder.com/uncle-bob/2017/03/03/TDD-Harms-Architecture.html">Clean Coder Blog</a>: "Yes. That’s right. Tests need to be designed. Principles of design apply to tests just as much as they apply to regular code. Tests are part of the system; and they must be maintained to the same standards as any other part of the system."<br />
<br />Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-2166173874691075452017-06-20T11:53:00.001+02:002017-06-20T11:53:22.026+02:00A Beginner’s Guide to Automated Testing – Hacker Noon"Remember the rule: If it matters that the code works you should write a test for it."<br />
<br />
<a href="https://hackernoon.com/treat-yourself-e55a7c522f71">A Beginner’s Guide to Automated Testing – Hacker Noon</a><br />
<br />Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-65665115372560113282017-06-07T10:42:00.001+02:002017-06-07T10:44:38.152+02:00Surviving Legacy Code with Golden Master and Sampling - The Code Whisperer<a href="http://blog.thecodewhisperer.com/permalink/surviving-legacy-code-with-golden-master-and-sampling#welc">Surviving Legacy Code with Golden Master and Sampling - The Code Whisperer</a>:<br />
<br />
"I treat valuable code with considerable respect. It provides food for families.<br />
I treat difficult-to-change code also with considerable respect, although this comes more from fear than admiration."<br />
<br />
This brings me to Rule Number Zero of Surviving Legacy Code:<br />
<blockquote style="background-color: #e6e6e6; border-left: 4px solid rgb(227, 104, 119); color: #4d4d4d; font-family: "Sinkin Sans", Roboto, Helvetica, sans-serif; font-size: 24px; line-height: 1.8; margin: 1.2rem 0px 0px 3em; padding: 0px 0px 0px 0.5em;">
<div style="font-size: 1.5rem; line-height: 1.8; margin-bottom: inherit !important; margin-top: 1.2rem; padding: 0px;">
Maximize safety.</div>
</blockquote>
Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-30899459125765762422017-05-11T12:44:00.001+02:002017-05-11T12:44:19.537+02:00Keep your tests clean. Treat them as first-class citizens of the system.<a href="http://blog.cleancoder.com/uncle-bob/2017/05/05/TestDefinitions.html">Clean Coder Blog</a>: "when people give up on unit tests, it’s usually because they haven’t followed the above author’s advice. They have not treated the tests like first-class citizens. They have not treated the tests as though they were part of the system. They have not maintained those tests to the same standards that they apply to the rest of the system. Instead, they have allowed the tests to rot, to become coupled, to become rigid, and fragile, and slow. And then, in frustration, they give up on the tests.
Moral: Keep your tests clean. Treat them as first-class citizens of the system."Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-74602123245644351552017-04-24T06:48:00.001+02:002017-04-24T06:48:05.923+02:0012 Things Truly Confident People Do Differently | Dr. Travis Bradberry | Pulse | LinkedIn<a href="https://www.linkedin.com/pulse/12-things-truly-confident-people-do-differently-dr-travis-bradberry">2. They Don’t Pass Judgment</a>: "Comparing yourself to other people is limiting. Confident people don’t waste time sizing people up and worrying about..."<br />
<br />
<a href="https://chrome.google.com/webstore/detail/pengoopmcjnbflcjbmoeodbmoflcgjlk" style="font-size: 13px;">'via Blog this'</a>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-82328875914177582402017-04-24T06:45:00.001+02:002017-04-24T06:45:36.692+02:0012 Things Truly Confident People Do Differently | Dr. Travis Bradberry | Pulse | LinkedIn<a href="https://www.linkedin.com/pulse/12-things-truly-confident-people-do-differently-dr-travis-bradberry">1. They Get Their Happiness from Within</a>: "in order to be confident in what you do, you have to be happy with who you are."<br />
<br />
<a href="https://chrome.google.com/webstore/detail/pengoopmcjnbflcjbmoeodbmoflcgjlk" style="font-size: 13px;">'via Blog this'</a>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-51289104834850571152017-04-02T10:13:00.001+02:002017-04-02T10:13:56.715+02:00Packaging Source Code With NuGet | nik codes<a href="https://nikcodes.com/2013/10/23/packaging-source-code-with-nuget/">Packaging Source Code With NuGet | nik codes</a>: <br />
<br />
<a href="https://chrome.google.com/webstore/detail/pengoopmcjnbflcjbmoeodbmoflcgjlk" style="font-size: 13px;">'via Blog this'</a>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-66192351235392085862016-05-10T18:27:00.001+02:002016-05-10T18:27:09.564+02:00Mob Programming, A Whole Team Approach<iframe allowfullscreen="" frameborder="0" height="270" src="https://www.youtube.com/embed/8cy64qkgTyI" width="480"></iframe>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-61244402775402258212016-05-09T13:00:00.001+02:002016-05-09T13:00:42.891+02:00Why Won’t They Pair?<a href="http://www.infoq.com/articles/why-wont-pair?utm_source=infoqWeeklyNewsletter&utm_medium=WeeklyNL_EditorialContent_culture-methods&utm_campaign=05032016news">Why Won’t They Pair?</a>: "Few companies recognize teamwork as a valued skill and instead look for the ‘super hero’ who can come in to save the day during a crisis."<br />
<br />
"<span style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 21px;">At the end of the day, most developers fear being discovered as less competent as they appear to be. Some would call it an example of imposter syndrome."</span><br />
<span style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 21px;"><br /></span>
<span style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 21px;">"</span><span style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 21px;">The fundamental challenge is creating an environment where people feel safe to learn, make mistakes, fail faster, and continually improve their skills."</span><br />
<span style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 21px;"><br /></span>
<span style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 21px;">"</span><span style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 21px;">Be sure to celebrate the successes and the failures, as they are all learning opportunities."</span>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-78622827667626291512016-04-08T16:39:00.001+02:002016-04-08T16:39:09.002+02:00Extreme Enthusiasm » Blog Archive » Bureaucratic tests<a href="http://matteo.vaccari.name/blog/archives/972">Extreme Enthusiasm » Blog Archive » Bureaucratic tests</a>: "Bureaucratic tests are about testing a bit of solution (that is, a bit of the implementation of a solution). Valuable test are about solving a little bit of the problem."Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-60644085903962957292015-12-03T14:28:00.001+01:002015-12-03T14:28:07.307+01:00Command and Query Responsibility Segregation VS Command–query separation<a href="https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf">https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf</a>: <br />
"<b>Command and Query Responsibility Segregation</b> uses the same definition of Commands and Queries that Meyer .... The fundamental difference is that in CQRS objects are split into two objects, one containing the Commands one containing the Queries."Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-14314592996627679672015-09-15T18:42:00.001+02:002015-09-15T18:42:53.632+02:00the Repository pattern | Exercises in .NET with Andras Nemes<a href="http://dotnetcodr.com/2015/06/18/various-topics-from-software-architecture-part-2-the-repository-pattern/">The Repository pattern | Exercises in .NET with Andras Nemes</a>: "Our goal is to make the concrete repository layer to depend on the domain layer and not vice versa which is often the case in real-life projects. This repository-independence is central in Domain Driven Design and has a special term for it: persistence ignorance."Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-87055133447735386342015-09-11T09:24:00.001+02:002015-09-11T17:50:17.619+02:00Aveva ragione mia madre... quando esci dalla "port" indossa un "adapter"a volte capita di dover importare nel nostro codice delle librerie esterne.<br />
<br />
In .NET è semplicissimo, basta importare un pacchetto nuget e il gioco è fatto.<br />
<br />
Il rovescio della medaglia è che in questo modo capita di utilizzare direttamente gli oggetti e i metodi che la libreria espone e ci si lega mani e piedi a questa.<br />
<br />
Questo vuol dire che se in futuro volessimo utilizzare una nuova libreria o la stessa modificasse o deprecasse le sue chiamate dovremmo intervenire direttamente nel nostro codice magari in "n" punti diversi, inoltre andiamo a creare delle dipendenze e il nostro codice diventa intestabile.<br />
<br />
Meglio sarebbe ascoltare i consigli di coloro che ci sono già passati e ne sanno più di noi... mia madre mi diceva sempre di mettermi una maglia di lana quando uscivo e faceva freddo... avrei dovuto ascoltarla più spesso :-)<br />
in particolare l'architettura esagonale o detta "port and adapters" di Cockburn (1) ci dice di disaccopiare tutto ciò che è esterno dal nostro codice e anche il "Dependency inversion principle" di SOLID (2) ci consiglia di non dipendere dalle implementazioni.<br />
<br />
Cosa fare quindi?<br />
<br />
1. Bisogna creare una nuova interfaccia che espone il metodo che ci serve<br />
2. Implementare l'interfaccia<br />
3. implementare il metodo che ci serve utilizzando la libreria scelta<br />
<br />
Questo ci permette di cambiare facilmente libreria, basta creare un nuovo adapter (3) verso la nuova libreria scelta.<br />
<br />
Questo permette anche di sostituire la libreria con un mock che estende la nostra interfaccia e testare quindi il nostro codice.<br />
<br />
1) <a href="http://alistair.cockburn.us/Hexagonal+architecture">http://alistair.cockburn.us/Hexagonal+architecture</a><br />
2) <a href="https://www.wikiwand.com/it/SOLID">https://www.wikiwand.com/it/SOLID</a><br />
3) <a href="http://dotnetcodr.com/2013/04/25/design-patterns-and-practices-in-net-the-adapter-pattern/">http://dotnetcodr.com/2013/04/25/design-patterns-and-practices-in-net-the-adapter-pattern/</a><br />
4) <a href="https://www.wikiwand.com/it/Domain-driven_design">https://www.wikiwand.com/it/Domain-driven_design</a>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-81908493436933492692015-09-07T18:47:00.001+02:002015-09-07T18:47:47.690+02:00Eric Evans on Domain Driven Design<a href="http://www.infoq.com/interviews/domain-driven-design-eric-evans">Eric Evans on Domain Driven Design</a>: "So then sometimes plain old Java code is clearer actually than you UML diagram that tries to convey some sort of relationship that is more dynamic."Unknownnoreply@blogger.comtag:blogger.com,1999:blog-359667256961520827.post-34095695378188134142015-07-16T14:42:00.002+02:002015-07-25T16:42:37.892+02:00"Wilma dammi l'ABTest"<br />
Immaginate di avere questa riga di codice:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">emailSender.Send(email);</span><br />
<br />
chiaro cosa fa questo codice? direi di si... invia un'email.<br />
<br />
<b>Cosa si nasconde dietro il metodo</b> Send?<br />
<br />
Nella mia esperienza potrei giurare che dietro questo metodo si nascondono una serie (innumerevole) di <b>if</b> e il metodo send molto probabilmente avrà centinaia (o migliaia) di righe e non farà solo il send ma probabilmente molto altre operazioni al contorno!<br />
<br />
E pensare che probabilmente tutto è iniziato con una "semplice" if<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">if(il_dato_ha_questo_valore) { </span><br />
<span style="font-family: Courier New, Courier, monospace;"> fai questo;</span><br />
<span style="font-family: Courier New, Courier, monospace;">}</span><br />
<br />
semplice no?<br />
<br />
e poi si sa come vanno queste cose, una "if" tira l'altra, l'emergenza, il fix "al volo" il poco tempo, sempre di corsa, il caldo... mi stanno chiamandodevoandare, sono le 18, suona la campanella... insomma "piccoli metodi crescono" e si arriva a creare nel tempo e a più mani un blob informe che assume comportamenti strani e diversi, che sembra vivere di vita propria a volte che a metterci mano bisogna prima farsi il segno della croce e quando ti chiedono una modifica bisogna avere la scusa pronta e non è sempre facile... una roba che "è colpa di chi ci ha messo mano prima di me", è codice legacy, non l'ho fatto io, io non c'ero e non ho fatto niente, non è colpa mia... insomma ci siamo capiti, è una storia già sentita vero?<br />
<br />
Se qualcuno di voi ha mai sentito parlare della campagna anti-if (http://antiifcampaign.com/) sa di cosa sto parlando!<br />
<br />
Molto spesso (anzi sempre) un "if" sottintende comportamenti diversi e logiche diverse.<br />
Molto spesso (anzi sempre) l'applicazione dei principi SOLID (http://www.wikiwand.com/en/SOLID_(object-oriented_design)) salva la vita.<br />
<br />
Facciamo un esempio e facciamo un viaggio nel meraviglioso mondo del metodo "Send" e probabilmente vedremo cose di questo tipo.<br />
<span style="font-family: 'Courier New', Courier, monospace;">...</span><br />
<span style="font-family: Courier New, Courier, monospace;">if(isABTest) {</span><br />
<span style="font-family: Courier New, Courier, monospace;">...</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if(!recipients.isUnsubscribed)</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">{</span><br />
<span style="font-family: Courier New, Courier, monospace;"> doABTest(message);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> ...<br /> var vetting = EseguiVetting();<br /> </span><span style="font-family: Courier New, Courier, monospace;">if(</span><span style="font-family: 'Courier New', Courier, monospace;">vetting</span><span style="font-family: Courier New, Courier, monospace;">)</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">{</span><br />
<span style="font-family: Courier New, Courier, monospace;"> doABTest(message);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Logger.debug("fatto AB Test")</span><br />
<span style="font-family: Courier New, Courier, monospace;">}</span><span style="font-family: 'Courier New', Courier, monospace;">...</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<br />
Cosa ne pensate se invece avessimo una serie di componenti (oggetti) ognuno dei quali fa una sola cosa (Single Responsibility) e che vengono utilizzati dal nostro <span style="font-family: Courier New, Courier, monospace;">EmailSender</span> all'occorrenza abilitandoli o meno magari con un file di configurazione che li abilita solo in ambiente di staging e non li fa vedere in produzione perchè ahimè ci stiamo ancora lavorando?<br />
<br />
immaginiamo di scrivere questo codice:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">emailSender.Enable(ABTest);</span><br />
<span style="font-family: Courier New, Courier, monospace;">emailSender.Send(email);</span><br />
<br />
e torniamo nel nostro metodo Send dove al posto delle if troviamo una lista di <span style="font-family: Courier New, Courier, monospace;">SenderAction</span> da eseguire, infatti il nostro metodo <span style="font-family: Courier New, Courier, monospace;">Enable</span> aggiungerà semplicemente ad una lista l'azione da eseguire:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">private var workflow = new List<SenderAction>;<br />...<br />public void Enable(</span><span style="font-family: 'Courier New', Courier, monospace;">SenderAction actionToPerform</span><span style="font-family: 'Courier New', Courier, monospace;">){</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> workflow.Add(actionToPerform);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
mentre il metodo Send scorrerà semplicemente il nostro workflow e lancerà per ogni elemento il metodo Execute:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">private var workflow = new List<SenderAction>;<br />...<br />public void Send(</span><span style="font-family: 'Courier New', Courier, monospace;">email</span><span style="font-family: 'Courier New', Courier, monospace;">){</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> foreach(actionToPerform in workflow) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> actionToPerform.Execute();</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
infatti il nostro <span style="font-family: Courier New, Courier, monospace;">SenderAction</span> è semplicemente un'interfaccia che espone il metodo <span style="font-family: Courier New, Courier, monospace;">Execute</span><br />
<br />
<span style="font-family: Courier New, Courier, monospace;">interface SenderAction </span><span style="font-family: 'Courier New', Courier, monospace;">{</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> public void Execute();</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
nell'esempio sopra il nostro parametro ABTest implementa il metodo execute alla sua maniera eseguendo solo l'ABTest ma ognuno ci può fare quello che vuole.<br />
<br />
<b>Quali vantaggi</b> ho ottenuto?<br />
<br />
L'oggetto che fa l'AB test fa solo l'AB test(ancora Single Responsibility).<br />
L'ABTest viene passata al EmailSender (Dependency Injection), quindi è mockabile permettendomi di testare il Sender.<br />
L'ABTest è testabile a sua volta.<br />
Ogni metodo ha poche righe e se devo mettere mano so dove andare.<br />
L'EmailSender diventa quindi un semplice orchestratore, cioè della serie "Miwa lanciami i componenti" (cit. Jeeg Robot) oppure "Wilma, dammi l'ABTest!".<br />
<br />
<b>E se voglio fare il caffè?</b><br />
<br />
Se voglio estendere il mio EmailSender e scopro che tra l'ABTest e l'operazione di Vetting per esempio deve farmi un caffè basterà semplicemente creare una classe <span style="font-family: Courier New, Courier, monospace;">AnExpressoPlease</span> che implementa l'interfaccia <span style="font-family: Courier New, Courier, monospace;">SenderAction</span> ed eseguire il metodo<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">emailSender.Enable(new </span><span style="font-family: 'Courier New', Courier, monospace;">AnExpressoPlease</span><span style="font-family: Courier New, Courier, monospace;">());</span><br />
<br />
e il gioco è fatto! :-)<br />
<br />
<br />Unknownnoreply@blogger.com