emanuele delbono
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

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:

```ruby

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.