For the couple of last weeks, there was the Euro 2012 Cup in Poland and Ukraine, and everybody around me was crazy about the football those days. On the other side, couple of months ago I started to practice Domain Driven Design with Command Query Responsibility Segregation with Event Sourcing. I combined those two and launched my startup as a Facebook application written in this style: "Typer" (at this moment only in Polish).
What were my goals?
From the personal perspective, I wanted to give people some opportunity to have fun - to type scores in their own groups, compete with each other and find out who is the best football specialist.
From the business perspective, I wanted only to generate some traffic and see if it can be profitable in the future.
From the development perspective, I wanted to practice DDD/CQRS/ES, since I do not have enough possibilities to do it on daily basis.
From the management perspective, I wanted to learn how to use my time effectively, and how to lead my small team.
Did I succeed?
I did! Maybe I wasn't able to achieve 100% of goals that I set up, but I am proud of what I did and I am much smarter now. I want to share my thoughts with you, so here I present my 7 lessons learned:
1. So you think you are Agile?
From the very beginning, when I started to work as a professional software developer, I was told to be Agile. During my career, I saw a couple of implementations of that, but none of them was even close to the Real Startup Agility, which I had to adopt during that project. In all companies that I worked for (small and medium companies, large corporations, and even my own company for some time) there was and still is a lot of classic waterfall approach.
During this project, I had so extremely limited time resources (working after hours), and so hard deadline (the start of the Euro 2012) that I had to use the Pareto Rule on the Pareto Rule itself. I saw how prioritization and choosing right solutions in right places is extremely important.
For example - I did not have the rankings recalculation functionality when the first match was started. I was finishing it during the first minutes of the match and I released it after the first half. But it was conscious decision. Other things were more important before the beginning of the first match.
During those four weeks I released eight versions on my application. The only way to do it faster is to implement some continuous delivery mechanism.
So to summarize: If you didn't run a startup on your own, you probably are not that Agile as you think you are. ;)
2. DDD/ES domain model is the easiest to test.
If you are willing to flip the bit, and start doing Test Driven Development, start it on Event Sourced Domain Model. This is the best way to see how valuable TDD is. The idea is simple - structure your test cases in this way:
- Given - a list of events
- When - a command
- Then - a list of events
I did not have any bug in the domain model for the whole time - although I had some minor bugs in UI, and a bigger one in the security, which is fixed now (but screw it - it was a startup). ;)
3. You don't have to be DDD/CQRS/ES'ed everywhere.
Modeling the Domain is a hard job. It requires much more intellectual power than classic, anemic approach. But guess what! You don't have to do it everywhere. Sometimes the biggest value is not in the Model.
When I started working on the security module, I planned to do it fully DDD/CQRS/ES'ed. But after spending a lot more time than I actually planned on that, I had to revise my approach. The Model was not the most valuable thing in that place - the OAuth2 algorithm was. I dropped my fancy Model and rewrite it in the simplest possible way to support the algorithm. And I moved on.
4. The CQRS's Read Model is extremely flexible.
The Read Model can be dropped and completely rebuilt from events. This gives you a lot of possibilities. If you model your Domain right, and define Events correctly, you will be able to mess with the UI as much as you want. You will be able to improve the UX by generating better views and you won't need to write complex updaters. Just re-run all events and voilà!
As Yves Reynhout twitted once, I grasped the domain well. My commands didn't have to change, but the UX was updated couple of times.
5. You probably won't end up with the Context Map drawn at the very beginning.
When we (me and my team) decided to do this startup, we created a Vision Document. And according to that Vision we started to draw the Context Map. At the very beginning it looked very promising - seven Bounded Contexts with good boundaries. After a couple of iterations we realized, that this Context Map needs to be corrected here, erased there and some Bounded Contexts needs to be joined.
We also had to cut a lot from the final functionality, to be on time.
Maybe this approach (top-down) should be taken in the really big projects, but for startup you should go quite the opposite - start small and then evolve (bottom-up).
6. Fail faster.
We didn't test our UX against real users before we launch. We had to incorporate some UI changes in the later phase, when it was a little bit more expensive. There are so many ways to create cheap prototype and get the feedback from users. Paper cards for example are great example. We should have taken them under consideration.
If something is painful, do more of it. We had some problems with deployment at the very beginning. We tested most of the process and automated it as much, as we were able to. So that, when we were releasing, no problems occurred. And we were releasing quite often on that short period of time. I am starting to think that Continuous Delivery can be very interesting thing, that may improve your Agility.
When you are doing something, seek for the possibilities to fail safely as fast as you can. (I am not talking about searching for excuses!) If you see, that something may go wrong, go down that path and explore it. It is much safer (and cheaper) to do it early.
7. You need great people.
Last, but not least - people are the most important piece of that puzzle. It is easy to read, listen and watch presentations about methodologies, techniques and all that stuff. But at some point, you will have to implement all of them (or some part). And you need skilled and motivated team to achieve that.
So big up for all of you, who helped me with that: DEV (my bros, Wojtek and Krzysiek), UI (Marcin), OPS (Bartek), UX consultations (Marcel), and of course my biggest supporter - Ania. ;)