Don't blindly apply software patterns

Don’t blindly apply software patterns

I went for a run today and I was catching up with some podcast episodes today and I would like to share my comments to the great episode about sagas & process managers published by Mariusz Gil in the Better Software Design.

Mariusz has been talking with Kuba Pilimon. This was the third episode when these devs have discussed how to design software using Domain Driven Design techniques & design patterns. (The podcast is in Polish but some episodes - like the inverview with Alberto Brandolini are recorded in English).

I’ve listened to this podcast and the overall discussion is very interesting but I have some remarks:

Patterns are not the silver bullet

Mariusz & Kuba have dicsussed the saga pattern based on the example of cinema seats reservations. The model is simple - each Seat is an aggregate and to book 4 seats you need to have a saga that will ensure that all 4 reservations are processed or all of them will be revoked by compensating actions.

The example was as follows (pardon the pseudocode):

# ruby flavoured pseudocode here (time axis goes down)

    Process A             Process B
book_seat('A-1')      book_seat('A-3')
book_seat('A-2')      book_seat('A-4')
book_seat('A-3')      book_seat('A-5')
book_seat('A-4')
#... here  process A starts its compensating actions when booking of seat A-3
#    or A-4 has failed (booked already by process B)

This looks so simple - we have 2 processes (sagas). Each of them tries to book some seats. The first wins. The other one runs its compensating action to release already booked seats.

But the reality might not be that simple.

Having that in mind we could imagine situation like this:

# ruby flavoured pseudocode here (time axis goes down)

    Process A             Process B
book_seat('A-4')      book_seat('A-3')
book_seat('A-2')      book_seat('A-4')
book_seat('A-3')      book_seat('A-5')
book_seat('A-1')

What will be the result? Process A could not complete the saga - because seat A-3 is already booked. Process B could not complete its saga because seat A-4 is already booked. Both are starting its compensating actions and release all bookings. With some bad luck we could end up with seats that will not be sold even when there was a huge demand - translating to business terms: diappointed customers and lost revenue.

Another example I would like to comment is the most common example of saga pattern usage. Booking a plane, a hotel and a car and releasing the bookings when one of these has failed.

Don’t blindly apply software patterns

Mariusz & Kuba have discussed several scenarios how this could be extended. But what I’ve missed here, and what is always an issue for me when I read/hear this example is:

When you book plane, hotel & car and the car is not available what are your expectations? I could be wrong - but I would expect that my plane & hotel is booked and then the system will ask me what to do with missing car reservation. Definitelly I would not like the application to cancel my plane & hotel bookings when the car is not available!

What’s the solution?

Just ask your business/domain expert. They probably handle this kind of situations every day, business as usual. Don’t blindly apply software design patterns. Talk to people. Solve real world problems.

Struggling to apply DDD concepts to your Rails app?

For a few years we’ve been studying Domain-Driven Design and applying its techniques in our projects. In this book we describe techniques that you can use in new and old Rails apps to achieve better architecture. They were useful to us and we are sure they are going to be useful for you.

Click here to read more!

Domain-Driven Rails

There is more... check out other books published by us

You might also like