2010 m. liepos 17 d., šeštadienis

DDD - too large Agregate root

Last week I ran into problem where my aggregate root had too many child entities, way too many. My aggregate root snapshot was about 20 MB and that of course gave me a sign that it is wrong.

Model was rather simple one. I had to create a domain model for voucher system. Every deal that our company creates would need about 100k vouchers. Every deal has vouchers that provides different gifts to customers. Those deals are created pretty often, so we are talking about millions of vouchers.

Now voucher was identified as entity because it has behaviours. And as an aggregate for them I have presented Stock entity. It holded references to all vouchers and those were accessible through it. Also it was responsible for generating vouchers and exporting them. I was using a rule that there always should be a higher 'thing' for my entities and that thing should know what entities exists out there. It's like for licenses we have stock, for invoices ledger and so on.
Now why it is wrong ? (Well I think it is wrong)

First of all in this way I am transferring repository responsibility to other object - stock, ledger etc. I am creating repository that holds all data in-memory while I do not need it. What I really need is just another domain service.
So, let me explain how I have re-modeled my domain here.

Stock aggregate root remains but voucher becomes an aggregate root. I do present new aggregate root - VoucherGenerator that has knowledge about voucher code generation strategies. And to solve actual problem I add new services like GenerateVouchersService, VoucherLookupService. Instead of having behaviour on stock 'GenerateVouchers' i move this to Generator AR and then use this in service GenerateVouchersService to actually create new vouchers and add those to repository.
In this was my repository does what it suppose to do - acts as in-memory domain objects collection and my domain entity becomes free of millions child entities. Of course it still has a map of voucher code - UUID in my stock aggregate and I use it to get voucher UUID that later is used to get entity from repository.

Of course Stock AR still will have lot of data in it, but what we can do is introduce 'ClearOldVouchers' behaviour. Or remove voucher once it was used. And if at some point later I will have to restore my entities, because of event sourcing I am still able to do that.

So as you see, in this way we have solved large-aggregate-root problem and at the moment it seems to be the best solution for me.

Any comments ? Have you any other solution ?

2010 m. kovo 6 d., šeštadienis

Applying Scrum - Sprint Planning - Mind Map

Last Thursday our team have finished 3rd sprint. Despite some issues, we have achieved our goal and on Monday we will have our demo.

This evening I was sitting here and was analyzing how we were progressing during sprint. One new thing that we have tried for this sprint was - 'no story splitting into tasks' thing. What we did was, that we just created few tasks for the first day of the sprint and agreed to create the other tasks on the fly, whenever we will need it during sprint. After that we just brainstormed about all sprint stories and what solutions we can suggest for product owner.

So now when I am looking back to how it worked, I really like it. First of all sprint planing meeting was not so 'hard'. We were just sitting and discussing things. And if I try to compare it with sprint planning that happened before this one, so I could say that last one was much more productive. Because we were not forced to commit ourselves on what exactly we will have to do and how long it will take, like 'create x files' and 'create y things' and so on. But instead we analyzed in general how we will do it and what the best solution we can offer to our product owner. I think we have covered more things in this way compared to the splitting-into-concrete-tasks way.

Now during sprint, in every daily scrum we have defined new required tasks and agreed who will work on each task. What I liked the most about all this was that it was so easy to create those tasks. It was very clear what we need to do. Every morning there were new challenges that we had to take if we wanted to achieve our goals. And now when I have putted all those sprint tasks on the wall and joined them, I noticed that I have got a web:

Story A -> task 1 -> task 2
task 1 -> task 3
....

And that gave me an idea.


This sprint we will do the same thing, just I will try one additional activity. I will try in next sprint planning meeting to use a mind map tool. While we will brainstorm about each story, I will time-box each session for 10-15 minutes and will see with what trees we will come up. Then I will print all those trees and during daily scrum we will use those to define tasks.
What I hope to achieve is - better solution. Because during brainstorm session, of course we will define some solution for a story, but first solution, at the most of times, is the one that will be re-factored. So I hope these mind-maps will have those first solutions and during sprint, in daily scrums, we will see what solutions we already have and perhaps we will define some new ones and better ones and in this way we will improve quality of our software.

Let's see if it works.

2010 m. kovo 2 d., antradienis

Convert problems to challenges

We had sprint planning meeting and it was really hard meeting. Lot of unknown things about stories and problems were there and there and it seemed that all this product is one big problem. So what our product owner suggested, was like this (credit goes to Charlotte Way):
Let's change the word problem to challenge and when you have a problem, instead of saying I have a problem, say I have a challenge.
And you know it really works. It was not so depressive anymore to talk about those problems, because there were no problems! Product now is a challenge and bad 3rd party API is a challenge, that bug is a challenge and when you get used to that word it really works, and everything looks much easier.

So from that day, I do not have any more problems, there are only challenges!

Applying Scrum - Part 1

Few weeks ago I read a book, which basically was about how practically scrum was applied in one big company. Good thing about that book was that it contained only practical examples how Scrum worked for them, no theory, only pure practical examples.
That book helped me a lot, so I thought perhaps it would be good idea to share how we do scrum and perhaps someone will find it useful.

It's about team members commitment
Challenge - make team feel responsible for a product

At the beginning, when I have started to implement Scrum, everything was pretty ok. We have implemented all those basic scrum rules like daily scrum, we had backlog, product owner, scrum master, agreed on sprint length and so on. But despite of lot of other challenges, I will cover those later, after few sprints we were failing to deliver what we have promised and deliverables was note actually DONE.
So I was thinking were is that challenge? why this team is failing ?
When I have started to analyze, what actually we were doing during sprint, I found that team was not working as a team, but they rather just waited till what I will say how and what we should do! Daily scrum was like "so what should I do now ? I did that, and that, what next ?" And when you fall into this, when you start thinking what all should do, you are starting actually to manage them and that is wrong, very wrong.
Team must feel responsible for what they are delivering. You have a goal and you are responsible to do everything what you can to achieve that goal, there is always something you can do, you just have to feel that this is your product and you will see that there is a thousands of tasks that you can start working on. And there should be no "you" and "me", there must be a team and everyone must understand that if I will fail to do something - all team will fail.
And what happens when there is one person who is creating and assigning tasks and he is the only one who sees the whole picture? You always can blame him and only that person will be responsible.

So, lesson that I have learned is:
Before you start sprinting, make sure that team understands what that word "team" really means. Try to make them feel that they are a part of something that they are about to create. And also explain people what each of team member should be expecting from each other - that would be responsibility.
I think that if you want to be a very very productive team, first of all, all team members must feel responsible for the product and treat it like it would be their own baby.