tag:blogger.com,1999:blog-365471682015-07-17T20:24:40.570+02:00Invisible to the eyeA journey in web development, [computer] science, engineering:<br>
getting to know what lies under the hood <em>-- Giorgio Sironi</em>Giorgiohttp://www.blogger.com/profile/03558287012747987157noreply@blogger.comBlogger381125InvisibleToTheEyehttps://feedburner.google.comtag:blogger.com,1999:blog-36547168.post-85436431175365092772015-06-18T19:20:00.000+02:002015-06-18T19:20:59.913+02:00Property-based testing primerI'm a great advocate of automated testing and of finding out your code does not work on your machine, 30 seconds after having written it, instead of in production after it has caused a monetary loss and some repair work to be performed. This is true for many different kind of testing, from the unit level (which has also benefits for internal quality and design feedback) to the acceptance level (which ensures the stakeholders get what they need and documents it for the future). Your System Under Test can be a single class, a project or even a collaboration of [micro]services accessed through HTTP from another process or machine. <br /><br />However, classic test suites written with xUnit and BDD styles have some scaling problems they hit when you want to exercise more than some happy paths:&nbsp; <br /><ul><li>it is <b>difficult to cover many different inputs</b> by hand-writing test cases, so we stick with at most a dozen of cases for a particular method.</li><li>There are <b>maintenance costs </b>for every new input we want to test: each need some <b>assertions</b> to be written and be updated in the future if the System Under Test changes its API.</li><li>We <b>tend not to test external dependencies</b> such as the language or libraries, since we trust them to do a good job even if their failure is our responsibility. We chose them and we are deploying our project, not the original authors which provide<span class="st">d the code <i>"as is", without warranty.</i></span></li></ul>Note that here I define <i>input</i> as the existing state of a system, plus the new input provided by a test (the Given and When part of a scenario) and <i>output</i> as not only the actual response produced by the System Under Test but also the new state it has assumed.<br /><h3>sort() </h3><br />Let's take as an example a sort() function, which no one implements today except in job interviews and exercises.<br />Assuming an array (or list, depending on your language), we can produce several inputs for the function like we would do in a kata:<br /><ul><li>[1, 2, 3]</li><li>[3, 1]</li><li>[3, 6, 5, 1, 4]</li></ul>and so on. When do we stop? Maybe we also need some tricky input:<br /><ul><li>[]</li><li>[1]</li><li>[1, 1]</li><li>[2, 3, 5, 6, 8, 9, 1, 3, 6, 7, 8, 9] </li></ul>Once we have all the inputs gathered, we need to define what we expect for each of them:<br /><ul><li>[1, 2, 3] =&gt; [1, 2, 3]</li><li>[3, 1] =&gt; [1, 3[</li><li>[3, 6, 5, 1, 4] =&gt; [1, 3, 4, 5, 6]</li><li>[] =&gt; []</li><li>[1] =&gt; [1]</li><li>[1, 1] =&gt; [1, 1]</li><li>[2, 3, 5, 6, 8, 9, 1, 3, 6, 7, 8, 9]&nbsp; =&gt; [1, 2, 3, 3, 5, 6, 6, 7, 8, 8, 9, 9]</li></ul>You can do this incrementally, growing the code one new test case at a time, but you have to do it anyway. Considering this can become boring and error-prone in this toy example makes you wonder what to do when instead of sort() you have a RangeOfMoney class which is key to your business and manages point-like and arbitrary intervals of monetary amounts (true story).<br /><h3>Property-based testing in a nutshell</h3>Property-based testing in an approach to testing coming from the functional programming world. To solve the aforementioned problems (and get new, more interesting ones), it follows these steps:<br /><ol><li><b>generate</b> a random sample of possible inputs.</li><li><b>Exercise</b> the SUT with each of them.</li><li><b>Verify properties</b> which should be true on every output instead of making precise comparisons.</li><li>(Optionally) if the properties verification failed, possibly shrink to find a minimal input that still causes a failure.</li></ol><h3>How does this work for the sort() function?</h3>We can use rand() to generate an input array: <br /><script src="https://gist.github.com/giorgiosironi/9012fd79a945c1433aa6.js"></script>This array is composed by natural numbers (<i>Gen\nat</i>) and it is long up to 100 elements (<i>Gen\pos(100)</i>), since very long arrays could make our tests slow.<br /><br />Then, for each of these inputs, we exercise sort() and verify a simple property on the output, which is the order of the elements: <script src="https://gist.github.com/giorgiosironi/4d49638448e9c8ea63c0.js"></script><br />This is not the only property that sort() maintains, but it's the first I would specify. There are possible others:<br /><ul><li>every element in the input is also in the output</li><li>every element in the output is also in the input</li><li>the length of the input and output arrays are the same.</li></ul>Here is <a href="https://github.com/giorgiosironi/eris/blob/master/examples/SortTest.php">the complete example written using Eris</a>, our extension for PHPUnit that automates the generation of many kinds of random data and their verification.<br /><h3>How to find properties?</h3>How do we apply property-based testing to code we actually write every day? It certainly fits more in some areas of the code than in others, such as Domain Model classes.<br /><br />Some rules of thumb for defining properties are:<br /><ul><li>look for <b>inverse functions</b> (e.g. addition and substraction, or doubling an image in size and shrinking it to 50%). You can use the inverse on the output and verify equality with the input.</li><li>Relate <b>input and output on some property that is true or false on both</b> (e.g. in the sort() example than an element that is in one of the two arrays is also in the other)</li><li>Define <b>post conditions and invariants</b> that always hold in a particular situation (e.g. in the sort() example that the output is sorted, but in general you can restrict the possible output values of a function very much saying it is an array, it contain only integers, its length is equal to the input's length.)</li></ul><h3>[2, 3, 5, 6, 8, 9, 1, 3, 6, 7, 8, 9] makes my test fail</h3>Defining valid range of inputs with generators and the properties to be satisfied is a rich description of the behavior of the System Under Test. Therefore, when a sort() implementation fails we can work on the input in order to shrink it: trying to reduce its complexity and size in order to provide a minimal failing test case.<br /><br />It's the same work we do when opening a bug report for someone else's code: we try to find a minimal combination that triggers the bug in order to throw away all unnecessary details that would slow down fixing it.<br /><br />So in property-based testing the [2, 3, 5, 6, 8, 9, 1, 3, 6, 7, 8, 9] can probably be shrinked to [2, 3, 5, 6, 8, 9, 1, 3, 6, 7, 8] and maybe up to [1, 0], depending on the bug. This process is accomplished by trying to shrink all the random values generated, which in our case were the length of the array and the values contained.<br /><h3>Testing the language</h3>So here's some code I expect to work:<br /><script src="https://gist.github.com/giorgiosironi/4616671fafb3098a4369.js"></script>This function creates a PHP DateTime instance using the native <i>datetime</i> extension, which is a standard for the PHP world. It starts from an year and a day number ranging from 0 to 364 (or 365) and it build a DateTime pointing to the midnight of that particular day.<br /><br />Here is a property-based test for this function:<br /><script src="https://gist.github.com/giorgiosironi/4721aba8f1949cc3c938.js"></script> We generate two random integers in the [0. 364] range, and test that the difference in seconds of the two generated DateTime objects is equal to 86400 seconds multiplied by the number of the days passed between the two selected dates. A property of the input (distance) is maintained over the output in a different form (seconds instead of days).<br /><br />Surprisingly, <a href="https://github.com/giorgiosironi/eris/blob/master/examples/DateTest.php">this test</a> fails with the following message: <script src="https://gist.github.com/giorgiosironi/8466d58df1793692005d.js"></script>what happened is we triggered <a href="https://bugs.php.net/bug.php?id=62476">a bug of the DateTime object</a> while creating it with a particular combination of format and timezone. The net effect of this bug could have been that our financial reports (telling daily revenue) would have started showing the wrong numbers starting from February 29th of the next year.<br /><br />Notice that the input is shrinked to the simplest possible values that trigger the problem: January 1st on one value and March 1st on the other.<br />Eventually we found a easy work around, as with a couple more lines of code we can avoid this behavior. We could do that only after discovering the bug of course.<br /><h3>In conclusion</h3>Testing an application is a necessary burden for catching defects early and fix them with an acceptable cost instead of letting them run wild on real users. Property-based testing pushes automation also in the generation of inputs for the System Under Test and in the verification of results, hoping to lower the maintanance cost while increasing coverage at the same time.<br /><br />Given the domain complexity handled by the <i>datetime</i> extension, it's doing a fantastic job and it's being developed by very competent programmers. Nevertheless, if they can slip in bugs I trust that my own code will, too. Property-based testing is an additional tool that can work side by side with example-based testing to uncover problems in our projects.<br /><br />We named the <a href="https://github.com/giorgiosironi/eris">property-based PHPUnit extension after Eris</a>, the Greek goddess of chaos, since serious testing means attacking your code and the platform it is built on in the attempt of breaking it before someone else does.<br /><h3>References </h3><ul><li><a href="https://packagist.org/packages/giorgiosironi/eris">Eris on Packagist</a></li><li><a href="https://github.com/giorgiosironi/eris/tree/master/examples">Eris examples on GitHub</a></li><li>The tools that inspired Eris from other languages: <a href="https://hackage.haskell.org/package/QuickCheck">QuickCheck</a>, <a href="https://www.scalacheck.org/">ScalaCheck</a>, <a href="http://www.quviq.com/products/erlang-quickcheck/">Erlang QuickCheck</a>.</li></ul><img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/v4lfefymiiM" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com0http://www.giorgiosironi.com/2015/06/property-based-testing-primer.htmltag:blogger.com,1999:blog-36547168.post-80075308225246764972015-05-27T21:12:00.000+02:002015-05-27T21:12:08.073+02:00Eris 0.4.0 is out<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-1V7T2zf3cAU/VWYWorEG9SI/AAAAAAAABeY/yFuO08Du8vc/s1600/Artist%2527s_impression_dwarf_planet_Eris.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="http://4.bp.blogspot.com/-1V7T2zf3cAU/VWYWorEG9SI/AAAAAAAABeY/yFuO08Du8vc/s400/Artist%2527s_impression_dwarf_planet_Eris.jpg" width="400" /></a></div><a href="https://github.com/giorgiosironi/eris">Eris</a> is a PHPUnit extension for property-based testing, that is to say testing based on generating inputs to a system and check its state and output respect a set of properties. The project is a porting of <a href="http://en.wikipedia.org/wiki/QuickCheck">QuickCheck</a> and Eris is the name of the Greek goddess of chaos, since its aim is to break the System Under Test with unexpected inputs and actions.<br /><br />I am planning a talk at the PHP User Group Milano and a longer blog post to introduce the general public to how property-based testing works. I held the same talk for a few friends at the phpDay 2015 Unconference.<br /><br />Meanwhile version 0.4.0 is out, with the following <a href="https://github.com/giorgiosironi/eris/blob/master/ChangeLog.md">ChangeLog</a>:<br /><ul><li>Showing generated input with <code>ERIS_ORIGINAL_INPUT=1</code>.</li><li><code>names</code> and <code>date</code> (DateTime) new Generator.</li><li><code>tuple</code> Generator supports variadic arguments.</li><li>Shrinking respects <code>when()</code> clauses.</li><li>Dates and sorting examples.</li></ul><br />As for all semantic-versioned projects, the 0.x series should be considered alpha and no API backward compatibility is guaranteed on update. <br /><br /><a href="http://en.wikipedia.org/wiki/Eris_%28dwarf_planet%29#/media/File:Artist%27s_impression_dwarf_planet_Eris.jpg">Image credits</a><img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/MSNZnIdqLis" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com0http://www.giorgiosironi.com/2015/05/eris-040-is-out.htmltag:blogger.com,1999:blog-36547168.post-76198549178054441852015-03-29T17:48:00.001+02:002015-03-29T17:52:51.854+02:00Evolution in software developmentEvolution can be cited as a metaphor for iterative development: every new iteration (or commit at an ideal smallest scale) produces a shippable, new version of the software that has evolved from the previous one.<br /><br />Really simplifying the process, and skipping some steps for simplicity, we can see something like:<br /><ol><li>you start from a unicellular organism</li><li>which evolves (slowly) into a multicellular organism</li><li>which evolves into a fish</li><li>which evolves into a mammal such as a primate and then into <i>Homo Sapiens</i></li></ol>as a metaphor for:<br /><ol><li>you start from a Walking Skeleton</li><li>you add the features necessary to get to a Minimum Viable Product</li><li>you add, modify and drop features to tackle one part of a hierarchical backlog and get to some business objective.</li><li>you pick another area of the backlog to continue working</li></ol>Every metaphor has its limits: for example not all software descends from a common ancestor; variations in the new generations of software are not necessarily produced by randomness nor selected by reproductive ability of the software itself.<br />Still, we can take some lessons where patterns observed over million of years of evolution apply to a software development scenario.<br /><br /><i>If by any chance you happen to be a creationist it's better for you to stop reading this post.</i><br /><h3>Lesson: each step has to keep working</h3>My father is a human, working organism. His father was too - and also the mother of his father. We all descend from an unbroken line of ancestors who were capable of staying alive and, during their lifespans, reproduce. This line goes up until ancestors 4 billion years ago who were unicellular organisms.<br />Thus evolution has to keep all intermediate steps working. Evolution <b>cannot produce current versions who do not have value</b> in the hope that they can be turned into something valuable later.<br /><i>Value</i> here is not necessarily money as it can be a user base or market share that can be monetized later: the investors market puts a price tag on a large user base but often not on a sound software architecture.<br />In fact, this lesson is a reality in capitalism-based companies whose funding is received through demonstrating business results; again, not necessarily profitability but acquisition, retention, growth metrics (Twitter) or revenue (Amazon):<br /><blockquote class="twitter-tweet" lang="en"><div style="text-align: center;">No wonder tech is going the way it's going. People need something tangible in 3 months or no funding <a href="http://t.co/f370JW4C9W">http://t.co/f370JW4C9W</a></div><div style="text-align: center;">— Alvaro 阿尔瓦罗 (@old_sound) <a href="https://twitter.com/old_sound/status/579162149211230208">March 21, 2015</a></div></blockquote><script async="" charset="utf-8" src="//platform.twitter.com/widgets.js"></script> Short-term capital investments are a very common business model in companies adopting Agile software development. They're not the only possible model to develop wealth: the Internet and GPS were created through generous public funding by the US government (which had its own military reasons). <br /><h3>Lesson: evolution takes a long time</h3>If you take a look at the <a href="http://en.wikipedia.org/wiki/Timeline_of_the_evolutionary_history_of_life">timeline of evolution on Earth</a>, you'll see that it took a long time for more and more complex organisms to appear:<br /><ul><li>for the last 3.6 billion years, simple cells (prokaryotes);</li><li>for the last 300 million years, reptiles;</li><li>for the last 200 million years, mammals;</li><li>for the last 130 million years, flowers;</li><li>for the last 60 million years, the primates,</li><li>for the last 20 million years, the family Hominidae (great apes);</li><li>for the last 2.5 million years, the genus Homo (including humans and their predecessors);</li><li>for the last 200,000 years, anatomically modern humans.</li></ul>We can argue that flowers are simpler than dinousaurs, and I'm going to address this later, but we widely believe that modern age humans express the most complex abilities ever seen on Earth: speaking, reading, writing, and tool-building. It can take a long time too for a complex software and an adequate design to emerge purely from iteration.<br /><h3>Lesson: we may not be capable of anything else</h3><dl><dd><i>A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system.</i> – John Gall</dd></dl>Evolution has been wonderful at producing animals that can run while for robotics it was an hard problem to <a href="http://en.wikipedia.org/wiki/Moravec%27s_paradox">control artificial legs</a> on disparate terrains compared to ordinary computation.<br />But, if we believe Gall's law, there may not be another way to get to complex systems than to pass from simple systems first. In a sense, robotics engineers have not designed robot dogs from scratch but <b>evolved them from simpler artificial beings at a faster pace</b> than natural selection.<br />Exercises on evolving a product in thin slices such as the <a href="http://alistair.cockburn.us/Elephant+carpaccio">Elephant carpaccio</a> are often made fun of because of the triviality of the slices in a controlled exercise: "add an input field", "support two discounts instead of one". However, in a real environment the slices become more "launch the product in France for this 10 million people segment" and "launch for another segment of the population". To believe we can design the perfect solution and never slice the problem into steps really is a God complex.<br /><h3>Lesson: local minima are traps</h3><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-jMjV5J_lotU/VQ2RzF8X44I/AAAAAAAABZs/Q-qu9DBBzwM/s1600/giraffe_nerve.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-jMjV5J_lotU/VQ2RzF8X44I/AAAAAAAABZs/Q-qu9DBBzwM/s1600/giraffe_nerve.jpg" height="271" width="400" /></a></div>Humans and in general vertebrates have variants of the <span class="st">recurrent laryngeal nerve</span>, which connects the brain to the larynx or an equivalent organ. This nerve developed in fishes, where it took a short route around the main artery exiting from the heart. It still takes this route today in humans.<br />However, giraffes have undergone <b>a series of local optimizations</b> (boy-scout rule anyone?) where the giraffes with longer necks outcompeted the shorter ones, raising the average length of their necks up to what we see today. The nerve grew with the neck as the only possible local modification that keep the new giraffe capable of living and reproducing itself was to lengthen the nerve, not to redesign it.<br />Longer nerves have a cost: the more cells they are composed of, the easier it is for them to develop diseases or to suffer injuries. An engineer would never do such a design mistake when trying to build a giraffe.<br />It is open to speculation whether it is possible to develop a giraffe with a nerve taking a shorter route: an engineer would surely try to simplify the DNA with this <b>large refactoring</b>.<br />But there may be, for example, embryological reasons that prevent giraffes from being able to be grown from an embryo if the nerve takes a different route. We often estimate the time for a new feature as a critical path where nothing goes wrong, but what if you have to take offline and migrate your database for hours in order to deploy this brand new, clean object-oriented design? Your perfectly designed giraffe may be destined to be stillborn.<br />Nature isn't bad or good: it just <i>is</i>. Local minima are a fact of life and software. We should take care not to preach local improvements as the silver bullet solution, nor to jump into too large refactorings which will kill the giraffe.<br /><h3>Lesson: you don't necessarily get better </h3><div class="separator" style="clear: both; text-align: center;"><a href="http://en.wikipedia.org/wiki/Mosquito#/media/File:Mosquito_2007-2.jpg"><img alt="http://en.wikipedia.org/wiki/Mosquito#/media/File:Mosquito_2007-2.jpg" border="0" src="http://4.bp.blogspot.com/-LV04CgHmI5s/VQ2ioXssxSI/AAAAAAAABZ8/9PCc50oA8kM/s1600/Mosquito_2007-2.jpg" height="286" width="320" /></a></div><br />Fitness functions describe how well-adapted an organism is to its environment, and evolutionary pressure selects the organisms with the better fitness to survive for the next generations. Even when selective pressure is very slightly skewed in one direction, over many generations a trait may very well disappear or appear due to a cumulative effect.<br />Depending on your choice for fitness, you may get a different result. Modern-day mosquitoes evolved from the same tree of life as humans, so our evolutionary projects can either become humans, elephants, cats, cockroaches or mosquitoes depending on which direction the forces in play are selecting.<br />In fact, there are so many <b>legacy code projects</b> around that you wonder what has produced them. One line at the time, <b>they evolved into monsters</b> to satisfy the fitness function of external quality: add this feature, make more money, save server resources, return a response to the user faster.<br /><a href="http://en.wikipedia.org/wiki/Worse_is_better">Worse is better</a> is another example of philosophy where for software is more important to be simple than correct. Simple software is produced and spreads faster than cathedral-like software, taking advantage then of network effects such as the newly created community to improve. We have seen that at work with C and x86 (and so many other standards), we are seeing it now with JavaScript and MongoDB.<br />Again, I'm not saying this is good or bad: I'm saying this is happening and that if you want to replace JavaScript with a better language you have to take this into account instead of complaining about it. One wonders how many extinct animals we have never heard about, which leads us to the last lesson of evolution.<br /><h3>Lesson: extinction is around the corner</h3>Much of this article is a deconstruction of iterative development, as a way to swing the pendulum on the other side of the argument for once. There has to be a devil's advocate.<br />I will leave you instead with a final point on why iterative development is a crucial part of Agile. After all, even this post is iterative: written, edited and reviewed at separate times, I didn't write it with a pen and paper in fact but on a digital medium very easy to modify.<br /><blockquote class="tr_bq">More than 99 percent of all species that ever lived on the planet are estimated to be extinct -- <a href="http://en.wikipedia.org/wiki/Extinction#cite_ref-StearnsStearns2000_2-0">Extinction</a> on Wikipedia</blockquote><br />Why a species goes extinct? It may evolve into another species, but this happens very slowly. What usually happens is the member of a species are <i>no longer able to survive in changing conditions or against superior competition</i>. Which sounds like something extracted from a management book.<br /><br />In fact, one of the fundamental maxims of Agile software design is to <b>keep software easy to change</b>. Resist the over-optimization of today to survive and thrive tomorrow, as we can't foresee the future but we can foresee that we will likely have to change.<br /><br /><img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/JWqs447cbCA" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com1http://www.giorgiosironi.com/2015/03/evolution-in-software-development.htmltag:blogger.com,1999:blog-36547168.post-10392084921140853432014-09-21T15:01:00.001+02:002014-09-21T15:01:33.811+02:00Microservices are not Jars<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-pGtoIMq62VI/VB7APV7LfCI/AAAAAAAABSU/LaT3BT8U7r8/s1600/monolith.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://4.bp.blogspot.com/-pGtoIMq62VI/VB7APV7LfCI/AAAAAAAABSU/LaT3BT8U7r8/s1600/monolith.jpg" height="320" width="226" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">The cult of the monolith</td></tr></tbody></table>I've been building microservices for two years and my main complaint is that they're still not micro- enough. Here's a rebuke of Uncle Bob's recent post <a href="http://blog.cleancoder.com/uncle-bob/2014/09/19/MicroServicesAndJars.html">Microservices and Jars</a>, which he apparently has written after forming an opinion based on an article in Martin Fowler's bliki:<br /><blockquote class="tr_bq">One of my clients recently told me that they were investigating a micro-service-architecture. My first reaction was: "What's that?" So I did a little research and found Martin Fowler's and James Lewis' <a href="http://martinfowler.com/articles/microservices.html">writeup</a> on the topic.</blockquote>&nbsp;"I didn't even know what microservices were up until several days ago. Now I'm ready to pontificate about the topic."<br /><blockquote class="tr_bq">So what is a micro-service? It's just a little stand-alone executable that communicates with other stand-alone executables through some kind of mailbox; like an http socket. Lots of people like to use REST as the message format between them.<br /> Why is this desirable? Two words. <em>Independent Deployability</em>.</blockquote>Let's ignore the <i>REST as the message format</i> terminology. Only two words? Independent deployability is nice, but I've seen cases where independence is total, and cases where an end-to-end test suite still needs to run including the production version of services A and B and the new version C' that we want to deploy to substitute C.<br />Other interesting properties of microservices such as scaling them independently come to mind. Or writing them in different languages. Or adapting to Conway's law by aligning teams with microservices for most of their work.<br /><blockquote class="tr_bq">You can fire up your little MS and talk with it via REST. No other part of the system needs to be running. Nobody can change a source file in a different part of the system, and screw your little MS up. Your MS is immune to all the other code out there.<br /> You can test your MS with simple REST commands; and you can mock out other MSs in the system with little dummy MSs that do just what your tests need them to do.<br /> Moreover, you can control the deployment. You don't have to coordinate with some huge deployment effort, and merge deployment commands into nasty deployment scripts. You just fire up your little MS and make sure it keeps running.<br /> <b>You can use your own database. You can use your own webserver.</b> <b>You can use any language you like. You can use any framework you like.</b><br /> Freedom! Freedom!</blockquote>&lt;sarcasm&gt; tag needed.<br /><br /><blockquote class="tr_bq">But wait. Why is this better? Are the advantages I just listed absent from a normal Java, or Ruby, or .Net system? </blockquote>Yes:<br /><ul><li>existing databases tend to be attractors when new persistence requirements come up. So if I have MySQL up and running in my application and a job that would be a good fit for MongoDB comes up, I'm definitely not going to introduce MongoDB given the infrastructure setup time. I'll just go with the existing infrastructure and create some new tables, perpetuating the growth of the monolith.</li><li>Web servers are often tied to languages. If I want to use Node.js it will listen on the port 80 by itself, while PHP is commonly used with Apache, and Java with Tomcat or Jetty.&nbsp;</li><li>JARs are a pretty JVM-specific packaging system. I'm definitely not going to put PHP code into JARs.</li><li>Frameworks come from the language, and even inside the same language I can have multiple PHP applications where one has a custom user interface and one serves a Angular single-page application.</li></ul>Also the ones not listed:<br /><ul><li>It's easier to find out machines which contain <b>bottleneck</b> and replace them, CPU and IO usage maps directly to applications.</li><li>It's easier to <b>get started</b> working as a new developer because you need just a single microservice to run on your machine.</li><li>It's easier to <b>throw away</b> one microservice and replace it with a new one doing the same job, but better written.</li></ul><blockquote class="tr_bq">What about: <em>Independent Deployability</em>?<br /> We have these things called <code>jar</code> files. Or Gems. Or DLLs. Or Shared Libraries. The reason we have these things is so we can have independent deployability.</blockquote>Replacing single JARs or DLLs seems pretty dangerous to me where there are compile-time and binary dependencies in play. Since Uncle Bob has experience with that, I'm going to trust him to deploy safely this way.<br /><blockquote class="tr_bq">Most people have forgotten this. Most people think that <code>jar</code> files are just convenient little folders that they can jam their classes into any way they see fit. They forget that a <code>jar</code>, or a DLL, or a Gem, or a shared library, is <em>loaded and linked at runtime</em>. Indeed, DLL stands for <em>Dynamically Linked Library</em>.<br /> So if you design your <code>jar</code>s well, you can make them just as independently deployable as a MS. Your team can be responsible for your <code>jar</code> file. Your team can deploy your DLL without massive coordination with other teams. Your team can test your GEM by writing unit tests and mocking out all the other Gems that it communicates with. You can write a <code>jar</code> in Java or Scala, or Clojure, or JRuby, or any other JVM compatible language. You can even use your own database and wesbserver if you like.</blockquote>You can use any language you like as long as you run it on the JVM. Sure there must be people who work on other infrastructure or don't want to run their languages on a compatibly-yet-really-secondary platform? PHP applications? Ruby programmers?<br /><blockquote class="tr_bq">If you'd like proof that <code>jar</code>s can be independently deployable, just look at the plugins you use for your editor or IDE. They are deployed entirely independently of their host! And often these plugins are nothing more than simple <code>jar</code> files.<br /> So what have you gained by taking your <code>jar</code> file and putting it behind a socket and communicating with REST?</blockquote>SOAP is the last acronym where <i>simple</i> was used this way. Look, by generating a WSDL from your objects along with an XSD file that can be used to validate XML messages you can pass requests over HTTP with a Soap-Action header and regenerate Java (or other compatible languages) code from the WSDL...<br /><blockquote class="tr_bq">One thing you lose is time. It takes <em>time</em> to communicate through a socket. It takes <em>time</em> to decode REST messages. And that time means you cannot use micro-services with the impunity of a <code>jar</code>. If I want two <code>jar</code>s to get into a rapid chat with each other, I can. But I don't dare do that with a MS because the communication time will kill me.</blockquote>Of course, chatty fine-grained interfaces are not a microservices trait. I prefer <i>accept a Command, emit Events</i> as an integration style. After all, microservices can become dangerous if integrated with purely synchronous calls so the kind of interfaces they expose to each other is necessarily different from the one of objects that work in the same process. This is a property of every distributed system, <a href="http://scholar.harvard.edu/waldo/publications/note-distributed-computing">as we know from 1996</a>.<br /><blockquote class="tr_bq">On my laptop it takes 50ms to set up a socket connection, and then about 3us per byte transmitted through that connection. And that's all in a single process on a single machine. Imagine the cost when the connection is over the wire!</blockquote>It takes more to write a file line by line rather than doing it in a single shot. However, if the file is 2GB long, I prefer the first solution in order to preserve memory. I'm just trading off time for another resource.<br />In the case of microservices, I'm trading off the latency of single interactions between different services for more important resources: programmer time, independent scalability, even time experienced by the end user. A front end asynchronously publishing events to a backend service feels faster to the user than a monolithic application where I respond to user requests and generate report lines in the same process or on the same machines.<br /><blockquote class="tr_bq"> Another thing you lose (and I hate to say this) is debuggability. You can't single step across a REST call, but you can single step across <code>jar</code> files. You can't follow a stack trace across a REST call. Exceptions get lost across a REST interface.</blockquote>To me debuggability and introspection into an application improves when using microservices, because you will be full of all the HTTP logs of every service calling one another. You don't have to predispose logging cut points as they come for free with the HttpChannel objects. For a more business-oriented monitoring, take a look at <a href="http://www.udidahan.com/2009/06/14/domain-events-salvation/">Domain Events</a>: we publish them from different applications in order to build reports based on data from different components.<br /><blockquote class="tr_bq">After reading this you might think I'm totally against the whole notion of Micro-Services. But, of course, I'm not. I've built applications that way in the past, and I'll likely build them that way in the future. It's just that I don't want to see a big fad tearing through the industry leaving lots of broken systems in it's wake.</blockquote><blockquote class="tr_bq"> For most systems the independent deployability of <code>jar</code> files (or DLLS, or Gems, or Shared Libraries) is more than adequate. For most systems the cost of communicating over sockets using REST is quite restrictive; and will force uncomfortable trade-offs.</blockquote>Paraphrasing Stroustrup, <i>there are only two kinds of achitectures: the ones people complain about and the ones nobody uses</i>. We are here proposing microservices because they have provided value in many systems that were once thought not to need them. As long as you have reporting needs you don't want to burden your front end with, or need to scale up in the number of users or programmer, you can consider microservices (and their cost).<br /><blockquote class="tr_bq">My advice:<br /> <blockquote><em>Don't leap into microservices just because it sounds cool. Segregate the system into <code>jar</code>s using a plugin architecture first. If that's not sufficient, then consider introducing service boundaries at strategic points.</em></blockquote></blockquote>Please don't! The interaction between microservices are very different from the ones between objects inside a single application. Each call outside of the boundary is a potential failure mode that you should try to model as an asynchronous message that can be retried when delivery fails (the receiving microservice being down, slow or not reachable). Retrofitting microservices over an existing code base is a costly endeauvour and you should only embark on it if you have an adequate time and money budget, possibly bigger than the one necessary to build with microservices in the first place.<img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/_qyQxg3VMTM" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com3http://www.giorgiosironi.com/2014/09/microservices-are-not-jars.htmltag:blogger.com,1999:blog-36547168.post-65867747006015298852014-08-17T11:35:00.004+02:002014-08-17T11:37:55.970+02:00Tabular data in Behat<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-Qho6xvEr7Mg/U_B25rMW1QI/AAAAAAAABOk/Hr7NlPJTNT0/s1600/Pythia.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://1.bp.blogspot.com/-Qho6xvEr7Mg/U_B25rMW1QI/AAAAAAAABOk/Hr7NlPJTNT0/s1600/Pythia.jpg" height="180" width="320" /></a></div><blockquote class="tr_bq"><i>All of this has happened before, and all this will happen again.</i> -- <a href="http://en.battlestarwiki.org/wiki/Sacred_Scrolls">BSG</a></blockquote>I just watched Steve Freeman short talk <a href="https://skillsmatter.com/skillscasts/5009-given-when-then-considered-harmful">"Given When Then" considered harmful</a> (requires free login), and I was looking for some ways to cheaply eliminate duplication in Behat scenarios.<br /><br />Fortunately, Behat supports <a href="http://docs.behat.org/en/latest/guides/1.gherkin.html#scenario-outlines">Scenario Outlines</a> for tabular data which is an 80/20 solution to transform lots of duplicated scenarios:<br /><pre> Scenario: 3 is Fizz<br /> Given the input is 3<br /> When it is converted<br /> Then it becomes Fizz<br /><br /> Scenario: 6 is Fizz too because it's multiple of 3<br /> Given the input is 6<br /> When it is converted<br /> Then it becomes Fizz<br /><br /> Scenario: 2 is itself<br /> Given the input is 2<br /> When it is converted<br /> Then it becomes 2<br /></pre>into a table:<br /><pre> Scenario Outline: conversion of numbers<br /> Given the input is &lt;input&gt;<br /> When it is converted<br /> Then it becomes &lt;output&gt;<br /><br /> Examples:<br /> | input | output |<br /> | 2 | 2 |<br /> | 3 | Fizz |<br /> | 6 | Fizz |</pre><pre></pre>Moreover, you can also pass tabular data to a single step with <a href="http://blog.whiteoctober.co.uk/2012/09/12/behat-tablenodes-the-missing-manual/">Table Nodes</a>:<br /><pre> &nbsp;Scenario: two items in the cart<br /> Given the following items are in the cart:<br /> | name | price |<br /> | Cake | 4 |<br /> | Shrimps | 10 |<br /> When I check out<br /> Then I pay 14</pre>It takes a few minutes to learn how to do this into an existing Behat infrastructure. There are minimal changes to perform in the FeatureContext in the case of the Table Nodes, while Scenario Outlines are a pure Gherkin-side refactoring.<br /><br />My code is on Github in my <a href="https://github.com/giorgiosironi/behat-tables-kata">behat-tables-kata</a> repository. If this reminds you of PHPUnit's @dataProvider, try to think of other patterns that can be borrowed from the xUnit world to fast-forward Cucumber and Behat development.<img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/gASOtZNnGCM" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com0http://www.giorgiosironi.com/2014/08/tabular-data-in-behat.htmltag:blogger.com,1999:blog-36547168.post-27105111860298662812014-08-16T12:04:00.003+02:002014-08-16T12:04:49.111+02:00PHPUnit Essentials review<div class="separator" style="clear: both; text-align: center;"><a href="https://www.packtpub.com/application-development/phpunit-essentials" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="https://www.packtpub.com/application-development/phpunit-essentials" border="0" src="http://1.bp.blogspot.com/-up6erVynQXw/U-8oFSXlCWI/AAAAAAAABOQ/CBHTT64FWqI/s1600/3439OS_cov.jpg.png" height="320" width="259" /></a></div><a href="https://www.packtpub.com/application-development/phpunit-essentials">PHPUnit Essentials</a> by Zdenek Machek is a modern and complete book about PHPUnit usage. I've been sent an electronic copy by Packt Publishing and am now reviewing it here.<br /><br />The first thing that struck me about the book was the breadth of subjects: you start from mocks and command line options, to get even to Selenium usage. You have to know your tools and given PHPUnit being a standard, this is all knowledge that will accompany you for several years.<br /><br />Every book on PHPUnit must be compared with <a href="http://phpunit.de/manual/current/en/installation.html">the wonderful manual</a>, to see what it adds to the picture with respect to the documentation. PHPUnit Essentials, in this respect, looks also at 3rd party libraries such as mocking libraries or "competitors" such as PHPSpec to enlarge the picture to the whole open source PHP landscape. This is something the documentations of single projects cannot do, and where a bit of opinionated advice can be taken.<br /><br />There is a bit of what may seem outdated information in the book such as how to perform a PEAR-based installation, but it's identified as such (PEAR being deprecated and dismissed by the end of the year.) Another seemingly outdated tool is Selenium IDE, but once upgraded with a formatter for Selenium2TestCase like explained in this book it becomes usable again. This kind of advice demonstrates the real world experience of the author and makes you trust the content.<br /><br />On the whole by reading this book you go in as a naive tester and you come out with lots of skills on using PHPUnit in different scenarios; so I would recommended it to programmers wanting to dive into testing PHP applications. Probably it's not worth a read for the medium-to-advanced users, for which most of the content is already known from PHPUnit manual or personal experience. After all the book's named <i>Essentials</i>, so it delivers all that you expect from the title in a convenient single package.<br /><br /><img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/IxDDMXc3QS4" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com1http://www.giorgiosironi.com/2014/08/phpunit-essentials-review.htmltag:blogger.com,1999:blog-36547168.post-6696533697562685222014-07-19T14:21:00.004+02:002014-07-19T14:26:10.967+02:00Skateboards, rockets and mathThis slide from Spotify has been popular for a while: <br /><blockquote class="twitter-tweet" lang="en"><div style="text-align: center;">Loving this slide! <a href="http://t.co/YTOUhpdUp2">pic.twitter.com/YTOUhpdUp2</a></div><div style="text-align: center;">— blat (@ferblape) <a href="https://twitter.com/ferblape/statuses/448813238638358528">March 26, 2014</a></div></blockquote><script async="" charset="utf-8" src="//platform.twitter.com/widgets.js"></script>It explains how a product can be built iteratively, satisfying first the <i>need for transport</i> with lesser means and then evolving to a more powerful platform. In this model feedback such as business model validation and satisfaction from the project sponsors can arrive early, even when <u>they</u>'re negative (especially so).<br /><br />From what I read about Spotify, they're also well-aware that incremental development can only take you so far: you don't get a car by making a better bicycle. Sometimes you have to take a leap to a new platform; or if it's clear that simpler technology won't support your vision, start from an higher level of essential complexity.<br /><br />Here's someone that didn't start from a skateboard:<br /><div style="text-align: center;"><blockquote class="twitter-tweet" lang="en">[PHOTO] Falcon 9 lifts off carrying 6 ORBCOMM satellites to orbit. <a href="http://t.co/Os04NVR3oI">pic.twitter.com/Os04NVR3oI</a><br />— SpaceX (@SpaceX) <a href="https://twitter.com/SpaceX/statuses/489166607030038529">July 15, 2014</a></blockquote></div><script async="" charset="utf-8" src="//platform.twitter.com/widgets.js"></script> Imagine telling Spotify to install WebSphere (or some other technological terror) as the first step when starting a brand new project; or telling SpaceX teams "Come on, Elon, just give us a bicycle and we'll get some first sales!"<br /><br />Or telling Larry Page that <a href="http://www.sarahmei.com/blog/2014/07/15/programming-is-not-math/">programming isn't math</a>:<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://en.wikipedia.org/wiki/PageRank"><img alt="http://en.wikipedia.org/wiki/PageRank" border="0" src="http://3.bp.blogspot.com/-s-ruKfD4-ik/U8phFuFqzkI/AAAAAAAABNQ/ryqYd0foD50/s1600/a0e11cd17235ba8f80701fe365b9790f.png" height="123" width="640" /></a></div><br />Keeping in mind this strong dependency on context, where do the competitive advantages of your product lie?<br />In finding a better fit with the needs of users, maybe a lower time to market? In solving technology problems to carry humanity into space at an acceptable cost? In algorithms that can find high quality information in the web ocean? In fooling VCs in giving you free money?<br /><br />From your vision, your choices of education, process, and technology.<img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/NvH3hohejg0" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com0http://www.giorgiosironi.com/2014/07/skateboards-rockets-and-math.htmltag:blogger.com,1999:blog-36547168.post-27211862019822434252014-04-25T12:12:00.002+02:002015-07-09T20:45:27.645+02:00The full list of my articles on DZone<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-eYNhnAl387c/U1o1CG5oW8I/AAAAAAAABJw/KTHu_Foqcy8/s1600/quill.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-eYNhnAl387c/U1o1CG5oW8I/AAAAAAAABJw/KTHu_Foqcy8/s1600/quill.png" width="101" /></a></div>From 2010 to the end of 2013 I have written a few articles each week on DZone. Here is the full list as a reference.<br /><br /><b>Warning:</b> it appears DZone redesigned the site and as a result <i>deleted</i> dozens of these articles. If a link does not work try loading it in the <a href="https://dzone.com/books/dont-publish-transaction">Web Archive</a> to see if there is a copy there which has not been lost due to incompetence.<br /><h3><a href="https://www.blogger.com/null" name="patterns"></a>Practical PHP Patterns</h3>PHP implementations for the <a href="http://en.wikipedia.org/wiki/Design_Patterns">GoF Design Patterns book</a> and <a href="http://martinfowler.com/eaaCatalog/">Martin Fowler's Pattern of Enterprise Application Architecture</a>.<br /><br /><a href="http://css.dzone.com/books/dont-publish-transaction">Practical PHP Patterns: Transaction Script</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-domain">Practical PHP Patterns: Domain Model</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-table">Practical PHP Patterns: Table Module</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-service">Practical PHP Patterns: Service Layer</a><br /><a href="http://css.dzone.com/books/practical-php-patterns-table">Practical PHP Patterns: Table Data Gateway</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-row">Practical PHP Patterns: Row Data Gateway</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-active">Practical PHP Patterns: Active Record</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-data">Practical PHP Patterns: Data Mapper</a><br /><a href="http://css.dzone.com/books/practical-php-patterns-unit">Practical PHP Patterns: Unit of Work</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns">Practical PHP Patterns: Identity Map</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-lazy">Practical PHP Patterns: Lazy Loading</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-0">Practical PHP Patterns: Identity Field</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-foreign">Practical PHP Patterns: Foreign Key Mapping</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-1">Practical PHP Patterns: Association Table</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-2">Practical PHP Patterns: Dependent Mapping</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-3">Practical PHP Patterns: Embedded Value</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-4">Practical PHP Patterns: Serialized LOB</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-single">Practical PHP Patterns: Single Table Inheritance</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-5">Practical PHP Patterns: Concrete Table Inheritance</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-6">Practical PHP Patterns: Inheritance Mapping</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-7">Practical PHP Patterns: Metadata Mapping</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-query">Practical PHP Patterns: Query Object</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-8">Practical PHP Patterns: Repository</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-page">Practical PHP Patterns: Page Controller</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-front">Practical PHP Patterns: Front Controller</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-9">Practical PHP Patterns: Template View</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-10">Practical PHP Patterns: Transform View</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/web/practical-php-patterns-two">Practical PHP Patterns: Two Step View</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-remote">Practical PHP Patterns: Remote Facade</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-13">Practical PHP Patterns: Pessimistic Offline Lock</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-coarse">Practical PHP Patterns: Coarse Grained Lock</a><br /><a href="http://css.dzone.com/books/practical-php/practical-php-patterns-0">Practical PHP Patterns: Implicit Lock</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/session/practical-php-patterns">Practical PHP Patterns: Database Session State</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/basic/dnp-practical-php-patterns">Practical PHP Patterns: Gateway</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/basic/practical-php-patterns-mapper">Practical PHP Patterns: Mapper</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/basic/practical-php-patterns">Practical PHP Patterns: Separated Interface</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/basic/practical-php-patterns-layer">Practical PHP Patterns: Layer Supertype</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/basic/practical-php-patterns-0">Practical PHP Patterns: Registry</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/basic/practical-php-patterns-value">Practical PHP Patterns: Value Object</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/basic/practical-php-patterns-money">Practical PHP Patterns: Money</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/basic/practical-php-patterns-special">Practical PHP Patterns: Special Case</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/basic/practical-php-patterns-plugin">Practical PHP Patterns: Plugin</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/basic/practical-php-patterns-service">Practical PHP Patterns: Service Stub</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/basic/practical-php-patterns-record">Practical PHP Patterns: Record Set</a><br /><a href="http://css.dzone.com/books/practical-php-patterns-0">Practical PHP Patterns: Application Controller</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-client">Practical PHP Patterns: Client Session State</a><br /><a href="http://css.dzone.com/books/practical-php-patterns-1">Practical PHP Patterns: Optimistic Offline Lock</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-server">Practical PHP Patterns: Server Session State</a><br /><a href="http://css.dzone.com/articles/practical-php-patterns-class">Practical PHP Patterns: Class Table Inheritance</a><br /><a href="http://css.dzone.com/books/practical-php/practical-php-patterns-data">Practical PHP Patterns: Data Transfer Object</a><br /><a href="http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-visitor">Practical PHP Patterns: Visitor</a><br /><a href="http://css.dzone.com/news/practical-php-patterns-memento">Practical PHP Patterns: Memento</a><br /><a href="http://css.dzone.com/news/practical-php-patterns">Practical PHP Patterns: Mediator</a><br /><br /><h3><a href="https://www.blogger.com/null" name="refactoring"></a>Practical PHP Refactoring</h3>PHP examples for <a href="http://martinfowler.com/books/refactoring.html">Martin Fowler's Refactoring book</a>.<br /><br /><a href="http://css.dzone.com/articles/practical-php-refactoring">Practical PHP Refactoring: Inline Temp</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-move">Practical PHP Refactoring: Move Method</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-move-0">Practical PHP Refactoring: Move Field</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-0">Practical PHP Refactoring: Extract Class</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-hide">Practical PHP Refactoring: Hide Delegate</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-1">Practical PHP Refactoring: Inline Class</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-2">Practical PHP Refactoring: Remove Middle Man</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-3">Practical PHP Refactoring: Introduce Foreign Method</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-4">Practical PHP Refactoring: Introduce Local Extension</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-self">Practical PHP Refactoring: Self Encapsulate Field</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-5">Practical PHP Refactoring: Replace Data Value with Object</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-6">Practical PHP Refactoring: Change Value to Reference</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-7">Practical PHP Refactoring: Change Reference to Value</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-8">Practical PHP Refactoring: Replace Array with Object</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-9">Practical PHP Refactoring: Duplicate Observed Data</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-10">Practical PHP Refactoring: Change Unidirectional Association to Bidirectional</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-11">Practical PHP Refactoring: Change Bidirectional Association to Unidirectional</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-12">Practical PHP Refactoring: Replace Magic Number with Symbolic Constant</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-13">Practical PHP Refactoring: Encapsulate Field</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-14">Practical PHP Refactoring: Encapsulate Collection</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-16">Practical PHP Refactoring: Replace Type Code with Class</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-17">Practical PHP Refactoring: Replace Type Code with Subclasses</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-18">Practical PHP Refactoring: Replace Type Code with State or Strategy</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-19">Practical PHP Refactoring: Replace Subclass with Fields</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-20">Practical PHP Refactoring: Decompose Conditional</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-21">Practical PHP Refactoring: Consolidate Conditional Expression</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-22">Practical PHP Refactoring: Consolidate Duplicate Conditional Fragments</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-23">Practical PHP Refactoring: Remove Control Flag</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-24">Practical PHP Refactoring: Replace Nested Conditionals with Guard Clauses</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-25">Practical PHP Refactoring: Replace Conditional with Polymorphism</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-26">Practical PHP Refactoring: Introduce Null Object</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-27">Practical PHP Refactoring: Introduce Assertion</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-28">Practical PHP Refactoring: Rename Method</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-add">Practical PHP Refactoring: Add Parameter</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-29">Practical PHP Refactoring: Remove Parameter</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-30">Practical PHP Refactoring: Separate Query from Modifier</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-31">Practical PHP Refactoring: Parameterize Method</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-32">Practical PHP Refactoring: Replace Parameter with Explicit Methods</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-33">Practical PHP Refactoring: Preserve Whole Object</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-34">Practical PHP Refactoring: Replace Parameter with Method</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-35">Practical PHP Refactoring: Introduce Parameter Object</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-hide-0">Practical PHP Refactoring: Hide Method</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-37">Practical PHP Refactoring: Replace Constructor with Factory Method</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-38">Practical PHP Refactoring: Encapsulate Downcast (and Wrapping)</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-36">Practical PHP Refactoring: Remove Setting Method</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-40">Practical PHP Refactoring: Replace Exception with Test</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-pull">Practical PHP Refactoring: Pull Up Field</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-pull-0">Practical PHP Refactoring: Pull Up Method</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-39">Practical PHP Refactoring: Replace Error Code with Exception</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-pull-1">Practical PHP Refactoring: Pull Up Constructor Body</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-push">Practical PHP Refactoring: Push Down Method</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-push-0">Practical PHP Refactoring: Push Down Field</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-41">Practical PHP Refactoring: Extract Subclass</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-15">Practical PHP Refactoring: Replace Record with Data Class</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-42">Practical PHP Refactoring: Extract Superclass</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-43">Practical PHP Refactoring: Extract Interface</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-44">Practical PHP Refactoring: Collapse Hierarchy</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-form">Practical PHP Refactoring: Form Template Method</a><br /><a href="http://css.dzone.com/articles/replace-inheritance-delegation">Practical PHP Refactoring: Replace Inheritance with Delegation</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-46">Practical PHP Refactoring: Replace Delegation with Inheritance</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-47">Practical PHP Refactoring: Tease Apart Inheritance</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-48">Practical PHP Refactoring: Convert Procedural Design to Objects</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-49">Practical PHP Refactoring: Separate Domain from Presentation</a><br /><a href="http://css.dzone.com/articles/practical-php-refactoring-50">Practical PHP Refactoring: Extract Hierarchy</a><br /><a href="http://css.dzone.com/books/practical-php-refactoring-0">Practical PHP Refactoring: Extract Method</a><br /><a href="http://css.dzone.com/books/practical-php-refactoring/practical-php-refactoring-0">Practical PHP Refactoring: Inline Method</a><br /><a href="http://css.dzone.com/refcardz/html/practical-php-refactoring/practical-php-refactoring">Practical PHP Refactoring: Replace Temp with Query</a><br /><a href="http://css.dzone.com/refcardz/html/practical-php-refactoring/practical-php-refactoring-0">Practical PHP Refactoring: Introduce Explaining Variable</a><br /><a href="http://css.dzone.com/refcardz/html/practical-php-refactoring/practical-php-refactoring-1">Practical PHP Refactoring: Split Temporary Variable</a><br /><a href="http://css.dzone.com/refcardz/html/practical-php-refactoring/practical-php-refactoring-2">Practical PHP Refactoring: Remove Assignments to Parameters</a><br /><a href="http://css.dzone.com/refcardz/html/practical-php-refactoring/practical-php-refactoring-3">Practical PHP Refactoring: Replace Method with Method Object</a><br /><a href="http://css.dzone.com/books/practical-php-refactoring/substitute-algorithm">Practical PHP Refactoring: Substitute Algorithm</a><br /><br /><h3><a href="https://www.blogger.com/null" name="testing">Practical PHP Testing Patterns</a></h3>PHP implementations of the <a href="http://xunitpatterns.com/">xUnit testing patterns by Gerard Meszaros</a>.<br /><br /><a href="http://css.dzone.com/articles/practical-php-testing-patterns">Practical PHP Testing Patterns: Behavior Verification</a><br /><a href="http://css.dzone.com/books/practical-php-testing-patterns">Practical PHP Testing Patterns</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns">Practical PHP Testing Patterns: Recorded Test</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-0">Practical PHP Testing Patterns: Scripted Test</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-1">Practical PHP Testing Patterns: Data-Driven Test</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-2">Practical PHP Testing Patterns: Test Automation Framework</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-3">Practical PHP Testing Patterns: Minimal Fixture</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-4">Practical PHP Testing Patterns: Standard Fixture</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-5">Practical PHP Testing Patterns: Fresh Fixture</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-6">Practical PHP Testing Patterns: Shared Fixture</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-7">Practical PHP Testing Patterns: Back Door Manipulation</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-8">Practical PHP Testing Patterns: Layer Test</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-10">Practical PHP Testing Patterns: Four Phase Test</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-11">Practical PHP Testing Patterns: Assertion Method</a><br /><a href="http://css.dzone.com/books/practical-php-testing-patterns/practical-php-testing-patterns">Practical PHP Testing Patterns: Test Method</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-12">Practical PHP Testing Patterns: Assertion Message</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-13">Practical PHP Testing Patterns: Testcase Class</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-14">Practical PHP Testing Patterns: Test Runner</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-15">Practical PHP Testing Patterns: Testcase Object</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-16">Practical PHP Testing Patterns: Test Suite</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-17">Practical PHP Testing Patterns: Test Discovery</a><br /><a href="http://css.dzone.com/books/practical-php-testing-patterns/practical-php-testing-patterns-0">Practical PHP Testing Patterns: Inline Setup</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-19">Practical PHP Testing Patterns: Delegated Setup</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-20">Practical PHP Testing Patterns: Creation Method</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-21">Practical PHP Testing Patterns: Implicit Setup</a><br /><a href="http://css.dzone.com/books/practical-php-testing-patterns/practical-php-testing-patterns-1">Practical PHP Testing Patterns: Prebuilt Fixture</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-23">Practical PHP Testing Patterns: Lazy Setup</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-24">Practical PHP Testing Patterns: Suite Fixture Setup</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-25">Practical PHP Testing Patterns: Setup Decorator</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-26">Practical PHP Testing Patterns: Chained Tests</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-27">Practical PHP Testing Patterns: State Verification</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-28">Practical PHP Testing Patterns: Custom Assertion</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-29">Practical PHP Testing Patterns: Delta Assertion</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-30">Practical PHP Testing Patterns: Guard Assertion</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-31">Practical PHP Testing Patterns: Unfinished Test Assertion</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-32">Practical PHP Testing Patterns: Garbage-Collected Teardown</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-33">Practical PHP Testing Patterns: Automated Teardown</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-34">Practical PHP Testing Patterns: In-Line Teardown</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-35">Practical PHP Testing Patterns: Implicit Teardown</a><br /><a href="http://css.dzone.com/books/practical-php-testing-patterns/practical-php-testing-patterns-2">Practical PHP Testing Patterns: Test Double</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-37">Practical PHP Testing Patterns: Test Stub</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-38">Practical PHP Testing Patterns: Test Spy</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-39"> Practical PHP Testing Patterns: Mock Object</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-40"> Practical PHP Testing Patterns: Fake Object</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-41">Practical PHP Testing Patterns: Configurable Test Double</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-42">Practical PHP Testing Patterns: Hard-Coded Test Double</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-43">Practical PHP Testing Patterns: Test-Specific Subclass</a><br /><a href="http://css.dzone.com/books/practical-php-testing-patterns/practical-php-testing-patterns-3">Practical PHP Testing Patterns: Named Test Suite</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-45">Practical PHP Testing Patterns: Test Utility Method</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-46">Practical PHP Testing Patterns: Parameterized Test</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-47">Practical PHP Testing Patterns: Testcase Class Per Class</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-49">Practical PHP Testing Patterns: Testcase Class per Fixture</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-50">Practical PHP Testing Patterns: Testcase Superclass</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-48">Practical PHP Testing Patterns: Testcase Class per Feature</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-51">Practical PHP Testing Patterns: Test Helper</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-52">Practical PHP Testing Patterns: Database Sandbox</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-53">Practical PHP Testing Patterns: Stored Procedure Test</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-54">Practical PHP Testing Patterns: Table Truncation Teardown</a><br /><a href="http://css.dzone.com/books/practical-php-testing-patterns/practical-php-testing-patterns-4">Practical PHP Testing Patterns: Dependency Injection</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-55">Practical PHP Testing Patterns: Transaction Rollback Teardown</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-57">Practical PHP Testing Patterns: Dependency Lookup</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-58">Practical PHP Testing Patterns: Humble Object</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-59">Practical PHP Testing Patterns: Test Hook</a><br /><a href="http://css.dzone.com/articles/practical-php-testing-patterns-0">Practical PHP Testing Patterns: Literal Value</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-61">Practical PHP Testing Patterns: Derived Value</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-62">Practical PHP Testing Patterns: Generated Value</a><br /><a href="http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-63">Practical PHP Testing Patterns: Dummy Object</a><br /><br /><h3>Lean tools </h3>Reflections on the Poppendieck's<span style="font-size: small;"> </span><span style="font-weight: normal;"><span style="font-size: small;"><span id="btAsinTitle"><a href="http://www.amazon.com/Lean-Software-Development-Agile-Toolkit/dp/0321150783">Lean Software Development: An Agile Toolkit</a>.</span></span></span><br /><br /><a href="http://css.dzone.com/articles/lean-tools-seeing-waste">Lean Tools: Seeing Waste</a><br /><a href="http://css.dzone.com/articles/lean-tools-value-stream">Lean Tools: Value Stream Mapping</a><br /><a href="http://css.dzone.com/articles/lean-tools-last-responsible">Lean Tools: the Last Responsible Moment</a><br /><a href="http://css.dzone.com/articles/lean-tools-queuing-theory">Lean Tools: Queuing Theory</a><br /><a href="http://css.dzone.com/articles/lean-tools-self-determination">Lean Tools: Self-Determination</a><br /><a href="http://css.dzone.com/articles/lean-tools-motivation">Lean Tools: Motivation</a><br /><a href="http://css.dzone.com/articles/lean-tools-expertise">Lean Tools: Expertise</a><br /><a href="http://css.dzone.com/articles/lean-tools-conceptual">Lean Tools: Perceived Integrity</a><br /><a href="http://css.dzone.com/articles/lean-tools-conceptual-0">Lean Tools: Conceptual Integrity</a><br /><a href="http://css.dzone.com/articles/lean-tools-refactoring">Lean Tools: Refactoring</a><br /><a href="http://css.dzone.com/articles/lean-tools-measurements">Lean Tools: Measurements</a><br /><a href="http://css.dzone.com/articles/lean-tools-contracts">Lean Tools: Contracts</a><br /><br /><h3>Erlang</h3>My experiments following <a href="http://shop.oreilly.com/product/9780596518189.do">O'Reilly's Erlang Programming</a>.<br /><a href="http://css.dzone.com/articles/erlang-hello-world">Erlang: Hello World</a><br /><a href="http://css.dzone.com/articles/erlang-tuples-and-lists">Erlang: tuples and lists</a><br /><a href="http://css.dzone.com/articles/erlang-build-and-test">Erlang: build and test</a><br /><a href="http://css.dzone.com/articles/erlang-functions-part-1">Erlang: functions (part 1)</a><br /><a href="http://css.dzone.com/articles/erlang-functions-part-2">Erlang: functions (part 2)</a><br /><a href="http://css.dzone.com/articles/erlang-concurrency">Erlang: Concurrency</a><br /><a href="http://css.dzone.com/articles/erlang-clientserver">Erlang: client/server</a><br /><a href="http://css.dzone.com/articles/erlang-linking-processes">Erlang: linking processes</a><br /><a href="http://css.dzone.com/articles/erlang-monitoring">Erlang: monitoring</a><br /><a href="http://css.dzone.com/articles/erlang-records">Erlang: records</a><br /><a href="http://css.dzone.com/articles/erlang-macros">Erlang: macros</a><br /><a href="http://css.dzone.com/articles/erlang-live-upgrade">Erlang: live upgrade</a><br /><a href="http://css.dzone.com/articles/erlang-higher-order-functions">Erlang: higher order functions</a><br /><a href="http://css.dzone.com/articles/erlang-list-comprehensions">Erlang: list comprehensions</a><br /><a href="http://css.dzone.com/articles/erlang-binaries-and-bitstrings">Erlang: binaries and bitstrings</a><br /><a href="http://css.dzone.com/articles/erlang-references">Erlang: references</a><br /><a href="http://css.dzone.com/articles/erlang-sets">Erlang: sets</a><br /><a href="http://css.dzone.com/articles/erlang-bags">Erlang: bags</a><br /><br /><h3>The wheel</h3>A small series highlighting open source libraries to counter by bias on building my own tools. <br /><a href="http://css.dzone.com/articles/wheel-symfony-console">The Wheel: Symfony Console</a><br /><a href="http://css.dzone.com/articles/wheel-symfony-filesystem">The Wheel: Symfony Filesystem</a><br /><a href="http://css.dzone.com/articles/wheel-symfony-stopwatch">The Wheel: Symfony Stopwatch</a><br /><a href="http://css.dzone.com/articles/wheel-monolog">The Wheel: Monolog</a><br /><a href="http://css.dzone.com/articles/wheel-twig">The Wheel: Twig</a><br /><a href="http://css.dzone.com/articles/wheel-guzzle">The Wheel: Guzzle</a><br /><a href="http://css.dzone.com/articles/wheel-symfony-routing">The Wheel: Symfony Routing</a><br /><a href="http://css.dzone.com/articles/wheel-assetic">The Wheel: Assetic</a><br /><br /><h3>Articles</h3><a href="http://css.dzone.com/news/why-im-leaving-subversion-git">Why I'm leaving Subversion for Git</a><br /><a href="http://css.dzone.com/news/acceptance-test-driven">Acceptance Test-Driven Development</a><br /><a href="http://css.dzone.com/news/how-improved-hardware-changed">How improved hardware changed programming</a><br /><a href="http://css.dzone.com/news/contributing-open-source">Contributing to open source projects</a><br /><a href="http://css.dzone.com/news/introducing-nakedphp-01">Introducing NakedPhp 0.1</a><br /><a href="http://css.dzone.com/news/how-i-learned-stop-worrying">How I learned to stop worrying and love new words</a><br /><a href="http://css.dzone.com/news/graphical-tips-average-coder">Graphical tips for the average coder</a><br /><a href="http://css.dzone.com/news/domain-driven-design-review">Domain-Driven Design Review</a><br /><a href="http://css.dzone.com/news/class-design-checklist">The class design checklist</a><br /><a href="http://css.dzone.com/news/http-verbs-php">HTTP verbs in PHP</a><br /><a href="http://css.dzone.com/news/java-versus-php">Java versus PHP</a><br /><a href="http://css.dzone.com/news/always-code">TDD: Always code as...</a><br /><a href="http://css.dzone.com/articles/tdd-checklist-red-green">The TDD Checklist (Red-Green-Refactor in Detail)</a><br /><a href="http://css.dzone.com/articles/model-view-controller-pattern">The Model-View-Controller pattern in PHP</a><br /><a href="http://css.dzone.com/articles/dont-publish-complete-guide">The guide to configuration of PHP applications</a><br /><a href="http://css.dzone.com/articles/vim-php-developers">Vim for PHP development</a><br /><a href="http://css.dzone.com/articles/synchronization-php">Synchronization in PHP</a><br /><a href="http://css.dzone.com/articles/evolution-programmer">Evolution of a programmer</a><br /><a href="http://css.dzone.com/articles/php-and-ruby-rails">PHP 2.x frameworks and Ruby on Rails</a><br /><a href="http://css.dzone.com/articles/zendtest-acceptance-tdd">Zend_Test for Acceptance TDD</a><br /><a href="http://css.dzone.com/articles/yahoo-query-language">Yahoo! Query Language</a><br /><a href="http://css.dzone.com/articles/osgi-and-servlets-can-work">OSGi and servlets can work together</a><br /><a href="http://css.dzone.com/articles/writing-user-stories-web">Writing user stories for web applications</a><br /><a href="http://css.dzone.com/articles/css3-pseudo-classes">CSS3 pseudo-classes</a><br /><a href="http://css.dzone.com/articles/death-buzzwords">Death by buzzwords</a><br /><a href="http://css.dzone.com/articles/testing-web-applications">Testing web applications with Selenium</a><br /><a href="http://css.dzone.com/articles/refactoring-breakthrough">The refactoring breakthrough on a CoffeeMachine</a><br /><a href="http://css.dzone.com/articles/lower-your-bar-test-driven">Lower your bar in Test-Driven Development</a><br /><a href="http://css.dzone.com/articles/web-mvc-java">Web MVC in Java (without frameworks)</a><br /><a href="http://css.dzone.com/articles/software-engineering-rail">Software engineering in the rail system</a><br /><a href="http://css.dzone.com/articles/web-applications-enterprise">Web applications as enterprise software</a><br /><a href="http://css.dzone.com/articles/all-you-have-know-about">The absolute minimum you'll ever have to know about session persistence on the web</a><br /><a href="http://css.dzone.com/articles/exceptional-javascript">Exceptional JavaScript</a><br /><a href="http://css.dzone.com/articles/jsp-are-more-templates">JSP are more than templates</a><br /><a href="http://css.dzone.com/articles/firebug-beautiful">Firebug is beautiful</a><br /><a href="http://css.dzone.com/articles/dojo-primer">A Dojo primer</a><br /><a href="http://css.dzone.com/articles/php-inclusions">PHP inclusions</a><br /><a href="http://css.dzone.com/articles/10-html-tags-which-are-not">10 HTML tags which are not used as often as they deserve</a><br /><a href="http://css.dzone.com/articles/webml-overcoming-uml-web">WebML: overcoming UML for web applications</a><br /><a href="http://css.dzone.com/articles/buzzword-glossary">The buzzword glossary</a><br /><a href="http://css.dzone.com/articles/charsets">The shortest guide to character sets you'll ever read</a><br /><a href="http://css.dzone.com/articles/wonders-input-tag-html-5">The wonders of the input tag in HTML 5</a><br /><a href="http://css.dzone.com/articles/native-jquery-animations">Native jQuery animations</a><br /><a href="http://css.dzone.com/articles/netbeans-vs-vim-php">NetBeans vs. Vim for PHP development</a><br /><a href="http://css.dzone.com/articles/different-kinds-testing">The different kinds of testing</a><br /><a href="http://css.dzone.com/articles/selenium-not-panacea">Selenium is not a panacea</a><br /><a href="http://css.dzone.com/articles/graceful-degradation-dead">Is graceful degradation dead?</a><br /><a href="http://css.dzone.com/articles/subversion-git-morning">From Subversion to Git in a morning</a><br /><a href="http://css.dzone.com/articles/why-pomodoro-helps-you-getting">Why a Pomodoro helps you getting in the zone</a><br /><a href="http://css.dzone.com/articles/phpunit-35-easier-asserting">PHPUnit 3.5: easier asserting and mocking</a><br /><a href="http://css.dzone.com/articles/css-refactoring">CSS refactoring</a><br /><a href="http://css.dzone.com/articles/php-paradigms-poll-results-oop">The PHP paradigms poll results: OOP wins</a><br /><a href="http://css.dzone.com/articles/how-set-pomodoro-technique">How to set up the Pomodoro Technique in your office</a><br /><a href="http://css.dzone.com/articles/what-you-need-know-about-your">What you need to know about your version control system</a><br /><a href="http://css.dzone.com/articles/paint-canvas-van-gogh">Paint on a canvas like Van Gogh</a><br /><a href="http://css.dzone.com/articles/must-know-color-theory">The must-know of color theory</a><br /><a href="http://css.dzone.com/articles/you-dont-have-always-stare">You don't have to always stare at a screen</a><br /><a href="http://css.dzone.com/articles/what-we-dont-need-object">What we don't need in object-oriented programming</a><br /><a href="http://css.dzone.com/articles/invest-user-stories">INVEST in user stories</a><br /><a href="http://css.dzone.com/articles/primitive-obsession">Primitive Obsession</a><br /><a href="http://css.dzone.com/articles/5-features-php">5 features of PHP that seem hacks, but save your life</a><br /><a href="http://css.dzone.com/articles/doctrine-1-doctrine-2">From Doctrine 1 to Doctrine 2</a><br /><a href="http://css.dzone.com/articles/dark-side-lean">The Dark Side of Lean</a><br /><a href="http://css.dzone.com/articles/lego-bricks">It's just like putting LEGO bricks together... Or not?</a><br /><a href="http://css.dzone.com/articles/best-tools-writing-uml">The best tools for writing UML diagrams</a><br /><a href="http://css.dzone.com/articles/zendglossary">Zend_Glossary</a><br /><a href="http://css.dzone.com/articles/date-and-time-php-5">Date and time in PHP 5</a><br /><a href="http://css.dzone.com/articles/zendvalidate-win">Zend_Validate for the win</a><br /><a href="http://css.dzone.com/articles/meaningless-docblocks">Meaningless docblocks considered harmful</a><br /><a href="http://css.dzone.com/articles/double-dispatch-next-best">Double Dispatch: the next best thing with respect to Dependency Injection</a><br /><a href="http://css.dzone.com/articles/zendlocale-win">Zend_Locale for the win</a><br /><a href="http://css.dzone.com/articles/technical-investment-or">Technical Investment, or quality vs. time</a><br /><a href="http://css.dzone.com/articles/real-life-closures-examples">Real-life closures examples ...for real</a><br /><a href="http://css.dzone.com/articles/client-applications-ajax-solr">Client applications with Ajax Solr: JavaScript vs. servlets</a><br /><a href="http://css.dzone.com/articles/sitting-couch">Sitting on the couch</a><br /><a href="http://css.dzone.com/articles/what-cooking-can-teach">What cooking can teach to a software developer</a><br /><a href="http://css.dzone.com/articles/couchdb-javascript">CouchDB from JavaScript</a><br /><a href="http://css.dzone.com/articles/reuse-your-closures-functors">Reuse your closures with functors</a><br /><a href="http://css.dzone.com/articles/these-are-not-buzzwords-youre">These are not the buzzwords you're looking for</a><br /><a href="http://css.dzone.com/articles/tdd-algorithms">TDD for algorithms: the state of the art</a><br /><a href="http://css.dzone.com/articles/small-infographic">An humble infographic on methodologies</a><br /><a href="http://css.dzone.com/articles/why-twitter-not-rss">Why Twitter is not an RSS replacement</a><br /><a href="http://css.dzone.com/articles/5-things-php-envies-java">5 things that PHP envies Java for</a><br /><a href="http://css.dzone.com/articles/pagerank-5-minutes">PageRank in 5 minutes</a><br /><a href="http://css.dzone.com/articles/where-has-xhtml-gone">Where has XHTML gone?</a><br /><a href="http://css.dzone.com/articles/behavior-driven-development-0">Behavior-Driven Development in PHP with Behat</a><br /><a href="http://css.dzone.com/articles/do-not-fear-command-line">Do not fear the command line</a><br /><a href="http://css.dzone.com/articles/can-you-use-php-without">Can you use PHP without frameworks nowadays?</a><br /><a href="http://css.dzone.com/articles/why-ruby-monkey-patching">Why Ruby's monkey patching is better than land mines...wait, what?</a><br /><a href="http://css.dzone.com/articles/how-remove-getters-and-setters">How to remove getters and setters</a><br /><a href="http://css.dzone.com/articles/solid-packag-err-namespaces">SOLID for packag... err, namespaces</a><br /><a href="http://css.dzone.com/articles/what-you-must-know-about-php">What you must know about PHP errors to avoid scratching your forehead when something goes wrong</a><br /><a href="http://css.dzone.com/articles/programmer-cloud">A programmer on the cloud</a><br /><a href="http://css.dzone.com/articles/github-web-application-twitter">GitHub is a web application, Twitter is not (yet)</a><br /><a href="http://css.dzone.com/articles/eliminating-duplication">Eliminating duplication</a><br /><a href="http://css.dzone.com/articles/table-free-css-layouts-10">Table-free CSS layouts in 10 minutes</a><br /><a href="http://css.dzone.com/articles/web-workers-responsive">Web Workers, for a responsive JavaScript application</a><br /><a href="http://css.dzone.com/articles/how-enrich-lawyers">How to enrich lawyers</a><br /><a href="http://css.dzone.com/articles/what-firefox-4-means-web">What Firefox 4 means to web developers?</a><br /><a href="http://css.dzone.com/articles/php-frameworks-poll-results">The PHP frameworks poll results</a><br /><a href="http://css.dzone.com/articles/struts-vs-zend-framework">Struts vs. Zend Framework</a><br /><a href="http://css.dzone.com/articles/http-your-wrench">HTTP is your wrench</a><br /><a href="http://css.dzone.com/articles/measures-programming">The measures of programming</a><br /><a href="http://css.dzone.com/articles/we-cannot-avoid-testing">We cannot avoid testing JavaScript anymore</a><br /><a href="http://css.dzone.com/articles/websockets-5-minutes">WebSockets in 5 minutes</a><br /><a href="http://css.dzone.com/articles/git-rebase">Linear trees with Git rebase</a><br /><a href="http://css.dzone.com/articles/exploring-tdd-javascript-small">Exploring TDD in JavaScript with a small kata</a><br /><a href="http://css.dzone.com/articles/all-you-want-know-about-web">All you want to know about Web Storage</a><br /><a href="http://css.dzone.com/articles/classical-inheritance">Classical inheritance in JavaScript</a><br /><a href="http://css.dzone.com/articles/mockery-review">A Mockery review</a><br /><a href="http://css.dzone.com/articles/gang-four-patterns-everyday">The Gang of Four patterns as everyday objects</a><br /><a href="http://css.dzone.com/articles/php-uml-generation-live-object">PHP UML generation from a live object graph</a><br /><a href="http://css.dzone.com/articles/bleeding-edge-javascript">Bleeding edge JavaScript for object orientation</a><br /><a href="http://css.dzone.com/articles/4-rules-simple-design">The 4 rules of simple design</a><br /><a href="http://css.dzone.com/articles/git-backups-and-no-its-not">Git backups, and no, it's not just about pushing</a><br /><a href="http://css.dzone.com/articles/how-bomb-technical-talk">How to bomb a technical talk</a><br /><a href="http://css.dzone.com/articles/extreme-programming-values">The eXtreme Programming Values</a><br /><a href="http://css.dzone.com/articles/web-services-java">Web services in Java</a><br /><a href="http://css.dzone.com/articles/kindle-3-finally-nails">The Kindle is ready for programmers</a><br /><a href="http://css.dzone.com/articles/commit-and-commit-messages">On commits and commit messages</a><br /><a href="http://css.dzone.com/articles/victorian-internet-and">The Victorian Internet, and the Victorian social networks</a><br /><a href="http://css.dzone.com/articles/parallelism-dummies">Parallelism for dummies</a><br /><a href="http://css.dzone.com/articles/automated-code-reviews-php">Automated code reviews for PHP</a><br /><a href="http://css.dzone.com/articles/monitoring-unix-scratch">Monitoring on Unix from scratch</a><br /><a href="http://css.dzone.com/articles/i-dont-know-how-test">I don't know how to test this</a><br /><a href="http://css.dzone.com/articles/week-without-flash">A week without Flash</a><br /><a href="http://css.dzone.com/articles/self-initializing-fakes-php">Self-Initializing Fakes in PHP</a><br /><a href="http://css.dzone.com/articles/testing-javascript-when-dom">Testing JavaScript when the DOM gets in the way</a><br /><a href="http://css.dzone.com/articles/era-object-document-mapping">The era of Object-Document Mapping</a><br /><a href="http://css.dzone.com/articles/hateoas-scary-acronym">HATEOAS, the scary acronym</a><br /><a href="http://css.dzone.com/articles/unit-testing-javascript-code">Unit testing JavaScript code when Ajax gets in the way</a><br /><a href="http://css.dzone.com/articles/phantom-js-alternative">Phantom JS: an alternative to Selenium</a><br /><a href="http://css.dzone.com/articles/symfony-2-eyes-zfer">Symfony 2 from the eyes of a ZFer</a><br /><a href="http://css.dzone.com/articles/php-54-features-poll-results">PHP 5.4 features poll: the results</a><br /><a href="http://css.dzone.com/articles/how-be-worse-programmer">How to be a worse programmer</a><br /><a href="http://css.dzone.com/articles/coffeescript-tdd-example">CoffeeScript: a TDD example</a><br /><a href="http://css.dzone.com/articles/assetic-javascript-and-css">Assetic: JavaScript and CSS files management</a><br /><a href="http://css.dzone.com/articles/fastest-browser-poll-results">The fastest browser poll: results</a><br /><a href="http://css.dzone.com/articles/syntactically-awesome">Syntactically Awesome Stylesheets</a><br /><a href="http://css.dzone.com/articles/edge-side-includes-varnish-10">Edge Side Includes with Varnish in 10 minutes</a><br /><a href="http://css.dzone.com/articles/rapha%C3%ABl-cross-browser-drawings">Raphaël: cross-browser drawings</a><br /><a href="http://css.dzone.com/articles/future-javascript-today">Future JavaScript, today: Google's Traceur</a><br /><a href="http://css.dzone.com/articles/backbonejs-mvc-javascript">Backbone.js: MVC in JavaScript</a><br /><a href="http://css.dzone.com/articles/web-typography-2011">Web typography in 2011</a><br /><a href="http://css.dzone.com/articles/practical-google-api">Practical Google+ Api</a><br /><a href="http://css.dzone.com/articles/phar-php-libraries-single-file">Phar: PHP libraries included with a single file</a><br /><a href="http://css.dzone.com/articles/cross-site-request-forgery">Cross-Site Request Forgery explained</a><br /><a href="http://css.dzone.com/articles/pretotyping-complete-example">Pretotyping: a complete example</a><br /><a href="http://css.dzone.com/articles/zend-framework-application">Zend Application demystified</a><br /><a href="http://css.dzone.com/articles/all-git-hooks-you-need">All the Git hooks you need</a><br /><a href="http://css.dzone.com/articles/temporal-correlation-git">Temporal correlation in Git repositories</a><br /><a href="http://css.dzone.com/articles/goal-software-development">The Goal of software development</a><br /><a href="http://css.dzone.com/articles/what-i-have-learned-ddd-day">What I have learned at DDD Day</a><br /><a href="http://css.dzone.com/articles/oauth-headless-applications">OAuth in headless applications</a><br /><a href="http://css.dzone.com/articles/look-dart-eyes-oo-programmer">A look at Dart from the eyes of an OO programmer</a><br /><a href="http://css.dzone.com/articles/and-now-instead-5-things-java">And now instead, 5 things Java envies PHP for</a><br /><a href="http://css.dzone.com/articles/tell-dont-ask-case-web-service">Tell, Don't Ask in the case of a web service</a><br /><a href="http://css.dzone.com/articles/getting-started-selenium-2">Getting started with Selenium 2</a><br /><a href="http://css.dzone.com/articles/ive-had-enough-running-scala">I've had enough of running Scala in a terminal, let's try with a web application</a><br /><a href="http://css.dzone.com/articles/using-virtual-machine-play">Using a virtual machine to play with multiple versions of PHP</a><br /><a href="http://css.dzone.com/articles/php-java-application-server">PHP on a Java application server</a><br /><a href="http://css.dzone.com/articles/web-applications-play">Web applications with the Play framework</a><br /><a href="http://css.dzone.com/articles/selenium-2-php-code">Selenium 2 from PHP code</a><br /><a href="http://css.dzone.com/articles/eventual-consistency">Eventual consistency is everywhere in the real world</a><br /><a href="http://css.dzone.com/articles/setting-lamp-box-puppet">Setting up a LAMP box with Puppet</a><br /><a href="http://css.dzone.com/articles/phonegap-native-applications">PhoneGap: native applications written in HTML</a><br /><a href="http://css.dzone.com/articles/drag-and-drop-uploading">HTML5 Drag and Drop uploading</a><br /><a href="http://css.dzone.com/articles/testing-and-specifying">Testing and specifying JavaScript code with Jasmine</a><br /><a href="http://css.dzone.com/articles/what-i-learned-global-day-code">What I learned in the Global Day of Code Retreat</a><br /><a href="http://css.dzone.com/articles/creating-virtual-server">Creating a virtual server with Vagrant: a practical walkthrough</a><br /><a href="http://css.dzone.com/articles/clojure-dummies-kata-0">Clojure for dummies: a kata</a><br /><a href="http://css.dzone.com/articles/rails-point-view-php-developer">Rails from the point of view of a PHP developer</a><br /><a href="http://css.dzone.com/articles/spark-micro-framework">The Spark micro framework</a><br /><a href="http://css.dzone.com/articles/3d-experience-browser-threejs">3D experience in a browser with Three.js</a><br /><a href="http://css.dzone.com/articles/clojure-libraries-and-builds">Clojure libraries and builds with Leiningen</a><br /><a href="http://css.dzone.com/articles/open-source-php-projects-2011">Open source PHP projects of 2011</a><br /><a href="http://css.dzone.com/articles/tdd-multithreaded-applications">TDD for multithreaded applications</a><br /><a href="http://css.dzone.com/articles/web-application-clojure">Web application in Clojure: the starting point</a><br /><a href="http://css.dzone.com/articles/object-oriented-clojure">Object-oriented Clojure</a><br /><a href="http://css.dzone.com/articles/openclosed-principle-real">Open/Closed Principle on real world code</a><br /><a href="http://css.dzone.com/articles/python-hello-world-web">Python Hello World, for a web application</a><br /><a href="http://css.dzone.com/articles/offline-web-applications">Offline web applications: a working example</a><br /><a href="http://css.dzone.com/articles/jquery-plugins-jstestdriver">jQuery plugins with jsTestDriver</a><br /><a href="http://css.dzone.com/articles/ajax-requests-other-domains">Ajax requests to other domains with Cross-Origin Resource Sharing</a><br /><a href="http://css.dzone.com/articles/unit-testing-when-value">Unit testing when Value Objects get in the way</a><br /><a href="http://css.dzone.com/articles/introduction-r-language">An Introduction to the R Language</a><br /><a href="http://css.dzone.com/articles/my-use-case-checked-exceptions">My use case for checked exceptions</a><br /><a href="http://css.dzone.com/articles/what-wsgi">What WSGI is</a><br /><a href="http://css.dzone.com/articles/decorator-pattern-or-its">The Decorator pattern, or its cousin, in JavaScript</a><br /><a href="http://css.dzone.com/articles/bottle-lightweight-python">Bottle: a lightweight Python framework</a><br /><a href="http://css.dzone.com/articles/spam-filtering-naive-bayes">Spam filtering with a Naive Bayes Classifier in R</a><br /><a href="http://css.dzone.com/articles/erlangs-actor-model">Erlang's actor model</a><br /><a href="http://css.dzone.com/articles/7-habits-highly-effective">The 7 habits of highly effective developers</a><br /><a href="http://css.dzone.com/articles/our-experience-domain-events">Our experience with Domain Events</a><br /><a href="http://css.dzone.com/articles/audio-html-5-state-art">Audio in HTML 5: state of the art</a><br /><a href="http://css.dzone.com/articles/running-javascript-inside-php">Running JavaScript inside PHP code</a><br /><a href="http://css.dzone.com/articles/gradient-descent-octave">Gradient descent in Octave</a><br /><a href="http://css.dzone.com/articles/zend-framework-2-tryout">A Zend Framework 2 tryout</a><br /><a href="http://css.dzone.com/articles/asynchronous-and-negative">Asynchronous and negative testing</a><br /><a href="http://css.dzone.com/articles/all-mouse-events-javascript">All the mouse events in JavaScript</a><br /><a href="http://css.dzone.com/articles/everything-you-need-know-about">Everything you need to know about Python exceptions</a><br /><a href="http://css.dzone.com/articles/css-bits-mouse-cursor">CSS Bits: The Mouse Cursor</a><br /><a href="http://css.dzone.com/articles/bootstrap-rapid-development">Bootstrap: rapid development and the complexity of a framework</a><br /><a href="http://css.dzone.com/articles/test-driven-emergent-design-vs">Test-Driven Emergent Design vs. Analysis</a><br /><a href="http://css.dzone.com/articles/php-objects-mongodb-doctrine">PHP objects in MongoDB with Doctrine</a><br /><a href="http://css.dzone.com/articles/travisci-examples">TravisCI Intro and PHP Example</a><br /><a href="http://css.dzone.com/articles/sometimes-python-magic">Sometimes Python is magic</a><br /><a href="http://css.dzone.com/articles/writing-clean-code-php-54">Writing clean code in PHP 5.4</a><br /><a href="http://css.dzone.com/articles/object-calisthenics">Object Calisthenics</a><br /><a href="http://css.dzone.com/articles/ajax-and-mvc">Ajax and MVC</a><br /><a href="http://css.dzone.com/articles/tdd-python-5-minutes">TDD in Python in 5 minutes</a><br /><a href="http://css.dzone.com/articles/test-driven-development-osgi">Test-Driven Development with OSGi</a><br /><a href="http://css.dzone.com/articles/including-php-libraries">Including PHP libraries via Composer</a><br /><a href="http://css.dzone.com/articles/theres-no-reason-not-switch">There's no reason not to switch to DocBlox</a><br /><a href="http://css.dzone.com/articles/unknown-acronym-grasp">The unknown acronym: GRASP</a><br /><a href="http://css.dzone.com/articles/bullets-legacy-code">Bullets for legacy code</a><br /><a href="http://css.dzone.com/articles/finding-wiring-bugs">Finding wiring bugs</a><br /><a href="http://css.dzone.com/articles/2-years-vim-and-php-distilled">2 years of Vim and PHP distilled</a><br /><a href="http://css.dzone.com/articles/all-about-jms-messages">All about JMS messages</a><br /><a href="http://css.dzone.com/articles/asynchronous-processing-php">Asynchronous processing in PHP</a><br /><a href="http://css.dzone.com/articles/page-object-pattern">The Page Object pattern</a><br /><a href="http://css.dzone.com/articles/software-versions-necessary">Software versions, the necessary evil</a><br /><a href="http://css.dzone.com/articles/commodities-it-world">Commodities in the IT world</a><br /><a href="http://css.dzone.com/articles/return-vim">The return of Vim</a><br /><a href="http://css.dzone.com/articles/whats-name">What's in a name?</a><br /><a href="http://css.dzone.com/articles/standard-php-setup">The standard PHP setup</a><br /><a href="http://css.dzone.com/articles/selenium-android">Selenium on Android</a><br /><a href="http://css.dzone.com/articles/hexagonal-architecture">Hexagonal architecture in JavaScript </a><br /><a href="http://css.dzone.com/articles/why-everyone-talking-about">Why everyone is talking about APIs</a><br /><a href="http://css.dzone.com/articles/testing-php-scripts">Testing PHP scripts</a><br /><a href="http://css.dzone.com/articles/software-metaphors">Software Metaphors</a><br /><a href="http://css.dzone.com/articles/mongodb-and-java">MongoDB and Java</a><br /><a href="http://css.dzone.com/articles/phpspec-bdd-your-classes">PHPSpec: BDD for your classes</a><br /><a href="http://css.dzone.com/articles/what-global-state">What is global state?</a><br /><a href="http://css.dzone.com/articles/crash-course-mongodb-console">A crash course for the MongoDB console</a><br /><a href="http://css.dzone.com/articles/my-love-story-ssh">My love story with SSH</a><br /><a href="http://css.dzone.com/articles/surgery-metaphor">The surgery metaphor</a><br /><a href="http://css.dzone.com/articles/phpunitselenium">PHPUnit_Selenium</a><br /><a href="http://css.dzone.com/articles/turing-test-0">The Turing test</a><br /><a href="http://css.dzone.com/articles/function-javascript">Functional JavaScript with Underscore.js</a><br /><a href="http://css.dzone.com/articles/record-and-replay-testing">Record and replay for testing of legacy PHP applications</a><br /><a href="http://css.dzone.com/articles/php-54-examples">PHP 5.4 by examples</a><br /><a href="http://css.dzone.com/articles/my-take-utility-and-strategic">My take on Utility and Strategic software</a><br /><a href="http://css.dzone.com/articles/duck-lie">The Duck is a Lie</a><br /><a href="http://css.dzone.com/articles/getting-know-solr">Set Up Solr and Get it Running</a><br /><a href="http://css.dzone.com/articles/all-debugging-and-no-testing">All debugging and no testing makes the PHP programmer a dull boy</a><br /><a href="http://css.dzone.com/articles/all-ways-perform-http-requests">All the ways to perform HTTP requests in PHP</a><br /><a href="http://css.dzone.com/articles/roman-numerals-kata-tdd-and">The Roman numerals kata: TDD with and without analysis</a><br /><a href="http://css.dzone.com/articles/refactoring-away-spaghetti-php">Refactoring away from spaghetti PHP</a><br /><a href="http://css.dzone.com/articles/what-statistical-learning">What is statistical learning?</a><br /><a href="http://css.dzone.com/articles/why-i-am-functophobic">Why I am functophobic</a><br /><a href="http://css.dzone.com/articles/how-build-kanban-board">How to build a Kanban board</a><br /><a href="http://css.dzone.com/articles/introduction-weka">An Introduction to WEKA - Machine Learning in Java</a><br /><a href="http://css.dzone.com/articles/how-take-unit-testing-and-test">How to Take Unit Testing (and Test-Driving) Seriously</a><br /><a href="http://css.dzone.com/articles/transform-switches-maps">Transform switches in maps</a><br /><a href="http://css.dzone.com/articles/manual-test-driven-development">Manual Test-Driven Development</a><br /><a href="http://css.dzone.com/articles/errors-part-learning-curve">Errors: part of the learning curve</a><br /><a href="http://css.dzone.com/articles/build-your-own-java-stopwatch">Build your own Java stopwatch</a><br /><a href="http://css.dzone.com/articles/development-latex-documents">Development of Latex documents</a><br /><a href="http://css.dzone.com/articles/pomodoro-updates">The Pomodoro updates</a><br /><a href="http://css.dzone.com/articles/problem-user-identity">The problem of user identity</a><br /><a href="http://css.dzone.com/articles/dont-overspecify-your-mocks">Don't overspecify your mocks</a><br /><a href="http://css.dzone.com/articles/factory-patterns-collaborators">Factory patterns: Collaborators Map</a><br /><a href="http://css.dzone.com/articles/perils-long-running-test">The perils of long-running test suites</a><br /><a href="http://css.dzone.com/articles/crc-cards-primer">A CRC cards primer</a><br /><a href="http://css.dzone.com/articles/no-one-always-needs-framework">No one always needs a framework</a><br /><a href="http://css.dzone.com/articles/scheduling-not-same-computers">Scheduling is not the same for computers and people</a><br /><a href="http://css.dzone.com/articles/dont-ignore-errors">Don't ignore errors</a><br /><a href="http://css.dzone.com/articles/why-having-api-matters-testing">Why having an API matters: testing</a><br /><a href="http://css.dzone.com/articles/what-i-learned-italian-agile">What I learned at the Italian Agile Day 2012</a><br /><a href="http://css.dzone.com/articles/preparing-coach-game-life">Preparing to coach with the Game of Life</a><br /><a href="http://css.dzone.com/articles/lessons-learned-code-retreat">Lessons learned from the Code Retreat</a><br /><a href="http://css.dzone.com/articles/danger-large-releases-trenord">The danger of large releases: Trenord case study</a><br /><a href="http://css.dzone.com/articles/oo-vs-functional-game-life">OO vs. functional: the Game of Life</a><br /><a href="http://css.dzone.com/articles/code-katas-ruzzle-solver">Code Katas: Ruzzle solver</a><br /><a href="http://css.dzone.com/articles/agile-traveling">Agile traveling</a><br /><a href="http://css.dzone.com/articles/how-acid-mongodb">How ACID is MongoDB?</a><br /><a href="http://css.dzone.com/articles/solid-principles-are-they">SOLID principles: are they enough for OO?</a><br /><a href="http://css.dzone.com/articles/caring-about-build-files">Caring about build files</a><br /><a href="http://css.dzone.com/articles/thinking-value-terms">Thinking in value terms</a><br /><a href="http://css.dzone.com/articles/why-hateoas-not-witch-burn"> Why HATEOAS is not the witch to burn</a><br /><a href="http://css.dzone.com/articles/carriers-vs-osi-model">Carriers vs. the OSI model</a><br /><a href="http://css.dzone.com/articles/how-correctly-work-php">How to correctly work with PHP serialization </a><br /><a href="http://css.dzone.com/articles/pomodoro-2013-edition">Pomodoro, 2013 edition</a><br /><a href="http://css.dzone.com/articles/experiences-book-club">Experiences with the book club</a><br /><a href="http://css.dzone.com/articles/external-processes-and-php">External processes and PHP</a><br /><a href="http://css.dzone.com/articles/php-streams-everything">PHP streams for everything</a><br /><a href="http://css.dzone.com/articles/isolation-mongodb">Isolation in MongoDB</a><br /><a href="http://css.dzone.com/articles/phps-mcrypt">PHP's mcrypt</a><br /><a href="http://css.dzone.com/articles/design-choices-return-values">Design Choices: Return Values and Mocks</a><br /><a href="http://css.dzone.com/articles/contributing-paratest">Contributing to Paratest</a><br /><a href="http://css.dzone.com/articles/java-php">From Java to PHP</a><br /><a href="http://css.dzone.com/articles/continuous-integration-and">Continuous Integration and Pull Requests</a><br /><a href="http://css.dzone.com/articles/mongodb-24-out">MongoDB 2.4 is Out!</a><br /><a href="http://css.dzone.com/articles/monoids-php">Monoids in PHP</a><br /><a href="http://css.dzone.com/articles/cancer-automated-testing"> Automated Testing is Cancer</a><br /><a href="http://css.dzone.com/articles/diving-behat">Diving into Behat</a><br /><a href="http://css.dzone.com/articles/monitoring-datadog">Monitoring with DataDog</a><br /><a href="http://css.dzone.com/articles/trying-out-php-refactoring">Trying out PHP Refactoring Browser</a><br /><a href="http://css.dzone.com/articles/difficult-relationship-between"> The difficult relationship between developers and business</a><br /><a href="http://css.dzone.com/articles/whats-constructor"> What's in a constructor?</a><br /><a href="http://css.dzone.com/articles/phpunit-vs-phake-cheatsheet">PHPUnit vs. Phake cheatsheet</a><br /><a href="http://css.dzone.com/articles/how-stub-soap-php">How to stub SOAP in PHP </a><br /><a href="http://css.dzone.com/articles/many-ubiquitous-languages">Many Ubiquitous Languages</a><br /><a href="http://css.dzone.com/articles/accessing-apis-without-taking"> Accessing APIs without taking down your own application</a><br /><a href="http://css.dzone.com/articles/game-life-haskell">Game of life in Haskell</a><br /><a href="http://css.dzone.com/articles/cloning-php">Cloning in PHP</a><br /><a href="http://css.dzone.com/articles/slack-missing-concept">Slack, the missing concept</a><br /><a href="http://css.dzone.com/articles/simple-strategy-dotfiles">A simple strategy for dotfiles</a><br /><a href="http://css.dzone.com/articles/nosql-does-not-mean-no">NoSQL does not mean no migrations (but opens up new ways of doing them)</a><br /><a href="http://css.dzone.com/articles/serialization-and-injection">Serialization and injection</a><br /><a href="http://css.dzone.com/articles/r-word">The R-word</a><br /><a href="http://css.dzone.com/articles/selenium-screenshots-rendering">Selenium screenshots for rendering tests</a><br /><a href="http://css.dzone.com/articles/pitfalls"> The pitfalls of O(N)</a><br /><a href="http://css.dzone.com/articles/how-think-about-patterns">How to think about patterns</a><br /><a href="http://css.dzone.com/articles/why-not-add-new-feature">Why not add this new feature?</a><br /><a href="http://css.dzone.com/articles/continuous-deployment">Continuous Deployment Demystified</a><br /><a href="http://css.dzone.com/articles/backward-compatibility-even">Backward compatibility, even inside a single project</a><br /><a href="http://css.dzone.com/articles/legacy-code-retreat">The Legacy Code Retreat</a><br /><a href="http://css.dzone.com/articles/xp-values-simplicity">XP Values: Simplicity</a><br /><a href="http://css.dzone.com/articles/xp-values-feedback">XP Values: Feedback</a><br /><a href="http://css.dzone.com/articles/memcache-102">Memcache 102</a><br /><a href="http://css.dzone.com/articles/my-vim-values">My Vim values</a><br /><a href="http://css.dzone.com/articles/review-implementing-domain">Review: Implementing Domain-Driven Design</a><br /><a href="http://css.dzone.com/articles/upgrading-php-trenches">Upgrading PHP, from the trenches</a><br /><a href="http://css.dzone.com/articles/elephant-carpaccio-user">Elephant Carpaccio (on user stories)</a><br /><a href="http://css.dzone.com/articles/battle-legacy-reducing-ifs">Battle with legacy: reducing ifs</a><br /><a href="http://css.dzone.com/articles/management-30-review">Management 3.0 review</a><br /><a href="http://css.dzone.com/articles/openclosed-principle-kata">An Open/Closed Principle kata</a><br /><a href="http://css.dzone.com/articles/notes-software-team-leader">Notes to a Software Team Leader Review</a><br /><a href="http://css.dzone.com/articles/xp-values-courage">XP Values: Courage</a><br /><a href="http://css.dzone.com/articles/importing-data-api-way">Importing data, the API way</a><br /><a href="http://css.dzone.com/articles/xp-values-communication">XP Values: Communication</a><br /><a href="http://css.dzone.com/articles/how-shard-cron">How to shard a cron</a><br /><a href="http://css.dzone.com/articles/little-toolbox-php-performance">The little toolbox of PHP performance optimization</a><br /><a href="http://css.dzone.com/articles/how-lazydecorator-can-let-your">How a LazyDecorator can let your application avoid building massive object graphs</a><br /><a href="http://css.dzone.com/articles/karate-chop">Karate Chop</a><br /><a href="http://css.dzone.com/articles/what-your-test-suite-wont">What your test suite won't catch</a><br /><a href="http://css.dzone.com/articles/book-review-slack">Book review: Slack</a><br /><a href="http://css.dzone.com/articles/unix-commands-dealing">Unix commands for dealing with structured text</a><br /><a href="http://css.dzone.com/articles/programmers-information-diet"> The programmer's information diet</a><br /><a href="http://css.dzone.com/articles/six-months-behat">Six months of Behat</a><br /><a href="http://css.dzone.com/articles/revisiting-conways-law">Revisiting Conway's law</a><br /><a href="http://css.dzone.com/articles/unix-lessons-sed">Unix lessons: sed</a><br /><a href="http://css.dzone.com/articles/object-relational-mapping">Object-relational mapping: seriously</a><br /><a href="http://css.dzone.com/articles/migration-aws-part-1">Migration to AWS: part 1</a><br /><a href="http://css.dzone.com/articles/pull-model-event-stores">A pull model for Event Stores</a><br /><a href="http://css.dzone.com/articles/book-review-puritan-gift">Book review: The Puritan Gift</a><br /><a href="http://css.dzone.com/articles/book-review-feedback-control">Book review: Feedback control for computer systems</a><br /><a href="http://css.dzone.com/articles/migration-aws-part-2">Migration to AWS: part 2</a><br /><a href="http://css.dzone.com/articles/different-kind-kata-harry"> A different kind of kata: Harry Potter books</a><br /><a href="http://css.dzone.com/articles/migration-aws-part-3">Migration to AWS, part 3</a><br /><a href="http://css.dzone.com/articles/http-katas">HTTP katas</a><br /><a href="http://css.dzone.com/articles/two-days-business-side">Two days in the business side</a><br /><a href="http://css.dzone.com/articles/configuration-code">Configuration is code</a><br /><a href="http://css.dzone.com/articles/rest-callbacks">REST callbacks</a><br /><a href="http://css.dzone.com/articles/distributed-time">Distributed time</a><br /><a href="http://css.dzone.com/articles/course-jb-rainsberger">A course with J.B. Rainsberger</a><br /><a href="http://css.dzone.com/articles/italian-agile-days-2013"> Italian Agile Days 2013</a><br /><a href="http://css.dzone.com/articles/mongodb-and-its-locks">MongoDB and its locks</a><br /><a href="http://css.dzone.com/articles/roman-numerals-towards-reuse">Roman numerals, towards reuse</a><br /><a href="http://css.dzone.com/articles/global-day-code-retreat-2013">Global Day of Code Retreat 2013</a><br /><a href="http://css.dzone.com/articles/no-return-statements">No return statements</a><br /><a href="http://css.dzone.com/articles/long-running-php-processes">Long-running PHP processes: external resources</a><br /><a href="http://css.dzone.com/articles/mongodb-christmas-optimization">MongoDB Christmas optimization</a><br /><a href="http://css.dzone.com/articles/stand-back-im-going-try">Stand back, I'm going to try science!</a><br /><a href="http://css.dzone.com/articles/angularjs-first-impression">AngularJS: first impression</a><br /><a href="http://css.dzone.com/articles/using-apc-correctly">Using APC correctly</a><br /><a href="http://css.dzone.com/articles/parallel-phpunit">Parallel PHPUnit</a><br /><br /><h2>Polls</h2><a href="http://css.dzone.com/polls/what-paradigm-should-php">What paradigm should PHP applications embrace?</a><br /><a href="http://css.dzone.com/polls/touch-typing-mandatory">Is touch typing mandatory?</a><br /><a href="http://css.dzone.com/polls/dont-publish-next-week-which">Which PHP framework would you use today for a brand new application?</a><br /><a href="http://css.dzone.com/polls/which-browser-do-you-consider">Which browser do you consider the fastest?</a><br /><a href="http://css.dzone.com/polls/what-new-feature-php-54">What new feature in PHP 5.4 is the most important to you?</a><img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/ioGryK9_7qk" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com0http://www.giorgiosironi.com/2014/04/the-full-list-of-my-articles-on-dzone.htmltag:blogger.com,1999:blog-36547168.post-83710891052296990032014-04-23T21:57:00.000+02:002014-04-23T21:59:26.548+02:00Integrated tests are not feeling well. Long live design.<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-dEi3lLF_EOI/U1gISBSXbaI/AAAAAAAABI4/Il9uQHvKnHA/s1600/guns_and_roses.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://4.bp.blogspot.com/-dEi3lLF_EOI/U1gISBSXbaI/AAAAAAAABI4/Il9uQHvKnHA/s1600/guns_and_roses.jpg" height="300" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;"><i>Take me down to the big Rails city / where the tests are green and they take 10 minutes</i></td></tr></tbody></table>I checked the date this afternoon:<br /><span style="font-family: &quot;Courier New&quot;,Courier,monospace;">$ date<br />Wed Apr 23 14:38:08 CEST 2014</span><br />and apparently it's 2014, but there's still a widely held belief (<a href="http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html">in some circles</a>) that integrated (or end-to-end) tests should be favored over unit tests. A belief that Test-Driven Development does not have a beneficial influence on the quality of your tests and code.<br />So today I'm repeating a few things I have been writing about in the last years. <br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-g2G7giVVWOU/U1gVkIUiL_I/AAAAAAAABJQ/myCtZ6CvFMg/s1600/darth.jpeg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://3.bp.blogspot.com/-g2G7giVVWOU/U1gVkIUiL_I/AAAAAAAABJQ/myCtZ6CvFMg/s1600/darth.jpeg" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Don't be too proud of this technological terror you've constructed. The ability to INSERT a row is insignificant next to the power of Domain Models.</td></tr></tbody></table><h3>A few properties of unit tests</h3>Unit tests target one or a few objects at a time, without accessing different resources than the CPU and memory of the current process. With respect to integrated tests, they are:<br /><ul><li><b>Easier to write</b>: their setup phase takes a few lines where Test Doubles are injected in a constructor.</li><li><b>Faster</b>: a 1000-test suite takes <i>seconds</i> to run.</li><li><b>Isolated</b>: they cannot interfere with each other or with the global state of the process.</li><li><b>Repeatable</b>: they always give the same result no matter the initial conditions.</li><li><b>Precise</b>: they tell you which wire does not work instead that the car does not start.</li></ul><h3>Listen to your tests </h3><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody><tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-L4hSk_GqdpM/U1gVDhvyGpI/AAAAAAAABJI/PBBDfe_9C_4/s1600/015_bob_dylan_theredlist.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-L4hSk_GqdpM/U1gVDhvyGpI/AAAAAAAABJI/PBBDfe_9C_4/s1600/015_bob_dylan_theredlist.jpg" height="241" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">How many asserts must a man write down / before you call him a man</td></tr></tbody></table><br />That's not to say integrated tests are not useful: I have <a href="http://2014.phpday.it/talk/how-to-test-2-years-of-behavior-for-16-countries-in-4-minutes-and-30-seconds/">a talk coming up at phpDay</a> in which I will explain how our Behat test suite work and the optimizations we made to keep it under 5 minutes. Some concerns where integration tests shine are making sure systems built by different teams work together, refactoring legacy code, and acceptance-level tests written in the customer's language.<br />However, the ratio of unit tests to integrated tests should be in the range of 10 to 1, or even 50 to 1. If there is a force at work in a project that pushes for more integrated tests than unit tests, you are falling into a vicious cycle where instead of writing:<br /><span style="font-family: &quot;Courier New&quot;,Courier,monospace;">assertEquals("1.00", new Money(100).toString());</span><br />you're writing, more often than not:<br /><span style="font-family: &quot;Courier New&quot;,Courier,monospace;">createSubscription(); </span><br /><span style="font-family: &quot;Courier New&quot;,Courier,monospace;">assertEquals(</span><br /><span style="font-family: &quot;Courier New&quot;,Courier,monospace;">&nbsp;&nbsp;&nbsp; "&lt;span class="money"&gt;1.00&lt;/span&gt;",</span><br /><span style="font-family: &quot;Courier New&quot;,Courier,monospace;">&nbsp; &nbsp; findPriceTag(get("/subscription/" + id))</span><br /><span style="font-family: &quot;Courier New&quot;,Courier,monospace;">);</span><br />and promoting coupling between the Money, Subscription and PageTemplate objects.<br />The <i>Listen to the tests</i> principle tell us to take difficult-to-write integrated tests as a smell: a warning that we need to break the dependencies between objects to be able to reuse them, for example in isolated tests (lowering coupling); and move responsibilities around until objects respond to an interface with a small surface area (increasing cohesion).<br />The benefit of TDD is continuously applying these two forces in your codebase. Renouncing to it while favoring integrated tests is thinking you're able to do the same in your mind, for the rest of the life of your codebase. We test because we don't want to break features, such as being able to perform a payment; but we unit test because we don't want to impact non-functional concerns such as reuse and the ability to change.<br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-xd96iZxJnlg/U1gXlAUVpwI/AAAAAAAABJc/Hy8KJXCIKO4/s1600/scorpions.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-xd96iZxJnlg/U1gXlAUVpwI/AAAAAAAABJc/Hy8KJXCIKO4/s1600/scorpions.jpg" height="240" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Take me to the magic of the moment / on a glory night / where the objects of tomorrow dream away / in the wind of change</td></tr></tbody></table><h3>Resources</h3>I'll stop short. Here's where you can know more about integrated and unit tests, explained by some of the best people in the field. <br /><ul><li>The <a href="http://martinfowler.com/bliki/TestPyramid.html">Test Pyramid</a>, codified by Martin Fowler.</li><li><a href="http://blog.thecodewhisperer.com/2010/10/16/integrated-tests-are-a-scam/">Integrated tests are a scam</a> and J.B. Rainsberger's blog. Since following his TDD course last fall I have a better mental model of the test-driven process and its output.</li><li>Some <a href="http://www.mockobjects.com/search/label/listening%20to%20the%20tests">examples of listening to the tests</a> to pursue a simpler design.</li></ul>And finally the style of this post is inspired by <a href="http://aphyr.com/posts/284-call-me-maybe-mongodb">Call me maybe: MongoDB</a>. <img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/h_J9NsZDR1k" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com3http://www.giorgiosironi.com/2014/04/integrated-tests-are-not-feeling-well.htmltag:blogger.com,1999:blog-36547168.post-56928138540784625022014-03-09T13:57:00.000+01:002014-03-09T13:57:06.681+01:00The good old TCP/IP stackThere are theoretical models, such as the ISO/OSI one, that cast the Internet into a set of many levels in an attempt of standardization. The <a href="http://en.wikipedia.org/wiki/Internet_protocol_suite">Internet protocol suite</a>, also known as TCP/IP, describes instead what goes on in reality to show you this blog post. The suite is divided into multiple layers, each building on the previous one and containing several protocols that can be theoretically swapped with each other.<br />I may use some protocol-specific terminology for <i>antonomasia</i>, such as <i>frame</i>.<br /><h3>Link layer</h3>The link layer solves the problem: <i>how do I get a frame of bytes from one physical device to another?</i> Consider that the network resources, such as physical cables and radio frequencies, may be shared so that collision is possible. For the same reason, sometimes routing has to be available to identify who am I sending these bytes to; however this routing is physical, consisting of single point-to-point connections or of network card addresses.<br />Inside a local network, <b>Ethernet</b> and the <b>wireless</b> IEEE 802.11 standards have the lion's share of the market. Devices are identified by their firmware-based MAC addresses and the network may contain switches sending the frames travelling trough them to the correct recipient.<br />However, a local network is of limited utility nowadays. To talk with the rest of the world, more complex link layer protocols are needed: they get you from your <b>DSL</b> router to your ISP ones, maybe even involving multiple hops such as a section based on copper wires and one on optical fiber.<br />The link layer is closely coupled to the hardware available: different protocols work on different mediums such as wires, glass and electromagnetic waves. It is possible in theory to abstract the business logic (say, how to detect a collision) from the medium; however, it's like testing a Repository object by looking at the query that it generates instead of running it against the real database.<br /><h3>Internet layer</h3>In the Internet model, machines may have globally-recognizable addresses that have meaning outside their local network. Thanks to these IP addresses and the related protocols, you can solve the problem of <i>getting packets of data from one node in the world to another.</i><br />However, these packets have severe limitations:<br /><ul><li>they are of a limited or fixed size, that cannot be increased more than a few thousand bytes due to the packet switching model.</li><li>No order is guaranteed: packet may take different paths to get to the target host and arrive in any order. </li><li>Their transmission is best-effort, as there can be arbitrary packet loss. </li></ul>Inside the global network, all hops at the Internet layer level have an IP address; the source and target IP addresses are written inside each packet so that each intermediate node can route it towards the neighbor that is probably nearest to the target. You can imagine the complexity of constantly updating this routing table while addresses are (re)assigned every day.<br /><b>IP</b> (version 4 or 6) is not the only Internet layer protocol. <b>ICMP</b> is one of the other famous ones, used for example by ping and traceroute for troubleshooting.<br />Finally, note that due to the limitations of the public address ranges containing only 4 billion IPs, NAT and other techniques have been developed to provide private address spaces to local networks. This severely breaks the model of&nbsp; globally addressable nodes, as for example nodes inside your home or office network cannot accept incoming connections (without resorting to port forwarding). It is a necessary evil due to the ubiquitousness of IPv4 and its 32-bit address fields.<br /><h3>Transport layer</h3>The Internet layer provides global connectivity, but with the limitations described above. To provide a useful bidirectional communication channel, the Transport layer builds upon the unreliable packets of the Internet layer to provide <i>the illusion of a local IO stream</i>, the same you could get by reading a file.<br />Consider for example the Transmission Control Protocol, <b>TCP</b>; it provides:<br /><ul><li>reliable and ordered communication between hosts. Lost packets are retransmitted and sequence numbers to correct out-or-order arrival. </li><li>multiplexing of communication channels between two nodes single link via ports. I can connect to the same web server with multiple browsers without the HTML pages and images being returned messing with each other.</li></ul>Other protocols such as <b>UDP</b> are not optimized for reliable communications, but on other parameters like latency. What matters is that with a transport layer we can build a remote terminal which is conceptually the same as a local one, sending streams of text and receiving other text back.<br /><h3>Application layer</h3>Once we have transformed the mess of wires and network devices into a universal interface made of text and bytes, it's up to the application to do something useful with it. Protocols at the application layer differ in what they offer to the end user:<br /><ul><li>Identification of nodes with an host name even if its IP address changes or they are physically moved elsewhere (<b>DNS</b>).</li><li>A way to read and create hypertext/hypermedia documents and related resources (<b>HTTP</b>).</li><li>A secure terminal session on a remote machine (<b>SSH</b>).</li><li>Updates for the local clock of your machine so that it's always correctly set (<b>NTP</b>).</li><li>Voice and video chat (proprietary protocols usually).</li></ul><h3>Importance</h3>Why it's important to know how the full stack of the Internet protocols works?<br /><ul><li>When something breaks or slows down, it helps to identify the level at which the failure is happening, and contact the right person such as a your ISP, a system administrator that has to restart a VPN or a programmer not targeting the correct HTTP response code.</li><li>Layers are isolated from each other, so you can usually swap implementations inside one layer while keeping a system functional, sometimes sacrificing non-functional requirements such as performance. If your DSL line is down, you can use a mobile broadband Interney key without changing software.</li><li>Some problems are best solved inside a particular layer: congestion control by the transport layer, routing and visibility at the Internet layer. Why wasting energy in segregating responsibilities when there is already a standard division of labor we cannot change...</li></ul><img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/zg4w7UfssNM" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com0http://www.giorgiosironi.com/2014/03/the-good-old-tcpip-stack.htmltag:blogger.com,1999:blog-36547168.post-69970722406665587562014-01-26T17:17:00.002+01:002014-01-26T17:22:09.685+01:00Writing here again<div class="separator" style="clear: both; text-align: left;"><a href="http://4.bp.blogspot.com/-yZ-vEllSxzY/UuU0jHvaATI/AAAAAAAABFc/DvKC47AV9ag/s1600/dzone_02.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-yZ-vEllSxzY/UuU0jHvaATI/AAAAAAAABFc/DvKC47AV9ag/s1600/dzone_02.png" height="150" width="200" /></a></div>Starting from January 2014 I have stopped writing on DZone my standard 2 weekly articles. You can still find the complete archive of everything I have ever written on DZone (469 articles) on <a href="http://css.dzone.com/users/piccoloprincipe">my profile page</a>.<br /><br />It's a matter of simplification and <b>focus</b>: not having to juggle schedules and tasks from my day job at <a href="http://onebip.com/">Onebip</a> and from something else. <br /><br />Now I am back to writing here without any fixed schedule, which means I should be able to keep up quality without worrying about quantity. The time that goes into 4 small articles can be put inside a single one that is 100x more useful.<br /><br />Of course, the opposite can happen: without a fixed schedule I end up never writing. I hope my commuter's schedule will stimulate me with uninterrupted blocks of time in which to focus.<img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/tgcb3-ImNNo" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com0http://www.giorgiosironi.com/2014/01/writing-here-again.htmltag:blogger.com,1999:blog-36547168.post-38486028681481791372013-03-03T22:54:00.001+01:002014-03-27T17:45:08.257+01:00If you're a programmer, you don't need Alta Scuola Politecnica<b>TL;DR</b>: as a software developer, you can successfully ignore <a href="http://www.asp-poli.it/presentation/">Alta Scuola Politecnica</a> and pursue a career on your own so that you can be happy when you get up in the morning.<br /><br /><h3>What's this ASP</h3>The ASP in the title is not some form of programming language such as ASP.NET, but it's the acronym of Alta Scuola Politecnica, a joint program of the two major technical universities in Italy which attempts to select the top tier of master students.<br /><br />With the official brochure words:<br /><blockquote class="tr_bq">The ASP cultural project is aimed at complementing the MSc education (120 credits) with 30 additional credits, equally subdivided between courses and projects, so as to expose its students to a multidisciplinary way of managing complex problems and treat them in an innovative way. While the MS studies gives them extensive, deep, high-quality skills in focusing on a specific discipline, ASP studies broaden student's competence through interdisciplinarity and team-working.&nbsp;</blockquote>In my words: you work for two years on a project that usually never sees the light of day with people from other backgrounds, unless you count "it works on paper" as a deliverable. I heard ASP alumni defining this activity as "project simulation".<br /><br />In the other half of ASP, you are sent for three weeks a year in seminars where you can get wasted at the evening and then sleep with your fellows during the day while economics and innovation concepts are explained compressed in some hours.<br /><br />I've had this post for like months in my drafts, but never got to speak out loud. Let's dive into it: I hope this can serve as a note to the next computer engineer in PoliMi and PoliTo which will google about ASP when he is contacted to enter in it. I speak from personal experience (been there, done that) about the computer engineer role in Alta Scuola Politecnica, which has been for me using Prezi and Google Docs.<br /><br /><h3>Who pays this?</h3>The source of funds for paying teachers, trips, hotels, speakers, and so on, comes partly from the public education budget and from private companies sponsoring.<br /><br />However, and here's the catch, these companies are famous in the Italian communities (communities such as Grusp and XP User Groups, to name a few) to be the ones you don't want to work for. Why?<br /><br />Because they see programmers as a commodity of factory workers more than as capable designers of software systems. Basically, trying to pay as little as possible for as much hours as possible, possibly body renting you to another company. A developer role in these companies can usually be filled by postman and philosophy graduates that took a two-week Java course.<br /><br />The companies that you won't see in ASP: Google? No, of course, they're not even in Italy with technical people. Github? Etsy? Connextra? Sourcesense? Thoughtworks? You're dreaming. You will see however, companies that <i>are</i> the dream job of management engineers, just not of computer engineers that actually like&nbsp;to code.<br /><br /><h3>From inside PoliMi</h3>While I googled for ASP, I found <a href="http://home.dei.polimi.it/mandriol/SitoItaliano/consdidattica.html">this gem by Dino Mandrioli</a>, former president of the Consiglio Corso di Laurea Ingegneria Informatica. Which means: a computer engineer.<br /><br />His summary: "yet another piece of paper with some credits on it that we give to people that do not need it, because if someone's really good, he doesn't care about supplements".<br />The piece was written when ASP was first proposed inside PoliMi.<br /><br /><h3>Courses and projects</h3>These courses always have <i>innovation</i> in the title; they compress lots of concepts in an intensive week, and lets you work as a team on presentations.<br /><br />You know, when I submit a talk to a conference, is the by-product of several months of my workday activities. Why are we teaching students how to conjure up presentations from nowhere in the space of several hours is a mystery to me, but it may be a sought-after skill.<br /><br />About the projects, they range from designing satellites to helmets to mobile applications (since it's such a buzzword these days). Keep in mind the <i>design</i>&nbsp;verb: I never got to write code in a year. Imagine going to work and not write code for a year; what kind of position are you pursuing?<br />If the answer is "I don't want to write code" and you're not a hardware guy, stop reading now, quit Computer Engineering and pivot to philosophy.<br /><br /><h3>The students</h3>But I've been there; I'm no journalist or teacher, I'm a former ASP student who dropped out after the first year to pursue an interesting job with an Italian company, which lasted after graduation and became my full time occupation.<br /><br />So here's some anecdotes on what really happens inside Alta Scuola Politecnica, mainly during the 1-week seminars:<br /><ul><li>Everyone singing the Italian national anthem at dinner, because it was the 150th anniversaty of Italy unification. In retrospect, seem like we were part of Comunione&amp;Lberazione, but with a different religion.</li><li>Dozens of students late for the morning lesson because they were trashed from the previous night in a disco; event followed by mega-punishment of writing an additional paper about the week for everyone that was more than 30' late.</li><li>Ericsson speaker asking if someone had heard of Goldratt and being alone in raising my hand. Really, management courses do not name Goldratt and the Theory of Constraints even for a minute?</li><li>An high percentage of the students getting food poisoning at the former Olympic villages we were staying into. Twice. Maybe it was the cold mountain air.</li><li>Projects where there is no code or architecture to write. What contribution can a computer engineer make apart from wasting two years?</li></ul><div><br /></div><h3>Your career and job</h3>If you get to the point of entering ASP, <b>you're likely to be bright enough to excel at practically anything they can make you do</b>: presentation and slides, researching papers or tools. <b>This is a problem</b> because since you do not fail you continue to do work which is not meaningful to your career: the projects of the 10-credit Distributed Systems course in Milan are alone worth more for your personal experience that the whole of ASP. If, during a job interview, someone prefers to hear that you are good at teamwork because of ASP rather than the fully distributed application you wrote in Erlang, I suggest you to leave immediately.<br /><br />Moreover, if you again are entering ASP, <b>you're still bright enough that you do not have problems in finding a programming job, even in Italy</b>, even in crisis. What matters to your happiness and personal growth is which job you choose, and ASP does not serve you well in providing opportunities of which you can say "this company does cool stuff". Forget about Agile, TDD, Domain-Driven Design, ye who enter here.<br /><br />In fact, there is a large selection bias at work: ASPers are successful because the commitee selects people who is already likely to be successful, not because ASP teaches them anything more than the location of discos at Sestriere. That's a spurious correlation between attendance and results.<br /><br />For example, statement like "graduated ASPers find a job/enter PHD in less than 2 months after graduation" are not a surprise: probably all the people who are selected for ASP but do not enter or drop out still find a job immediately. They'se selecting the top 7.5% after all.<br /><br />This is like the old saying: it's getting into Harvard that matters, not finishing it. Other than Mark Zuckerberg, there's plenty of <a href="http://edition.cnn.com/2011/LIVING/04/08/famous.harvard.dropouts.mf/index.html">people that dropped out of Harvard</a>, but in the case of ASP we are not even talking about a degree: it's just an additional program for a master's degree.<br /><br />You can reply with: the connections made in such a college matter, the same goes for Alta Scuola Politecnica. I argue that <b>the best connections you can make in Italy, as a <i>computer engineer</i>, are not inside Alta Scuola Politecnica</b>.<br /><br />Here's who you should get in touch with if you want a job that does not involve Cobol or legacy Java that runs in the cellar of some bank:<br /><ul><li><a href="http://milano-xpug.pbworks.com/w/page/20915693/FrontPage">XP</a>, <a href="http://www.jugmilano.it/vqwiki/jsp/Wiki?StartingPoints">Java</a>, <a href="http://milano.grusp.org/">PHP</a>, <a href="http://www.ugidotnet.org/">.NET</a> User Groups. Free associations built by programmers, for programmers.</li><li>Practitioner conferences such as <a href="http://www.bettersoftware.it/">Better Software</a>, <a href="http://rome.codemotionworld.com/">Codemotion</a>, the <a href="http://www.agileday.it/front/">Italian Agile Day</a>.</li><li>Organizations such as the <a href="http://www.grusp.it/">Grusp</a>, or Indigeni Digitali.</li></ul><br />When I get inquiries from companies that found me through PoliMi I almost never reply, as it's always the same offer: you are a Junior, come here with an entry level position so that we can sell your hours to some other company that we made a big contract with.<br /><br />The people from these groups that I got to knew in the last years are the real heart of the programmer's community in Italy. They are what helped me select a sane, well-paid, fun job 6 months before graduation. Beat that, ASP.<br /><br /><img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/80KLGIvVsMc" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com1http://www.giorgiosironi.com/2013/03/if-youre-programmer-you-dont-need-alta.htmltag:blogger.com,1999:blog-36547168.post-80859997860311698102013-02-09T15:43:00.000+01:002013-02-09T15:43:15.268+01:00PHP Benelux 2013In January I've been speaking at <a href="http://conference.phpbenelux.eu/2013/">PHP Benelux 2013</a>, one of the major PHP conferences in Europe.<br />You can find <a href="http://corporate.onebip.com/onebip-at-phpbenelux-2013/">a recount of what happened there on the Onebip blog</a> (my company, which sponsored my travel).<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://corporate.onebip.com/wp-content/uploads/2013/01/phpbenelux-300x225.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://corporate.onebip.com/wp-content/uploads/2013/01/phpbenelux-300x225.jpg" /></a></div><br /><img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/hGFG87gOtpM" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com2http://www.giorgiosironi.com/2013/02/php-benelux-2013.htmltag:blogger.com,1999:blog-36547168.post-77346703442829908462013-01-27T17:28:00.003+01:002013-01-27T17:28:57.748+01:00Pyramids and cathedrals<blockquote class="tr_bq"><span style="background-color: white; font-family: sans-serif; font-size: 13px; line-height: 19.200000762939453px;">Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves. -- <a href="http://en.wikiquote.org/wiki/Alan_Kay">Alan Kay</a></span><ul style="background-color: white; font-family: sans-serif; font-size: 13px; line-height: 19.200000762939453px; list-style-image: url(data:image/png; margin: 0.3em 0px 0px 1.6em; padding: 0px;"></ul></blockquote><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-g124jyb7Fks/UQVTZHyUdxI/AAAAAAAAA0k/xGQZBMfLWtM/s1600/549868_4678631935616_1798992414_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-g124jyb7Fks/UQVTZHyUdxI/AAAAAAAAA0k/xGQZBMfLWtM/s1600/549868_4678631935616_1798992414_n.jpg" /></a></div><blockquote class="tr_bq"><span style="background-color: white; color: #333333; font-family: Trebuchet, 'Trebuchet MS', Arial, sans-serif; font-size: 13px;">An analogy to these programs of the sixties is a dog house. If you take any random boards, nail, and hammer; pound them together and you've got a structure that will stay up. You don't have to know anything, except how to pound a nail to do that. Now, somebody could come along and look at this dog house and say, Wow! If we could just expand that by a factor of a hundred we could make ourselves a cathedral. It's about three feet high. That would give us something thirty stories high, and that would be really impressive. We could get a lot of people in there. The carpenters would set to work blowing this thing up by a factor of a hundred. Now, we all know, being engineers and scientists, that when you blow something up by a factor of a hundred, its mass goes up by a factor of a million, and its strength, which is mostly due to cross sections of things, only goes up by a factor of ten thousand. When you blow something up [by] a factor of a hundred, it gets by a factor of hundred weaker in its ability, and in fact, what will happen to this dog house; it would just collapse into a pile of rubble. Then there are two choices you can have when that happens. The most popular one is to say, Well, that was what we were trying to do all along. [Laughter] Put more garbage on it, plaster it over with limestone, and say, Yes, we were really trying to do pyramids, not gothic cathedrals. That, in fact accounts for much of the structure of modern operating systems today. [Laughter and applause]</span><br style="background-color: white; color: #333333; font-family: Trebuchet, 'Trebuchet MS', Arial, sans-serif; font-size: 13px;" /><br style="background-color: white; color: #333333; font-family: Trebuchet, 'Trebuchet MS', Arial, sans-serif; font-size: 13px;" /><span style="background-color: white; color: #333333; font-family: Trebuchet, 'Trebuchet MS', Arial, sans-serif; font-size: 13px;">Or, you can come up with a new concept, which the people who started getting interested in complex structures many years ago did. They called it architecture. Literally, the designing and building of successful arches. A non-obvious, a non-linear interaction between simple materials to give you non-obvious synergies, and a fast multiplication of materials. It's quite remarkable to people when I tell them that the amount of material in Chartres cathedral, which is an enormous, physical structure, is less than the amount of material that was put into the Parthenon. The reason is that it's almost all air, and almost all glass. Everything is cunningly organized in a beautiful structure to make the whole have much more integrity than any of its parts. That's the other way you can go, and part of the message of OOP was, that, as complexity starts becoming more and more important, architecture's always going to dominate material [...] -- still <a href="http://blog.moryton.net/2007/12/computer-revolution-hasnt-happened-yet.html">Alan Kay</a></span></blockquote>Let's choose between building pyramids or gothic cathedrals, by choosing to model behavior into piles of lines of code or into the web of messages that objects send to each other.<img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/oY1yZHR6c3M" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com1http://www.giorgiosironi.com/2013/01/pyramids-and-cathedrals.htmltag:blogger.com,1999:blog-36547168.post-88785421457934540062012-10-28T12:54:00.002+01:002012-10-28T12:54:49.360+01:00My thesis: linking social network profilesEach of us has several accounts on multiple social networks, such as Facebook, Twitter and LinkedIn. But there's currently no deterministic way to find the LinkedIn profile of a Facebook user in an automated way: you have to google the full name of that person and verify the search results by hand.<br />So in my thesis I set out to build a solution to this problem based on machine learning (in particular decision trees and support vector machines).<br /><br />Here's the abstract:<br /><br /><blockquote class="tr_bq">Record linkage is a well-known task that attempts to link different representations<br />of the same entity, who happens to be duplicated inside a database; in particu-<br />lar, identity reconciliation is a subfield of record linkage that attempts to connect<br />multiple records belonging to the same person. This work faces the problem in<br />the context of online social networks, with the goal of linking profiles of different<br />online platforms.<br />This work evaluates several machine learning techniques where domain-specific<br />distances are employed (e.g. decision trees and support vector machines). In ad-<br />dition, we evaluate the influence of several post-processing techniques such as<br />breakup of large connected components and of users containing conflicting pro-<br />files.<br />The evaluation has been performed on 2 datasets gathered from Facebook, Twitter<br />and LinkedIn, for a total of 34,000 profiles and 2200 real users having more than<br />one profile in the dataset. Precision and recall are in the range of cross-validated<br />90% depending on the model used, and decision trees are discovered as the most<br />accurate classifier.</blockquote><div><a href="https://www.politesi.polimi.it/handle/10589/64441">The full thesis can be downloaded</a> if you're interested into these sorts of things (namely applying machine learning to data coming from social network APIs).</div><br /><br /><br /><img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/jWILDGqYufI" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com0http://www.giorgiosironi.com/2012/10/my-thesis-linking-of-user-profiles.htmltag:blogger.com,1999:blog-36547168.post-78060988669393269652012-10-14T17:36:00.002+02:002012-10-15T21:04:03.091+02:00A Computer Engineering degree in 5 minutes<div class="separator" style="clear: both; text-align: center;"><a href="http://www.cusmilano.it/sito/images/stories/img/loghi/poli.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://www.cusmilano.it/sito/images/stories/img/loghi/poli.jpg" width="200" /></a></div>As you know, I have recently graduated as a Master of Engineering at Politecnico di Milano. I think each course in the program of Politecnico has some underlying principles which remain with you after the exam has been passed and the most technical things have been forgotten and left for documentation to remember.<br />Thus, I'll try to synthesize the most important concept I took away from each course. This list may be useful to engineers, students of PoliMi in Como and somewhere else, and just to curious programmers wanting to know what I did for 5 years.<br /><h4><b>First year</b></h4>Mostly, the courses of the first year are mandatory and involve basic maths and physics which will serve in the next years.<br /><b>Linear algebra</b>: algebra is a mature way of dealing with multidimensionality, as you generalize numbers and their multiplication or linear combination with vectors and matrices.<br /><b>Analysis 1</b>: an engineer really needs practical math skills, and not mere memorization of proofs.<br /><b>Analysis 2</b>: this course should be named Analysis N as you generalize from the 1 input/output variable of Analysis 1 to N independent/dependent variables.<br /><b>Electrical engineering</b>: engineers build simplified models to work with reality; in practice you use resistance and capacitors and Kirchhoff's laws, not the Maxwell equations. This course could have been focused on hydraulics and be useful as well.<br /><b>Physics 1</b>: Entropy is a nasty thing, and how to find and conserve energy in nature is an issue.<br /><b>Physics 2</b>: Maxwell equations tell you anything you need to know about classical electrodynamics. Preparing for the exam means writing them on a sheet of paper and be able to explain and use them.<br /><b>Computer science 1</b>: C is the minimum common denominator between all languages, and may its pointers and arrays be with you, always.<br /><b>Computer science 2</b>: a process is really a virtual machine provided for you by the operating system, appreciate that.<br /><b>Telecommunication networks</b>: abstraction over abstraction, you can go from varying voltage levels on a wire to transmitting web pages reliably.<br /><h4><b>Second year</b></h4>In the second year, you got to choose some courses, and to do some practical project.<br /><b>Probability calculus</b>: a mathematical model is built starting from sets and relations/functions.<br /><b>Economy</b>: an engineer must know where the money to fund his efforts comes from.<br /><b>Differential equations</b>: meteorologists cannot predict weather for more than a limited amount of time due to divergence from initial conditions.<br /><b>Automation</b>: feedback systems beat feed-forwards ones because they don't need an accurate model in order to work. Agilists, what do you say?<br /><b>Electronics 1</b>: according to classical physics, USB keys and other SSD drives cannot work. Fortunately, USB keys know some quantum mechanics.<br /><b>Operations research</b>: you can buy RAM if you have algorithms that consume too much space, but you can't buy time.<br /><b>Computer science 3</b>: algorithms are <i>really</i> intertwined with the data structures they work on.<br /><b>Software engineering</b>: maintainability is maybe the most important trait of design, and involves also writing diagrams not to avoid coding but to explain your code to other people.<br /><b>Software engineering project</b>: communication between teams is typically the hardest problem in software development.<br /><b>Statistics and measurement</b>: when you read <i>3:36:20 PM</i> on your watch, it's actually a range like <i>3:36:19.5-3:36:20.5</i>; and that interval has a mean and a variance.<br /><h4><b>Third year</b></h4>Now you get to choose more than half the courses, and of course you have to work on a Bachelor's thesis which workload is of a course and a half.<br /><b>Databases</b>: SQL and the relational model are not going to go away soon, and they're really about sets more than tables.<br /><b>Chemistry</b>: the structure of [almost] everything we touch on a daily basis can be explained by protons, neutrons and electrons arranged in different ways. Not philotes, but near enough.<br /><b>EM waves and nuclear physics</b>: waves are cool because you can carry information on their properties, such as frequency, amplitude and phase.<br /><b>Signals</b>: a transfer function goes a long way, and for the engineer everything is linear, time-invariant and Gaussian unless the contrary is proven.<br /><b>Computer installations</b>: you shouldn't really buy servers randomly without doing some math first.<br /><b>Theoretical computer science</b>: computers cannot solve every problem, and do not parse HTML with regular expressions.<br /><b>Knowledge engineering</b>: stochastic algorithms and neural networks work, give them a chance over pure statistical learning.<br /><b>Web technologies</b>: HTTP is the lingua franca you need to speak.<br /><b>Web technologies project</b>: (web) frameworks have a steep learning curve.<br /><b>Logical networks</b>: sequential and combinatorial are two concepts which appear everywhere.<br /><b>Information systems</b>: <s>that was just wasted time</s> having to rework RUP diagrams before changing a single line of code makes you aware of why the Agile manifesto is so popular.<br /><b>Thesis work</b>: when on unfamiliar ground like new frameworks, languages and APIs, Test-Driven Development with a very short Red-Green-Refactor cycle will definitely speed you up.<br /><h4><b>Fourth year</b></h4>This year is full of projects: you're a "graduate" student by now, so you're expected to show originality and autonomy.<br /><b>Advanced computer architectures</b>: we may be stuck with the x86 instruction set, but if you try a RISC architecture optimization can do wonders.<br /><b>Advanced database and web technologies</b>: it's not only SQL, and even universities recognize CouchDB and MongoDB now.<br /><b>Advanced software engineering</b>: there's so much going on in a project other than code. You don't see this on a small scale, and it doesn't mean that you have to write it all down, but diagrams and documentation have their communication purpose.<br /><b>Computer vision</b>:&nbsp;test-driven, object-oriented Matlab is a reality. But&nbsp;math is hard, especially for 3D models, so leverage libraries for complex domains you don't have time to explore by yourself. Oh yeah, and computers can see, but barely.<br /><b>Image processing</b>: testing image-related code is not easy, but regression testing it is.<br />Model identification: estimating the value of a stochastic process isn't just sampling and taking an average.<br /><b>Multimedia information retrieval</b>: Google (and Google Images) work because of math that you must have the courage to study.<br /><b>Pattern analysis and machine intelligence</b>: studying machine learning gives you an edge over all the programmers that don't know what regression is because of their theoretical background.<br /><b>Performance evaluation of computer systems</b>: utilization and queuing networks are concept that apply to servers but to teams as well.<br /><b>Workgroup and workflow systems</b>: you may dream of creating the new Tomb Raider, but 90% of the money is in business software.<br /><h4><b>Fifth year</b></h4>In the last year, you can choose courses from other campuses, and you work on a master's thesis for a third of your time.<br /><b>Philosophy of computer science</b>: ethos is an important part of execution. When in Rome, do as Romans do.<br /><b>Network architecture</b>: one day we will all have fiber in our homes and send phone messages over 4G instead of SMS.<br /><b>Distributed systems</b>: remote procedure call is not a modern way to build a distributed application, it's fundamentally different from running processes in a single addressing space.<br /><b>Game theory</b>: people are rational. Somewhat, if you consider their utility functions.<br /><b>Interactive TV</b>: recommendation systems literally print money.<br /><b>Pervasive systems</b>: the way to go is smaller computers, who use less power and are not even based on a general purpose CPU. <br /><b>Thesis work</b>: scientific work has other priorities with respect to programming; background and validation and are key with respect to coding and design.<br /><br /><img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/chRhhWNTC98" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com5http://www.giorgiosironi.com/2012/10/a-computer-engineering-degree-in-5.htmltag:blogger.com,1999:blog-36547168.post-10077168611433680692012-09-28T17:04:00.001+02:002012-09-28T17:04:44.561+02:00A paper on the philosophy of digital piracy<div class="separator" style="clear: both; text-align: center;"><a href="http://www.capn3m0.org/wp-content/uploads/2012/07/the_pirate_bay_logo.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="http://www.capn3m0.org/wp-content/uploads/2012/07/the_pirate_bay_logo.jpg" width="200" /></a></div>During my last course at Politecnico I wrote a paper on the philosophical argument of novelty of computer technology problems. Plainly speaking: ethical problems from copyright infringements are just a new version of theft or a new conceptual issue?<br />Here is the paper:<br /><a href="http://bit.ly/S62WtB">http://bit.ly/S62WtB</a><br />If philosophy is not your thing, it would be boring to read. But it was a good exercise to write.<img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/i4TlpEBW5HA" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com0http://www.giorgiosironi.com/2012/09/a-paper-on-philosophy-of-digital-piracy.htmltag:blogger.com,1999:blog-36547168.post-700251120199425402012-06-29T15:50:00.000+02:002012-06-29T15:50:05.216+02:00Roundup: the Lean tools series continues<div class="separator" style="clear: both; text-align: center;"><a href="http://ecx.images-amazon.com/images/I/5187M7BB52L._SS500_.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="http://ecx.images-amazon.com/images/I/5187M7BB52L._SS500_.jpg" width="200" /></a></div>Here are my posts about the <a href="http://css.dzone.com/category/tags/lean">Lean tools</a> for software development <a href="http://ecx.images-amazon.com/images/I/5187M7BB52L._SS500_.jpg">proposed by the Poppendiecks</a> and my daily experience with them. I've published also some independent tutorials that may help you in testing legacy code or cook up some functional JavaScript.<br /><br /><a href="http://css.dzone.com/articles/turing-test-0">The Turing test</a> explains which are the most popular interpretations of the famous test for distinguishing between humans and machines.<br /><a href="http://css.dzone.com/articles/lean-tools-pull-systems">Lean tools: Pull systems</a> is about limiting Work-In-Progress with a counter intuitive inversion.<br /><a href="http://css.dzone.com/articles/function-javascript">Functional JavaScript with Underscore.js</a> explains how to work with this library.<br /><a href="http://css.dzone.com/articles/lean-tools-queuing-theory">Lean Tools: Queuing Theory</a> is about a scheduling technique that works on both people and computers.<br /><a href="http://css.dzone.com/articles/record-and-replay-testing">Record and replay for testing of legacy PHP applications</a> lets you record HTTP requests for repeating them in tests later on.<br /><a href="http://css.dzone.com/articles/php-54-examples"></a><a href="http://css.dzone.com/articles/lean-tools-cost-delay">Lean tools: Cost of delay</a> tries to put a price tag on delays in releasing a feature.<br /><a href="http://css.dzone.com/articles/my-take-utility-and-strategic">My take on Utility and Strategic software</a> is a little essay on this dichotomy established by Fowler. In short, you want to work on strategic systems.<br /><a href="http://css.dzone.com/articles/lean-tools-self-determination">Lean Tools: Self-Determination</a> is about eliminating Taylorism and assembly lines from our profession.<br /><a href="http://css.dzone.com/articles/duck-lie">The Duck is a Lie</a> is a critique on duck typing.<br /><a href="http://css.dzone.com/articles/lean-tools-motivation">Lean Tools: Motivation</a> is about what gives a team motivation, and it's not money.<img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/YEF0NJMLXLM" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com0http://www.giorgiosironi.com/2012/06/roundup-lean-tools-series-continues.htmltag:blogger.com,1999:blog-36547168.post-6943027919681797322012-05-27T13:42:00.000+02:002012-05-27T13:42:22.382+02:00Roundup: OOP in PHPHere are the slides for my recent presentation at phpDay 2012, What they didn't tell you about object-oriented programming in PHP.<br /><div class="prezi-player"><style media="screen" type="text/css">.prezi-player { width: 550px; } .prezi-player-links { text-align: center; } </style><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" height="400" id="prezi_ytmecn4nyf6p" name="prezi_ytmecn4nyf6p" width="550"><param name="movie" value="http://prezi.com/bin/preziloader.swf"/><param name="allowfullscreen" value="true"/><param name="allowscriptaccess" value="always"/><param name="bgcolor" value="#ffffff"/><param name="flashvars" value="prezi_id=ytmecn4nyf6p&amp;lock_to_path=0&amp;color=ffffff&amp;autoplay=no&amp;autohide_ctrls=0"/><embed id="preziEmbed_ytmecn4nyf6p" name="preziEmbed_ytmecn4nyf6p" src="http://prezi.com/bin/preziloader.swf" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="550" height="400" bgcolor="#ffffff" flashvars="prezi_id=ytmecn4nyf6p&amp;lock_to_path=0&amp;color=ffffff&amp;autoplay=no&amp;autohide_ctrls=0"></embed></object><br /><div class="prezi-player-links"><a href="http://prezi.com/ytmecn4nyf6p/what-they-didnt-tell-you-about-object-oriented-programming-in-php/" title="What they didn't tell you about object-oriented programming in PHP">What they didn't tell you about object-oriented programming in PHP</a> on <a href="http://prezi.com/">Prezi</a></div></div><br />Here are also the links to the various articles I published in this period on DZone. I'm down to two articles a week for the foreseeable future.<br /><a href="http://css.dzone.com/articles/standard-php-setup">The standard PHP setup</a><br /><a href="http://css.dzone.com/articles/selenium-android">Selenium on Android</a><br /><a href="http://css.dzone.com/articles/hexagonal-architecture">Hexagonal architecture in JavaScript</a><br /><a href="http://css.dzone.com/articles/lean-tools-synchronization">Lean tools: synchronization</a><br /><a href="http://css.dzone.com/articles/why-everyone-talking-about">Why everyone is talking about APIs</a><br /><a href="http://css.dzone.com/articles/lean-tools-set-based">Lean tools: Set-Based Development</a><br /><a href="http://css.dzone.com/articles/testing-php-scripts">Testing PHP scripts</a><br /><a href="http://css.dzone.com/articles/software-metaphors">Software Metaphors</a><br /><a href="http://css.dzone.com/articles/mongodb-and-java">MongoDB and Java</a><br /><a href="http://css.dzone.com/articles/lean-tools-options-thinking">Lean tools: Options thinking</a><br /><a href="http://css.dzone.com/articles/what-global-state">What is global state?</a><br /><a href="http://css.dzone.com/articles/lean-tools-last-responsible">Lean Tools: the Last Responsible Moment</a><br /><a href="http://css.dzone.com/articles/php-54-examples">PHP 5.4 by examples</a><br /><a href="http://css.dzone.com/articles/crash-course-mongodb-console">A crash course for the MongoDB console</a><br /><a href="http://css.dzone.com/articles/surgery-metaphor">The surgery metaphor</a><br /><a href="http://css.dzone.com/articles/lean-tools-making-decisions">Lean tools: Making decisions</a><img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/WNo2GeMTux0" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com2http://www.giorgiosironi.com/2012/05/roundup-oop-in-php.htmltag:blogger.com,1999:blog-36547168.post-70706692979716956492012-04-15T13:44:00.001+02:002012-04-15T13:44:58.629+02:00Biweekly roundup: Selenium and AndroidAt PHP Goes Mobile on Friday I held a short talk about using Selenium 2 (with the WebDriver API) for driving an android browser, either on a real device or an emulator. Here are the slides (only the title is in Italian).<br /><div class="prezi-player"><style media="screen" type="text/css">.prezi-player { width: 550px; } .prezi-player-links { text-align: center; } </style><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" height="400" id="prezi_f8r0_qo8agxa" name="prezi_f8r0_qo8agxa" width="550"><param name="movie" value="http://prezi.com/bin/preziloader.swf"/><param name="allowfullscreen" value="true"/><param name="allowscriptaccess" value="always"/><param name="bgcolor" value="#ffffff"/><param name="flashvars" value="prezi_id=f8r0_qo8agxa&amp;lock_to_path=0&amp;color=ffffff&amp;autoplay=no&amp;autohide_ctrls=0"/><embed id="preziEmbed_f8r0_qo8agxa" name="preziEmbed_f8r0_qo8agxa" src="http://prezi.com/bin/preziloader.swf" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="550" height="400" bgcolor="#ffffff" flashvars="prezi_id=f8r0_qo8agxa&amp;lock_to_path=0&amp;color=ffffff&amp;autoplay=no&amp;autohide_ctrls=0"></embed></object><br /><div class="prezi-player-links"><a href="http://prezi.com/f8r0_qo8agxa/scrivere-test-in-php-che-usano-il-browser-android/" title="Scrivere test in PHP che usano il browser Android">Scrivere test in PHP che usano il browser Android</a> on <a href="http://prezi.com/">Prezi</a></div></div><br />Here are also my articles published in the last two weeks on DZone.<br /><a href="http://css.dzone.com/articles/finding-wiring-bugs">Finding wiring bugs</a> is possible not only with end-to-end tests, but also by analyzing the wiring itself.<br /><a href="http://css.dzone.com/articles/lean-tools-feedback">Lean tools: Feedback</a>&nbsp;describes feedback as not only one of the basis of the Agile manifesto but also of Lean.<br /><a href="http://css.dzone.com/articles/commodities-it-world">Commodities in the IT world</a>&nbsp;analyzes today's trends of commoditized technologies and value-adding ones, comparing open and closed platforms (Amazon, Apple...).<br /><a href="http://css.dzone.com/articles/2-years-vim-and-php-distilled">2 years of Vim and PHP distilled</a>&nbsp;contains the most important take-aways from my 2-year experience with this editor.<br /><a href="http://css.dzone.com/articles/page-object-pattern">The Page Object pattern</a>&nbsp;helps removing duplication and introducing abstraction into a test suite using browser-based tests.<br /><a href="http://css.dzone.com/articles/software-versions-necessary">Software versions, the necessary evil</a>&nbsp;contains some thoughts on versions and necessity for software and libraries upgrade.<br /><a href="http://css.dzone.com/articles/lean-tools-iterations">Lean tools: Iterations</a>&nbsp;describes a common application of feedback.<br /><a href="http://css.dzone.com/articles/whats-name">What's in a name?</a> That which we call a rose / by any other name would smell as sweet. Naming is commonly underrated in software engineering.<img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/7fNo0bc_1Zw" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com4http://www.giorgiosironi.com/2012/04/biweekly-roundup-selenium-and-android.htmltag:blogger.com,1999:blog-36547168.post-31902325022379865742012-04-01T12:54:00.002+02:002012-04-01T12:54:36.484+02:00Weekly roundup: announcing a new startup<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-gV-yHvyLycE/T3gwsO9bPGI/AAAAAAAAAwo/eo_GwtfWyls/s1600/vader2.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="214" src="http://2.bp.blogspot.com/-gV-yHvyLycE/T3gwsO9bPGI/AAAAAAAAAwo/eo_GwtfWyls/s320/vader2.jpg" width="320" /></a></div>Have you ever read a blog post, Wikipedia or TVTropes article and get spoiled about how Darth Vader is actually Luke's father? (Sorry)<br />Even with streaming and a network accessible from all over the world, watching movies and TV series at our own pace is increasingly difficult as even the most <a href="http://tvtropes.org/pmwiki/pmwiki.php/Main/Spoiler">innocent-looking web pages</a> can contain news about Bruce Willis's death, about how that name <a href="http://tvtropes.org/pmwiki/pmwiki.php/Main/ItWasHisSled">was his sled</a>&nbsp;and that Harvey Dent becomes Two-Face.<br />My new startup, <b>SpoilerAlert SRL</b>, will produce browser extensions that read the text embedded in HTML pages and cut away possible spoilers or blank the lines containing them. I'm sure many people will pay for this service!<br />Possible follow-ups to the initial service are filtering spoilers also from YouTube videos (not showing clips from too-new Doctor Who episodes) and allowing the user to specify an in-universe chronological point like <i>Already watched Episode V</i> or<i>&nbsp;Already watched Victory of the Daleks</i>; in the latter case only revelations from newer episodes of the series will be filtered.<br />How we will do this is an highly-guarded patent-pending technology for parsing natural language and store web pages in the Time Vortex. If you want to&nbsp;<a href="http://en.wikipedia.org/wiki/April_Fools'_Day">get an invitation for the service...</a><br /><br />P.S. These are my articles published this week on DZone.<br /><a href="http://css.dzone.com/articles/including-php-libraries">Including PHP libraries via Composer</a><br /><a href="http://css.dzone.com/articles/bullets-legacy-code">Bullets for legacy code</a><br /><a href="http://css.dzone.com/articles/return-vim">The return of Vim</a><br /><a href="http://css.dzone.com/articles/lean-tools-value-stream">Lean Tools: Value Stream Mapping</a><img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/zAx2K6zRq9g" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com0http://www.giorgiosironi.com/2012/04/weekly-roundup-announcing-new-startup.htmltag:blogger.com,1999:blog-36547168.post-53471037870827507842012-03-25T12:20:00.002+02:002012-03-25T12:20:44.762+02:00Weekly roundup: basic testingHere are my "slides" for the (Italian) talk I held at PHP.TO.START this week. It has been nice to meet so passionate colleagues in Turin, not only from the PHP field but also in the startup arena. If I can't find you and you see this, comment here or ping me on Twitter so that I can follow you.<br />The talk's topic is the evolution of testing in PHP - from manual to automatic and from a scope oriented to correctness to an aid in design.<br /><div class="prezi-player"><style media="screen" type="text/css">.prezi-player { width: 550px; } .prezi-player-links { text-align: center; } </style><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" height="400" id="prezi_rj0u48-v2eib" name="prezi_rj0u48-v2eib" width="550"><param name="movie" value="http://prezi.com/bin/preziloader.swf"/><param name="allowfullscreen" value="true"/><param name="allowscriptaccess" value="always"/><param name="bgcolor" value="#ffffff"/><param name="flashvars" value="prezi_id=rj0u48-v2eib&amp;lock_to_path=0&amp;color=ffffff&amp;autoplay=no&amp;autohide_ctrls=0"/><embed id="preziEmbed_rj0u48-v2eib" name="preziEmbed_rj0u48-v2eib" src="http://prezi.com/bin/preziloader.swf" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="550" height="400" bgcolor="#ffffff" flashvars="prezi_id=rj0u48-v2eib&amp;lock_to_path=0&amp;color=ffffff&amp;autoplay=no&amp;autohide_ctrls=0"></embed></object><br /><div class="prezi-player-links"><a href="http://prezi.com/rj0u48-v2eib/test-automatici-in-php/" title="Test automatici in PHP">Test automatici in PHP</a> on <a href="http://prezi.com/">Prezi</a></div></div><br />Here are my original articles published this week on DZone.<br /><a href="http://css.dzone.com/articles/lean-tools-seeing-waste">Lean Tools: Seeing Waste</a>&nbsp;is the first of a series of articles on Lean tools in their software development version (Lean is a movement that goes beyond the software field, of course.)<br /><a href="http://css.dzone.com/articles/php-objects-mongodb-doctrine">PHP objects in MongoDB with Doctrine</a>&nbsp;contains code for working with the Doctrine Object-Document Mapper and for integrating it with the ORM.<br /><a href="http://css.dzone.com/articles/travisci-examples">TravisCI Intro and PHP Example</a>&nbsp;shows you how to setup an open source project to build itself on Travis CI (for free).<br /><a href="http://css.dzone.com/articles/sometimes-python-magic">Sometimes Python is magic</a>&nbsp;because of its __methods.<img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/HqKZ5WEvjzE" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com0http://www.giorgiosironi.com/2012/03/weekly-roundup-basic-testing.htmltag:blogger.com,1999:blog-36547168.post-41481463727514985992012-03-18T16:36:00.000+01:002012-03-18T16:36:04.757+01:00Biweekly roundup: PHP.TO.START sold out<div class="separator" style="clear: both; text-align: center;"><a href="http://www.phptostart.it/" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://www.phptostart.it/images/logo.gif.pagespeed.ce.G_pXF_z0Id.gif" /></a></div>Apparently the <a href="http://www.phptostart.it/">Turin event</a> taking place this week is sold out. If you will be present, feel free to come up to me for geek chatting or OO/PHP/testing questions (which is the topic I will talk about.)<br /><br />In the last two weeks I have published several new articles on DZone, also about other pieces of the web:<br /><a href="http://css.dzone.com/articles/zend-framework-2-tryout">A Zend Framework 2 tryout</a>&nbsp;is my review of the Zend Framework 2 beta releases, along with a list of what you don't have to learn again for now.<br /><a href="http://css.dzone.com/articles/asynchronous-and-negative">Asynchronous and negative testing</a>&nbsp;is about testing that something does <i>not</i> happen in a running system.<br /><a href="http://css.dzone.com/articles/all-mouse-events-javascript">All the mouse events in JavaScript</a>&nbsp;is a collection of all and only the DOM events that are generated by a mouse, divided into classic and HTML5 ones.<br /><a href="http://css.dzone.com/articles/everything-you-need-know-about">Everything you need to know about Python exceptions</a>&nbsp;is about the <i>try..except..else..finally</i> construct and the exception hierarchy of Python.<br /><a href="http://css.dzone.com/articles/all-about-jms-messages">All about JMS messages</a>&nbsp;topic's is a must-know for working with ActiveMQ and similar message-based middleware - I know <i>middleware</i> sounds like a buzzword, but I assure you it has a specific meaning.<br /><a href="http://css.dzone.com/articles/css-bits-mouse-cursor">CSS Bits: The Mouse Cursor</a>&nbsp;is about customizing the mouse cursor appearance (interestingly, without any JavaScript code).<br /><a href="http://css.dzone.com/articles/bootstrap-rapid-development">Bootstrap: rapid development and the complexity of a framework</a>&nbsp;is my review of Bootstrap, a front end framework shipping some standard CSS solutions and UI widgets.<br /><a href="http://css.dzone.com/articles/test-driven-emergent-design-vs">Test-Driven Emergent Design vs. Analysis</a>&nbsp;is an essay about the dichotomy between writing code with the support of tests and exploring new classes and objects via other fluffy means like paper and boards. You know, that old thing called <i>thinking</i>.<img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/t6yyVg_hRdk" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com2http://www.giorgiosironi.com/2012/03/biweekly-roundup-phptostart-sold-out.htmltag:blogger.com,1999:blog-36547168.post-64336848111343919802012-03-04T14:42:00.001+01:002012-03-04T14:51:14.829+01:00Weekly roundup: PHP Goes Mobile rescheduled<div class="separator" style="clear: both; text-align: center;"><a href="http://mobilephp.grusp.org/" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://3.bp.blogspot.com/-9Zh4iIS1s1s/TyU6gnrprpI/AAAAAAAAAsI/M74xsHD1Q_U/s320/phpgoesmobile.png" /></a></div>PHP Goes Mobile<a href="http://mobilephp.grusp.org/"> has been rescheduled</a> for April 13th in Milan; I will present my short talk on PHPUnit_Selenium usage on an Android device. See you there!<br /><br />Here are my articles published this week on DZone.<br /><a href="http://css.dzone.com/articles/audio-html-5-state-art">Audio in HTML 5: state of the art</a>&nbsp;explains how to use &lt;audio&gt; and Audio JavaScript objects to play music or sounds in a web page.<br /><a href="http://css.dzone.com/articles/tdd-python-5-minutes">TDD in Python in 5 minutes</a>&nbsp;is a dive into the unittest Python module.<br /><a href="http://css.dzone.com/articles/running-javascript-inside-php">Running JavaScript inside PHP code</a>&nbsp;- yes, you read that right. Highly experimental.<br /><a href="http://css.dzone.com/articles/gradient-descent-octave">Gradient descent in Octave</a>&nbsp;is a walkthrough in a staple machine learning technique.<img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/9TkWn_I8bMA" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com0http://www.giorgiosironi.com/2012/03/weekly-roundup-php-goes-mobile.htmltag:blogger.com,1999:blog-36547168.post-54754552351620152802012-02-26T13:29:00.001+01:002012-02-26T13:29:34.734+01:00Biweekly roundup: PHP.TO.START<div class="separator" style="clear: both; text-align: center;"><a href="http://www.phptostart.it/" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://www.phptostart.it/images/logo.gif.pagespeed.ce.G_pXF_z0Id.gif" /></a></div>The <a href="http://torino.grusp.org/">Turin PHP User Group</a> has been growing in the last months and have now organized a <a href="http://www.phptostart.it/">free one-day conference</a> on March 21st. I will be a speaker with a basic talk on automated testing of PHP applications.<div>I'm getting to know better the diffusion of PHP in Milan and Turin - cities where historically there was not much attention for this ecosystem. The message is clear: investing on PHP as one of the platforms you specialize in your career is not a dead end.<br /><br />Here are my articles published in the last two weeks on DZone. The Practical PHP Refactoring series has ended, but I will always have space for PHP related articles.<br /><a href="http://css.dzone.com/articles/practical-php-refactoring-49">Practical PHP Refactoring: Separate Domain from Presentation</a>&nbsp;is one of the most necessary large-scale refactorings to perform on legacy code.<br /><a href="http://css.dzone.com/articles/bottle-lightweight-python">Bottle: a lightweight Python framework</a>&nbsp;explains the first steps for developing a Python web application with Bottle.<br /><a href="http://css.dzone.com/articles/practical-php-refactoring-50">Practical PHP Refactoring: Extract Hierarchy</a>&nbsp;explains how to segregate the responsibilities of a God class.<br /><a href="http://css.dzone.com/articles/spam-filtering-naive-bayes">Spam filtering with a Naive Bayes Classifier in R</a>&nbsp;is a full-featured example of R usage for data mining.<br /><a href="http://css.dzone.com/articles/erlangs-actor-model">Erlang's actor model</a>&nbsp;explains one of the ways this language blows your mind.<br /><a href="http://css.dzone.com/articles/7-habits-highly-effective">The 7 habits of highly effective developers</a>&nbsp;is an essay on a fluffy topic - which personal habits are beneficial to our job, solving problems?<br /><a href="http://css.dzone.com/articles/writing-clean-code-php-54">Writing clean code in PHP 5.4</a>&nbsp;is a photograph of the new features of PHP and how they may be abused to write spaghetti code.</div><div><a href="http://css.dzone.com/articles/our-experience-domain-events">Our experience with Domain Events</a>&nbsp;is a summary of how we have come to use Events as an additional Domain Model pattern in DDD.</div><img src="http://feeds.feedburner.com/~r/InvisibleToTheEye/~4/2zPIndO6s38" height="1" width="1" alt=""/>Giorgio Sironihttps://plus.google.com/111746708330132898280noreply@blogger.com3http://www.giorgiosironi.com/2012/02/biweekly-roundup-phptostart.html