emanuele delbono
ema.blog

Emanuele DelBono

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

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

  • ASP.NET WebApi succinctly

    Months ago, while digging inside the ASP.NET WebAPI I collected a lot of material and I decided to write a small book about the topics. I contacted Syncfusion beacause I really like their series “Succinctly”: small books that go straight to the main topic without much introductions or ceremonies. Few days ago my work have seen the light and you can grab it for free at this address: http://www.syncfusion.com/resources/techportal/ebooks/webapi There are a couple of persons that I need to thanks: Raffaele Rialdi help me a lot in understanting how the model binding works internally (and I can gurantee that is not easy as I expected). Second I have to thanks Ugo Lattanzi that helped me with some oddities of the routing system. Writing a book always was on my todo list and even if it’s not a big book I’m very happy that it is publicly available.

  • Functional programming

    In the last year Functional Programming is the topic that devs are talking about. Many functional languages are becoming popular (Scala, F#, Clojure, Elixir and someone is starting to say that functional programming will be the next big thing. As usual as a curious guy I started to study the fundamentals and theories behind functional programming and I must admit that most of the time we are using the wrong language to resolve our daily problems.

    Object Oriented Languages is useful when you have a state to persist (as in a GUI application) but in other cases you don’t need it. Consider a web app. The server side could be just a series of functions that respond to the HTTP commands that arrives from the clients.

    Functional programming is about writing programs that are a built as a set of functions that calls each others. Well actually this definition doesn’t made justice, functions must be pure and data must be immutable so consider this is a rough description. :-)

    The main points are that you cannot preserve the state and that the functions cannot modify arguments. This means that you can call the function whatever times you want and the function will return always the same result without affecting the state.

    This also mean that the execution model is simplyfied and the computer (the compiler/runner) have just to substitute the functions with their result to execute the program. So the implementation of the compilers and interpreters is quite easier.

    With object oriented programming the evaluation is much more complicated, since the executor must take care of the state to be able to execute the program. In second instance writing imperatives programs is more difficult since often you must take care of the order of the assignments.

    Consider this simple example of a program that calculates the factorial of a given number:

    defmodule ImperativeFactorial do
      def factorial(n) do
        iter(n, 1, 1)
      end
    
      def iter(n, counter, product) do
        if counter > n do
          product
        else
          product = counter * product
          counter = counter + 1
          iter(n, counter, product)
        end
      end
    end  
    

    This implementation is very imperative and use two variables to store the state (product, counter) between iterations. It works but if we swap the order of the two assignment the result will be wrong:

    counter = counter + 1 
    product = counter * product
    

    Functional programming avoid these flaws because it doesn’t store state. A possible implementation in Elixir is:

    defmodule Factorial do
      def iter(0), do: 1
      def iter(n) when n > 0 do
        n * iter(n-1)
      end
    end
    

    Apart the fact that is a lot simpler and short it doesn’t have the pitfall of the previous implementation.