emanuele delbono
ema.blog

Emanuele DelBono

  • 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.

  • Ruby Loves DDD (Part 6)

    We are almost at the end of our tour. In the last post we analysed what happens when a command is executed, we learnt that the events are collected in a collection of "uncommitted_events" inside the aggregate. Now we will give a look at what happen when these uncommitted events will be...committed. Let’s once more the code inside the handler:

    def execute(add_to_basket_command)
      basket = @repository.get_basket(add_to_basket_command.basket_id)
      article = @repository.get_article(add_to_basket_command.article_id)
      basket.add_item (article)
      basket.commit    
    end
    

    The interesting part for today is the call to commit. Inside that method, implemented in the AggregateRootHelper, there is this piece of code:

    def commit
      while event = uncommited_events.shift
        send_event event
        store_event event
      end
    end
    

    The code is very simple, it enumerates all the events and send them to the eventually subscribed objects (we will came back on this) and store the event in the database (or whatever will be). Since everything is already done, the task of commit is to store the events in the appropriate storage. The storage is an append-only list of events that are marked with the aggregate id and it’s the same list that we used to reload the aggregate http://ema.codiceplastico.com/2013/12/26/ruby-loves-ddd-part-4.html