emanuele delbono
ema.blog

Emanuele DelBono

  • 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

  • Ruby Loves DDD (Part 5)

    Going back to the handler. We saw in a previous post how the repository recreates the aggregate state re-executing the events. Now that we have the aggregate reference we can call methods on it:

    class AddToBasketHandler
      def execute(add_to_basket_command)
        #repository creates the basket reloading all the events
        basket = @repository.get_basket(add_to_basket_command.basket_id)
        # now we can operate on basket
        basket.add_item (add_to_basket_command.article_id) 
        basket.commit
      end
      # more code here...
    end
    

    In the above example we are adding a new item to the basket using the method add_item. Now we will see how the add_item is implemented in the basket object:

    def add_item (item)
      raise_event :item_added, item
    end
    

    The implementation is quite curious, all that it does is raising an event calling the method raise_event passing a symbol that specify the event name and the item to add.

    The raise_event method is provided by the AggregateRootHelper a module included in the Basket class:

    def raise_event(event_name, *args)
      uncommited_events << {name: event_name, args: args}
      send "on_#{event_name}", *args
    end
    

    It collect the event information inside an array of "uncommited events" and then dynamically call a method called on_item_added passing the event arguments.

    def on_item_added item
      get_item(item).try(:increase_quantity) || @items << BasketItem.new(item)      
    end
    

    The on_item_added event on basket class is where the job is really done: it increase the quantity of the item if it is already present in the basket otherwise it creates a new item.

    You may ask why should be so complecated add an item the the basket?

    The raise_event is necessary because the storage is event based not status based, so raising the event is important to track the fact that a new item is being added and the uncommitted_events array in the module is there to store this event (and to persist them later). The event raised could also be useful if we wan to inform other aggregates of the fact the a new item is added: for example a warehouse aggregate could receive the message to manage the available quantity.

  • Ruby Loves DDD (Part 4)

    In the last post we saw how it is implemented a command handler and how it interacts with the aggregate.

    The first task that we did was to get the aggregate from the event store. Remember that in an EventSource architecture that status of the objects (the aggregates) must be rebuilt executing every event that the object had received from its beginning. This means that the repository load a series of events (given the aggreate id) an apply all the events to the aggregate root to obtain the current state:

    # somewhere we load the evetns from the store and we get something like this
      basket_events = [
        {:aggregate_id => 1, :name => :item_added, :args => 2  },
        {:aggregate_id => 1, :name => :item_added, :args => 3  },
        {:aggregate_id => 1, :name => :item_removed, :args => 2  },
        {:aggregate_id => 1, :name => :item_added, :args => 4  },
      ]
    
    def get_basket (basket_id)     
        basket = Basket.new
        basket.apply_events basket_events
        basket
    end
    
    So, given a list of events (basket_events) the repository simply create a new instance of the Basket aggregate and apply on it all the events using the apply_events method.
    What we obtain is a basket with 2 items (ids are 3 and 4) that is the current state of the basket.
    
  • New website

    Today we launched our new company web site. You can view it here: http://codiceplastico.com. We are very happy to show the world our new image and to spread our new message #codeforjustice. We are tired to view bad programs, messy codebases, complex code and we created a movement of wise developers that strive for better code. We love beauty, we love high performance applications, we love well designed code and with our new web site we want to spread this message. Join us on twitter with the hashtag #codeforjustice.

    Gummy industries helped us a lot with their ideas and with the implementation, they are a group of smart crazy guys @bia_hvid, @betone, @pietro_colella, @giorgiomininno, @michelebertoli and @ilgadaldi.

    You will know more about our job in the next days....