Sunday, January 26, 2014

Repositories, where did we go wrong?

In essence, repositories are a simple abstraction over aggregate storage. A repository will insert, update, delete or fetch an aggregate from the underlying persistence mechanism. This abstraction avoids that databases, SQL statements, Object Mappers and the like leak into your domain. Next to that, swapping out repositories for an in-memory version makes testing easier.

Recently, the use of repositories is being questioned again.

Why would we wrap Object Mappers in yet another abstraction? Aren't Object Mappers already an implementation of the repository pattern? In a recent project, we left out repositories. In that project we're using RavenDB, which already has an expressive API, and which can be configured to use an in-memory database for testing. Even though LINQ and indexes help make simple queries expressive, a lot of cruft still leaks in, not doing the language any justice. In other projects, we did make use of repositories over our ORM. Partly because setting up in-memory tests without was awkward at best, but also because it removed constraints trying to capture the language. Next to testing and expressiveness, you should also consider how comfortable you feel gluing everything to a library or framework. When it comes to aggregate storage, having those repositories is a small price to pay to keep technicalities out.

Another remark is that a repository makes it hard to control eager- and lazy loading, which is contextual. In general I think that lazy loading introduces unpredictable behaviour. Getting in trouble without lazy loading is a strong indication that your aggregates are just too big.

The last and loudest argument is that once you have a view heavy application things get dirty really fast. It starts by adding a few badly named query methods on your repositories. Then, you start to see use cases where you need to query over multiple aggregates and deal with projections or aggregations. In these situations repositories won't help you.
Truth is that repositories were never intended for complex reads. Views on the data that your application needs rarely resemble the structure of your aggregates. Making your aggregates suited for querying inevitably steers away from behaviour thinking, back to data thinking. The trick is to separate read concerns from your domain. Instead of trying to use repositories for querying, make use of the best tool for the job, something as close to the database as possible. The implementation depends on your flavor, but what has worked for me is having use case optimized read models, a query object and a query handler that reads from the database and converts the result into a read model. The implementation of each query handler can differ; from raw SQL, to hibernate query language, to a micro ORM... whatever works best really.
Doing this, you allow your domain model to stay focused on the task at hand - handling complex business problems, staying far away from read concerns. Before you know it you're successfully applying that popular four letter acronym, enabling you to even try other concepts without having to rewrite your model completely.

Sunday, January 19, 2014

new YearPassed(2013);

I normally write this up at the end of the year, but circumstances made me push back this post for a few weeks. I use this annual post to look back at the year passed, and to look ahead to the year to come. I gave up on making resolutions in 2011. This year, I'm going to be naively ambitious again going into 2014.

Compared to previous years, I feel more confident that I have a pretty good idea of what I want next. Just before the holidays, my fiancée and I spent the weekend out of town where we took a whole evening to modelstorm 2013 and the future. We used green and red post-its to list all positive and negative memories of 2013. We then categorized those, and defined concrete actions to avoid repeating negative experiences, and to increase the number of positive ones in 2014. Next to this technique, we used a timeline to plan some key milestones a few years ahead of time.

My career

September 2013 marked the two year anniversary working for Euricom. It also marked the second year at my first client. There, I spent last year deeply immersed working on what has been coined by upper management as the most important project of 2014. Having invested much, and despite having a bunch of ingredients for failure, I'm relieved the project went out the door yesterday. I look back at the project with mixed feelings; there were several periods of intense learning and going fast, but way too much time and energy was wasted fighting the system. After spending more than five years in the bowels of the beast, I don't feel as if the enterprise is a healthy place for me to live in, let alone a place capable of cultivating good software.

I'm going to try really hard to avoid these breeds of working environments for a while. Unfortunately, they make up a good portion of Euricom's customer base. This led me to resign at Euricom last month. Four weeks from now, I will start at a much smaller gig where I hope to find more autonomy, skin in the game and entrepreneurship. I'm also extremely curious to discover and learn about the insides of the domain.

Blog

I published a bit less compared to previous years, but I found a sustainable pace for writing: one post a week. Like I said earlier, traffic has stagnated, but the number of subscriptions and the average time spent reading has increased. 

The topics I write about have drifted away from mostly technical ones to Domain Driven Design, modeling, personal experiences, conferences and book notes.

Community

Although I only spoke twice myself, I got to meet up with inspiring people more than once; the IDDD Tour, DDD Exchange, CQRSBeers, BuildStuff and most importantly the birth of the Belgian DDD Community

Meeting up with likeminded souls, exchanging ideas, war stories and hopes, sharing food and beer is something that has been a source of true bliss. There are too many people to thank, but I'd like to name a few in particular: Mathias, Alberto, Christophe, Bart, Stijn, Yves, Tom, Marco and Thomas

Next month, I'm attending FOSDEM and I'll be talking at DDDBE. I also already bought tickets for buildstuff later this year.

Travel

I got spoiled this year; I got to visit six different countries, spending more than five weeks abroad:
  1. England
  2. Spain
  3. Czech Republic
  4. Lithuania
  5. USA
  6. Luxembourg
We're still indecisive about whether we should visit Asia or something closer this summer. Anyone that can recommend locations in Asia?

Projects

I killed one side project at the start of this year, and documented it here. I spent a big part of this year working on another project. While I'm not sure if we will get that ever of the ground, I learned a few lessons though. Contact your potential customers before you build a close to finished product. If you're going to work on something in the weekends, don't make it feel like work.

Sports/Health

The fiancée and I have built a habit of regularly doing long hikes - once every month. This is something we're going to keep up, maybe even put it in the center of one of our holidays.  

I ran 705km this year, which is 270km less than last year. After running three competitions early on in the year, I lost my hunger, and started slacking. To keep the momentum going and to have something to work towards, I should probably enroll in a competition every few months. I already subscribed for the Antwerp Urban Trail run and the Antwerp 10 miles this year. Anyone else subscribing? I haven't found a partner yet.

I also didn't cancel my gym subscription this year. I have put together a satisfying routine that mostly consists of lifting heavy things avoiding modern equipment. It's been fairly successful, bulking up 9kg the last six months. 

2014 side missions

Avoid Windows at home.
Learn a new (programming) language.
Build something just for me.
Spend less time in front of my machine. 
Read more. Watch more conference videos. 
Do nothing. It heals the soul.
Plan the weekend. 
More dinner parties.
Plan the wedding.
Take more guitar lessons.

Thanks for everything, I'm very grateful.

Sunday, January 12, 2014

Happiness before success

Somewhere in the beginning of last century, two shoes salesmen were sent to Africa hoping to expand their employer's market. Both salesmen reported home within days of their arrival. The first salesman wrote: "This trip turned out to be a waste of time; the locals are not wearing any shoes." The second salesman wrote something similar, yet very different: "This is looking very promising; people aren't wearing any shoes yet!"

A group of seventy year olds was invited to spend a week in a remote location where everything was arranged to make it feel as if they went back in time twenty years; they would get to read old news papers, were shown recorded television shows etc... They were also asked to talk about their jobs and kids as if it were twenty years ago. Once the week was over, medical exams showed extraordinary results. Their health had improved noticeably; their eyesight improved, their blood pressure went down, their posture had changed...

In another experiment, a group of people was trained into using a new piece of software. Half of the class was taught to prevent errors from happening, while the other half was encouraged to make mistakes. A test afterwards showed that the group that had learned by making mistakes was a lot faster and efficient using the software than the group that was taught to avoid errors at all costs.

The mind is incredibly powerful; it's in full control of how we perceive things. One might be poor, having to live off a few dollars a day, and be perfectly content with his situation. While someone on the other side of the world might have everything he can imagine at his fingertips, but be completely miserable.

Popular belief dictates that if you work hard, you will eventually become successful, and once you're successful, then you'll be happy. This recipe is elementally flawed. With each victory, we put our eyes on that next big thing, never arriving at happiness.

In The Happiness Advantage, Shawn Achor starts by claiming that we have it all wrong, and that it's actually the other way round; happiness leads to success. Positive brains make us more efficient, creative, thoughtful and productive, boosting performance at work and at home. While the first few pages make a great sales pitch, the rest of the book differs from the usual life improvement charlatans backing up this hypothesis with narratives and DIY practices extracted from modern happiness research.

The book turned out to be a very casual read; the writing is easy and it only counts two hundred small pages - I finished it in a few hours. It has inspired me to try and be more conscious about how I deal with certain things, to always focus on the good, not allowing negativity to slowly poison me.

Quotes from the book
If all you strive is diminishing the bad, you'll only attain the average and you'll miss out entirely on the opportunity to exceed the average. 
Happiness is not just a mood - it's a work ethic. 
It takes about three positive comments, experiences, or expressions to fend off the languishing effects of one negative. 
Happiness is not about lying to ourselves, or turning a blind eye to the negative, but about adjusting our brain so that we see the ways to rise above our circumstances.
The fastest way to disengage an employee is to tell him his work is meaningful only because of the paycheck. 
Constantly scanning the world for the negative comes with a great cost. It undercuts our creativity, raises our stress levels, and lowers our motivation and ability to accomplish goals. 
Common sense is not common action. 
Couldn't the key to sustaining positive change be to turn each desired action into a habit, so that it would come automatically, without much effort, thought, or choice? 
This invisible pull toward the path of least resistance can dictate more of our lives than we realize, creating an impassible barrier to change and positive growth. 
Lower the activation energy for habits you want to adopt, and raise it for habits you want to avoid.

Sunday, January 5, 2014

Command and event semantics

Yesterday, I read this blog post by Michael Feathers. In the post he goes over a pain point he has often found himself struggling with while breaking down a large method; conditional statements. 
if (alarmEnabled) {
  var alarm = new Alarm();  
  ...
  alarm.Sound();
}
Should we extract the if and the associated block into a new method, or just the content of the block? Is the condition too important to hide in a method? How would we name the extracted method? How do we avoid the code from telling us lies?

To read up on all the nuances that the answers to these questions bring, you should read the full post. What's important for this post - spoiler alert - is that he ends up with two strategies.

He either gives the method an event-ish name...
IntruderDetected();
...or raises the level of abstraction by giving the method a very general name, avoiding lies too.
PerformNotifications();
While both options solve the original problem, their semantics are very different. When I raise an event, I don't care who is listening; one, multiple or no things might be listening. When I issue a command (the second strategy), I expect it to go to exactly one destination. Sending commands indicates a rather strong dependency; you expect something to happen because of it. Events are more loosely coupled; you broadcast something happened, and something might or might not happen because of it.

With this in mind, you can still make arguments for both options. The key here is whether notifications are considered to be an essential component of intrusion detection. Is intrusion detection still conceptually whole without notifications? Are notifications just a side effect of an intruder being detected?
Since the alarm is only sounded when it's enabled, it doesn't seem to be an indispensable part. Intrusion detection can live on its own, unaware of notifications. This makes a pretty strong case for having the detection component just raise an event - indirectly resulting in the notifications being sent.

In this example, I'd probably pull notifications out, add an event and a bit of infrastructure that dispatches events, making the separate concepts and messages between them explicit.
Events.Raise(new IntruderDetected());

public class NotificationService : IHandle<IntruderDetected>
{
    public void Handle(IntruderDetected event)    { ... }        
}
With those extra bits, we could also, instead of listen for the event and only sounding the alarm when it's enabled, only subscribe to the event when the alarm is enabled.