emanuele delbono
ema.blog

Emanuele DelBono

  • On learning TDD

    Even if Test Driven Development is an old topic and even if today almost everybody should have learned the benefits of TDD I still do a lot of mentoring on the topic and some people ask me if I have some examples of code written on TDD. Well, my Github account is full code written in TDD, the Kata repository is completely written in TDD but you can’t learn TDD looking at the final result, you learn TDD watching the process that goes to the result.

    It’s like learning Origami. Do you think you can learn how to do a swam just looking a final result?

    TDD is a process and the result come after many iterations made of refactored code, deleted code, tests that are removed and is very difficult to understand why we arrived at that point just looking at the result.

    For example one of my usual first test is a test on a constructor that usually I delete after adding a couple of tests since it became useless and looking at the final result you miss this iteration.

    So what are the best way to learn it? On vimeo and youtube there are lots of kata in different languages, looking at them is a good exercise to learn the basic of the process. Pair with other developers is another way to improve you design skills and to practice TDD. In any case I’m available for remote pairing too! :-)

  • Projects structure

    Frameworks like ASP.NET MVC, Rails & C. impose you a strict folder structure using a "topology approach". This means that files of same types are in the same folder. So you end up with a Controllers folder that contains tens of files that are uncorrelated since ControllerA doesn't have anything to do with ControllerB. Even worse the correlated files, for example the ModelA, are in a completely different folder mixed with other tens of uncorrelated files. Topology organization is the most used, I saw folders named Enums, Interfaces and Constants and it was very very difficult find the needed things.

    Starting from one of the last project I tried a completely different approach, I'm using a functional organization creating a folder for every module of my application putting in each folder the complete structure (Controllers, Models, Views, etc).

    ContractModule

    • Controllers
    • Views
    • Models
    • Others...

    CallCenterModule

    • Controllers
    • Views
    • Models
    • Others...

    Doing this way I obtain a modular application and each folder is actually a micro-application that contains all that it needs to run and to be maintained. It's easier to find the needed files and eventually move components out of the main project. Usually there is also a "Common folder" that contains the cross-module assets (extension methods, directives in case of angularjs, global filters and so on)

  • About TDD (IMHO)

    In these days everybody talks about TDD due to the post of DHH titled TDD is Dead and the various hangouts with Fowler and Beck. I’m a proponent of TDD, I teach TDD and I practice it for 5 years even if I’m not a fanatic and I don’t do TDD all the time. But I like it, and I gain value from applying TDD in my projects. Why?

    • With TDD I can broke up my story in small tasks and every time I add a test and it became green I’m moving towards the final implementation. One test is equivalent to a small functionality.

    • TDD force me to deeply think at what the customer wants. If I’m not sure what the customer needs I can’t even write a test so I’m forced to ask more informations that I will use to write the tests and then the implementation.

    • Using TDD I’m indirectly creating a test suite that I can run every time I need feedback on the status of my codebase.

    • TDD let you design your classes in a simpler way. Since the tests are naturally simple, the tested code is by default simple too.

    • TDD let me think at my code from the user perspective, this means that the first things that I do is to design the interface of my method: I define the name, the return type and the parameters without caring at the implementation. This results in a cleaner interface.

    • TDD let you do extreme refactoring without worries about breaking the functionalities. Can you really refactor your code without the tests?

    By looking at the list above you can see that TDD is more about design that about testing, the tests are a welcome side effects and TDD really helps you in design orthogonal classes that respect the OOP principles.

    So why DHH said that TDD is dead? There are cases in which TDD doesn’t fit and big frameworks like Rails is one of those situations. Doing TDD on a Ruby on Rails application (or ASP.NET MVC) is useless, the design of the controllers is already defined by the framework itself and TDD doesn’t add anything, so in this case you can add your tests later. Other cases in which TDD doesn’t work, at least for me, is when I have to learn how to use a new library or a new programming language. In these cases using TDD to experiment make the learning process more difficult and complicated so I prefer to try the new stuff without other ballasts that slow me down.

    So, I will continue to do TDD when possible since until now I get lot of value from this practice and the 6 points above are for me very valuable.

  • Software principles

    I have more than ten years of experience as a software developer, don’t know if I have to be happy or to be sad for the time that pass. During these years I saw lot of technologies, frameworks, libraries passing, some of them are still here but most of them are dead. As a young dev I was super excited to have the opportunity to try some of them, I remember the excitement when a new version of the library xyz came out (in alpha edition) with the promise to solve all the problems (that probably I even didn’t have). But as I said most of them are passed by and today we look at them with a sort of “it seemed a good idea, but it was wrong”.

    So what remains of them?

    The principles. The principles are still here and every pattern even if it was born in the eighties it is still used today and almost certainly we will use them in the future.

    Thats why the developers should spend more time on learning the principles than on learning how to use a framework, because in every framework the principles remains valid and good software is built on good principles.

    So it's time to go back to SOLID, KISS, DRY, YAGNI and so on....

  • Coding Conventions

    In CodicePlastico we take the code readability very seriously and during last months we are trying to change the way we write code to made it more readable and performant.

    Martin Fowler In his book about refactoring write this:

    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand."

    Everybody agree on that but, in my opinion, we must define better which kind of human should be able to read the code. Often we write code so that even our customers will be able to read it, does it make sense? Do your customer really read your code? In our opinion code is written for developers that knows the syntax of the language.

    Wikipedia defines readability as:

    "Readability is the ease in which text can be read and understood. Various factors to measure readability have been used, such as "speed of perception," "perceptibility at a distance," "perceptibility in peripheral vision," "visibility," "the reflex blink technique," "rate of work" (e.g., speed of reading), "eye movements," and "fatigue in reading." (wikipedia)

    So readability is also a matter of how much time we need to read code. Consider this line of C# code:

    _wrostExamEvaluatorService.CheckPercentageForAnyActiveGroupLevel(allActiveExamList, _mainGroupServiceController.GetAllRangeForCurrentGroup(_currentUserId, groupThatShouldBeExcluded));
    

    Do you consider it readable? In some sense yes, but it needs too much time to be read because is too long.

    On the opposite side there are languages like J (a dialect of APL) that are more concise and let you write complex algorithm with just a bunch of characters:

    quicksort=: (($:@(<#[), (=#[), $:@(>#[)) ({~ ?@#)) ^: (1<#)
    

    Is that readable or not? Most probably not, but once you know the syntax it became more readable than other languages with cycles and ifs, and even more better than the algorithm explained in plain english.

    So, during our experiments, we have decided to try to use only a single letter for the identifiers and for our class names, methods and variables, so that the previous C# code written above will became:

    e.c(l,s.g(u,x));
    

    Our experiments demonstrate that developers learn the convention very easily and we don't even need a dictionary, even if we put a brief dictionary on top of our files for newcomers developers.

    Using this new methodology we have reduced the size of our programs, from megabytes to only some kilobytes and the performance, both at compile time and runtime (the compiler parse small files and it's faster).

    We are planning more articles on this topic, so stay tuned.