Tag Archives: DDD

Beware of proxy domain experts

Today I’ve watched Greg Young’s keynote from DDD eXchange 2016. The talk is really awesome, though-provoking, turning everything upside down… I really recommend.

However, the point that caught my attention most was the answer to the question from the audience (at the very end). Greg mentioned that we need to be very careful with who we consider domain experts. He even said that on one project their end-users hated the app, because their “domain experts” actually had no idea about the work that end-users were doing.

I’ve experienced that mistake myself, in one of my summer jobs. For a couple months I worked in a call-centre for a mobile operator.

When you call somebody in the middle of the day to talk about their soon-expiring-contract with a mobile operator, what do you think is the most common answer?

I need to think about it/I can’t talk right now, please call me at XYZ time.

Pretty obvious, right?

The only problem was that it was impossible to do, because the calls were assigned randomly to people and it was impossible to make sure the call was assigned at a specified time! You could specify the preferred time range, but more often than not it didn’t work as you’d expect.

The result?

People entered random information and date in the system, wrote everything down in their paper calendars and handled the whole case outside the system. Some time later another unlucky operator who got that call assigned had a very bad day (you won’t believe how angry people are when you have no idea what they told your colleage a few months earlier and what they asked them to do back then).

In the end the system was an expensive phone book, that pissed off a lot of people, both working there and those that got the calls. The work was hard, stressful and annoying enough in itself, and the software we had to use only made it much worse instead of helping.

That’s what happens when you don’t realize you’re dealing with proxy domain experts.

To DDD or not to DDD? What to do if your domain is boring?

I’ve heard many times that DDD should be applied to complex, interesting domains only. Even some experts that I deeply admire say that, so it must be true, right?

The problem is that I’ve never heard what exactly makes a domain interesting or complex. Especially, what makes it interesting or complex enough for the purpose of DDDifying it. I think the problem is we’ve been asking the wrong question here.

This tweet by @DDD Borat summarizes my thinking perfectly:

borat

But first let’s have a look at two examples that shaped my opinion on the subject.

Case study # 1. Anemic domain model. Boring, boring, boring LOBA (BBBLOBA).

A few years ago I’ve worked on an e-commerce system. We’ve covered basically everything you could imagine online store does, starting with displaying catalog, managing promotions, calculating prices, checkout, through emails, payments integrations, to all the backend stuff that customers never see, like refunds or shipments integration.

The business logic was randomly divided between controllers, data access classes and stored procedures. There was no business logic layer whatsoever (at least not when I started there).

One day I was particularly frustrated. Looking at yet another property bag which was proudly (and inaccurately) called our domain entity, I mumbled something about Anemic Domain Model. My colleague heard it and he sighed. “Yep, no wonder we have anemic domain model here”, he said. “There’s no interesting business logic. That domain is just soooo boring.”

I didn’t know what to say. I’ve just spent a week tracking how refunds are calculated. I found a bug, which was rejected by our QA saying “It’s too complicated, I’m not raising it”. If that wasn’t an interesting piece of business logic, then I have no idea what else it was. So I only nodded my head in faked agreement and went back to work.

Case study # 2. Domain crunching applied. Boring, boring, boring pet project.

A few months ago together with my boyfriend we got really pissed off with the mess which is called our personal finance. We didn’t know exactly where our money went and how much we spent. We used Excel before, but that didn’t seem good enough anymore. Our finances got more complicated over time. Also our expectations were higher. After a few years of tracking expenses, we knew what we wanted out of the app.

We did some research, I checked dozens of apps and none of them fit our criteria. We could hack them to fit our needs and do some calculations outside of the app. Instead we did what any programmer would do in such a situation – we decided to write our own.

Now this surely is the most boring domain one could imagine, right? Apart from maybe a TODO list, it’s the most popular pet project ever. Every programmer writes it at some point.

But over the period of a few months we’ve learned a lot about the domain. I think we can say we did the proper domain crunching. I acted mainly as the annoying customer/business expert, who is never satisfied with what they get (I’m absolutely brilliant in this role). Often I didn’t know what I was after, but I knew exactly when something felt wrong.

The first insight was that in fact we have two main parts in our app, which are to large extent independent. Tracking and analyzing. That fact impacted our model in significant way.

For example accounts are very useful for tracking. I can compare the actual total on one of our 11 accounts and the data in our app. If there’s a difference I can start looking what I missed this time. FYI I can’t force myself to enter all transactions every day, so it’s extremely important that identifying what transactions I missed is convenient. Accounts are perfect for this.

On the other hand I don’t care about accounts at the analysis stage. I don’t care if the specific payment was made from my personal account, our joint account, or my boyfriends wallet. Consequently, why in the world would I filter my expenses by account in reports? It gives me no actionable insights whatsoever. Adding such a feature would be a waste of time.

You might think “Isn’t it obvious? What’s the big deal?”. This is exactly what shows that we’re on the right track with modeling our domain. Afterwards it seems like the most obvious thing under the sun. But I can assure you it wasn’t that obvious when we started. Plus, most apps DO reports by account. Don’t ask me why would anybody use this. I have no idea. I wouldn’t.

Then we hit our first problem. I’m self-employed, so I pay taxes and health insurance myself. It’s not really an expense, in the sense that I can’t do much to make it lower. So from the perspective of optimizing expenses it was only a noise. Yet, it showed on my account and it was useful to track in some way. At first we added a flag which indicated whether the specific expense should be included in analysis. But after a while we’ve realized we have a missing concept here – an income cost. We have other expenses that shouldn’t be included in reports, but tracking my income costs on its own is actually useful information. Making this concept explicit made both things easier and less error-prone.

The next challenge came from my boyfriend. He does a lot of business trips. He covers expenses during his trips himself, and then his employer returns the money in the next salary. He goes mainly to countries more expensive than Poland, so those expenses are rather high. They completely ruined our analysis, and made tracking all expenses challenging. We still wanted to track those in the app, so we don’t forget to check if the money was returned, but those weren’t just normal expenses like groceries. That lead us to discovering another new concept – reimbursable transactions.

Since I occasionally lend money to family or friends we thought about explicitly modelling loans too. After giving it some thought we decided that using reimbursable transactions in that case is good enough. If we ever need more detailed distinctions between those two types of transactions, we can adjust our model. For now it’s good enough.

We’ve made many more discoveries like those described above. We used the app, noticed that something feels wrong, discussed it and refined our model. With each new discovery, our model got cleaner and made more sense. Looking back we were surprised we didn’t come up with all of this from the very beginning. It looks so obvious!

Back to DDD Borat

If you think about this, an e-commerce platform is way more complex and interesting than a personal finance app. Or is it?

I think we’ve been asking the wrong question here. It’s not about the domain per se. It’s not that one domain is more interesting or more complex than the other. Being interesting (whatever that means) is not an intrinsic characteristic of a particular domain.

What makes a particular domain interesting are problems you are solving.

In many cases it doesn’t make sense to go with your “domain crunching” very deep and some basic, off-the-shelf model, or slightly customized solution would do. If you can get away with CRUD, then by all means, do CRUD. If you’re a physicist then a bird is a bird, that level of abstraction would do just fine. It wouldn’t work for a biologist though.

The other thing that makes a particular domain interesting is you.

Can you notice when your model is not good enough anymore? Do you know when it’s time for a re-modeling session? Do you ever talk to your domain experts using their language? Are you truly interested in their problems and how to best solve them?

If not then no domain would be “interesting enough” to justify using DDD.

No excuses

So don’t let the popular myth to hold you back. You can apply the so-called “strategic design” principles even on your pet project.

In our case applying DDD concepts to the pet project pays off. The app is easy to use, we make fewer mistakes than in the beginning. When it was a simple CRUD app, I messed something up at least few times a week, because I forgot what flags to set in what situation. Fixing my mistakes could take us anything between 10 min. to 1 hr. Now each concept is modeled explicitly and I have no doubts how to enter all transactions, even when I’m particularly tired.

In many ways our app is simpler than the apps available on the market (e.g. our “budgets” are primitive), but it’s more sophisticated in other aspects. Above all – it makes sense to us.

What is good for everything, is not really good for anything

Some time ago I worked on an ecommerce system, which allowed for very flexible promotions setup. If I remember correctly, it was poosible to create roughly 30 types of promotions. As you might imagine, testing all of it was a pain, since for every single promotion type I would need at least 10 test cases. So instead I decided to find out what combinations are actually used and focus only on realistic scenarios.

One day later I learned that business used only 5 fairly static kinds of promotions. And thank you very much for asking, they are happy with that number. They don’t need more. But since we’re already talking, would it be possible to have a promotion name in a dropdown and prepopulate fields accordingly? Most of the setup was static per promotion type and there was sooo much clicking, wouldn’t it be easier to just select a name from the dropdown, enter one number and voila, new promotion is ready? Knowing that promotions are much less complicated than we thought would also simplify implementation, not to mention testing…

I remembered that situation when Udi Dahan told us a universal reporting tool story during his ADSD course. He asked if we were ever told to create a universal reporting tool with all sorts of fancy filtering, sorting and presentation features? Did it allow for saving all those uber-flexible setups and giving them names, so business can run the same reports over and over on regular basis? Maybe you also find it disturbingly familiar?

The problem with flexible tools is that building them is extremely complex, they need to perform well on huge amounts of data and using all possible combinations of available options. That’s exactly what MSExcel does and Microsoft worked on it for a number of years now. Yet, usually we’re asked to build ‘mini-excel’ in much shorter time and given much smaller team.

The sad part is that most of the time the flexibility is not really useful. Most users save their 5 or, in extreme cases, maybe 10 static setups and run reports on them for months. So first of all, it’s a wasted effort. The exception is small percentage of users that really don’t know what they’re looking for in data until they actually see it. They play with models, look for patterns. But they’re minority and would be probably better off using tools dedicated for that kind of exploration.

Then, knowing what information user looks for, we could give them much better experience, so it’s also a lost opportunity. In case of promotions, we could save them typing and clicking. Given they had to setup dozens of promotions each month that would add up very fast and result in much better experience. In case of reporting we could think about generating ‘real time reports’ and sending them alerts. For example if every day somebody needs to run a report to check whether there were any orders matching some parameters, wouldn’t it be great if they got an email every time it actually happened? I bet they would love you for that feature. Not to mention how much work you would save yourself by implementing simpler, narrow solution.

So if ‘the other way’ is so bright why we keep working on universal, super flexible, yet not fully utilized features? In my experience the following factors contribute to the problem:

  • We don’t talk (enough) to business. The most obvious one. Maybe we’re not interested in business side of things, or maybe we don’t have opportunity to talk to the right people. Either way it’s obvious that something is missing here.
  • Business has to constantly fight for IT resources. So since we’re already doing something for them, they tend to ask for anything they can think of. After all nobody knows when they get hold of any geek the next time. By having a flexible tool they can do their job without needing us that often.
  • We (as an industry) taught business to speak our language. As an industry we didn’t do a very good job in learning how to get requirements out of business users. Not stories, not features, not “I want Y shown when I click X on ABC screen”, not CRUD. I’m talking about getting to the source, to what problem business is trying to solve with the feature they dream about, about discovering their why. Only then we can help them to come up with a good solution. Blindly following the specification is just not enough. Business users don’t come up with best solutions and designs. That’s our job.
  • The more complicated the feature, the more fun it is to implement. Let’s face it, sometimes it’s just too tempting 🙂

Are there any more factors you observed? Please, share them in comments.

Why DDD is so damn hard?

In my latest post I mentioned the quote from Evans book. I met quite a lot of people interested in DDD, that either missed this quote or didn’t realize how significant it is. Yet, I think this is the single most important thing you should understand before you even attempt to start doing DDD. Even more so if you want to advocate it in your company and drive the adoption.

DDD is hard. Not because it’s complicated. In fact it’s a rather simple idea. Not because you have to be another Evans to get any value out of it. You can do a lot of tiny things, right where you are now, starting today. Not because there are no materials available or that the good advice is given only to the chosen few. Everything’s out there, easy to find, a lot of useful things you can get for free or pay a few dollars for a book.

I think that DDD is hard for two main reasons – it requires a completely different skillset than what is normally expected from developers and a completely new way of thinking. You need to become the soft geek and watch out to not slip into the more comfortable mode.

The soft skills can (and should!) be learned, also by means of formal training. There’s really a lot of good material out there on Emotional Intelligence, motivation and goal setting, communication, dealing with conflict and leading change. At the end I put links to my favourite resources, in my preferred “geeky style” – very pragmatic, based on solid research, with advice specific enough to get it into practice right away. I’ve gone through every one of them more than once and intend to do it again and again. I learn something new every time. But this is the easier part, if you know what you’re looking for, then eventually you’ll find a way to get it.

The other problem is that the way you approach DDD is very counterintuitive, it’s different from what usually works for us, it’s very, very, very uncomfortable (it really is!!!). There are some experts, but you need to learn to be your own expert, because DDD is messy and very sensitive to the context. What worked for Evans, might not work in your project. You can’t really get a good answer to DDD-related question on StackOverflow. There’s no book or a flowchart that will help you with making decision. You need to learn to observe, listen, become more self-aware, recognize hidden assumptions and… your own biases.

Evans casually mentions that the technical talent usually prefers to work on elaborate frameworks, rather than solve domain problems. Rather than treat software as a tool, means to an end, we learn to use it as a universal hammer. This is how we work, this is how we provide value, this is what we’re proud of doing, in essense – this is who we are.

Learn to see it, notice limitations it introduces. Then start asking why, why, why? Don’t be afraid to take a couple of steps back and question everything you “know” to be true. You might feel uncomfortable, because you suddenly stop “getting things done”, you feel unproductive. Even though you understand on an intellectual level that this way you provide more value, it’s still challenging on the emotional level.

When I first started asking a lot of questions, every single task was taking a lot of time. We had lots of meetings and discussions. Some colleagues told me that if the customer can’t get the requirements right, then it’s their problem, we should do our best, the way we understand it. I didn’t agree. I worked my own way… and felt very unproductive.

After all those discussions some work was even dropped, because we realized that it was in the backlog for too long and it wasn’t relevant anymore. It happened once for 3 tasks in the row. So my colleagues joked that they will give to me any task that they didn’t want to do and maybe I’ll convince customers that we shouldn’t do it. It was funny, but also… After a few days of work I had nothing to show, no results, no feature shipped. All those meetings and discussions were demanding, I had to think how to explain things, watch out for assumptions to question. It would be so much easier just to do as I was told and do my best to interpret requirements without asking any questions. If something was wrong, they’d have noticed, right?

There were other things too. Since I’m an introvert all that extra communication cost me a lot of energy. Some days I was literally exhausted, after work I just wanted to sit alone in my room and don’t talk to anybody. Then I didn’t know how “those things” should be done. I was new to the system. I asked a lot of silly questions, quite a few times felt like a total idiot and promised myself that I won’t ask any more. Then I felt that I’m simply annoying because I give all those people lots of extra thinking, extra work, they surely must have hated me for this, not to mention that I slowed down the whole process.

For some reason that I can’t explain I believed this to be a good approach. And over time it started slowly paying off. We had an important project that involved changes in 30 different systems at the same time. My team worked on only 2 of them. The project lasted a few months. We managed to catch a few important misunderstandings at the very early stage of the project… and then we wasted the whole day discussing how to ensure data is consistent at the end of the “processing window”, only to discover that the business is ok with temporary incosistency. We insisted on having enough time for tests and consulted test cases with business. We caught a few other misunderstandings. The project was successful, there were maybe 3 bugs found in the business testing phase (compared to literally thousands raised for those other 28 systems). Questioning everything and talking to business weren’t the only reasons for success, but I know that if we didn’t do it, we’d probably miss those misunderstandings and they’d be discovered at a very late stage. We had enough time to find alternatives and we avoided re-work.

Still… I changed jobs, went to another company at the opposite end of the world, worked with a different client and it all started again. Feeling like an idiot more times than I dare to admit, doing things differently than they “were done there”, not sure if and how fast I can show that it actually provides some value…

It’s so much easier to disconnect and just “do as you’re told”, hoping that somebody else will make sure we’re working on the right thing and get the requirements right. Once you get involved, you also assume more responsibility, it’s not “somebody else’s job” anymore. It’s also so much easier to focus on all the patterns, discuss superiority of repository over static CRUD-like objects or hold endless modelling sessions, looking for the perfect model. The trouble is all that doesn’t really matter if you work on the wrong thing. Doesn’t matter how perfect your model is, if you focused on some unimportant part of business and don’t understand the domain.

So be prepared. Quite likely, you’ll be a lot out of your comfort zone, doing things you have no idea about, pretending that you actually know what you’re doing, learning a lot from your own mistakes… There will be lots of them. Maybe some colleagues will get angry with you,  they will tell you that what you’re doing is silly and a complete waste of time. Worst of all, they might be right, especially in the beginning. But you won’t learn all this just by reading a book and sitting in front of your screen all day. You can’t really learn all those things by doing your pet project, using some made-up requirements. You need to accept the discomfort and start learning those crazy things. The good news is, some day it won’t be that hard anymore.

Recommended materials:

“Influencers” great material if you want to lead the change in your organization, even if it’s “just” promoting automated tests and clean code

“Crucial conversations” absolute must-have on difficult conversations with high impact

“Crucial accountability” on how to keep each other accountable without ruining the relationship and being a jerk

“Succeed” a great book on goal setting and motivation (with the silliest title ever:)), solid research, no usual motivational crap, pure science and practical advice

“Inspiring Leadership through Emotional Intelligence” a Coursera course that proves that Emotional Intelligence can be learned and improved, fantastic material on how to listen better and how to avoid burnout

Evans got it wrong… or did he?

Recently I attended a local DDD meetup. I think the idea is slowly reaching its maturity, as after many “How to get started”, we’re moving slowly towards “How I/we/you got it wrong” kind of talks. It’s fantastic that people are openly discussing their mistakes and share lessons learned, but there’s something that really troubles me. It’s a growing DDD mythology.

Lenin is attributed with saying that a lie told often enough becomes the truth. Yes, this Lenin. Apparently he knew what he was talking about. We have quite a few of those lies already repeated over and over by well meaning people. I believe they’re trying to help, but unfortunately they didn’t check their facts before passing them on.

For example, if you’re interested in DDD, sooner or later you’ll hear that Evans got it wrong, that the order of chapters in his book is suboptimal. Some will even advise you to read the book in a specific, right order (skip chapters on tactical design and read them at the end).

People say that due to this silly error, some devs have done harm. Poor chaps got so excited with all the new ideas, that they decided to change the world right after chapter 7 (or sooner!). Before we get sidetracked into discussion on how is it even possible, that professional adults make serious decisions based on one book they didn’t even finish reading, go ahead, look at the table of contents. Do it now! It’s free.

Anything interesting?

Did you notice that tactical patterns are described only as far as part II?

Then go back to the sample content. Read it. Or if you’re in a hurry, go straight to the page 4 and scroll to the last two sentences. There. Read three sentences. Only three, I promise. The last two on page 4, and the first one on page 5.

“Technical people enjoy quantifiable problems that exercise their technical skills. Domain work is messy and demands a lot of complicated new knowledge [!!!] that doesn’t seem to add to a computer scientist’s capabilities. Instead, the technical talent goes to work on elaborate frameworks, trying to solve domain problems with technology [!!!].”*

Now let it sink in your mind.

The next time you hear somebody saying that Evans got it wrong, please, do world a favour and tell them to read the book in order. Tell them to stop reading at chapter 3, if they don’t feel like they can make it to the end. Tell them to start with the last two sentences on page 4 and the first one on page 5. Even if that’s all they’ll read about DDD, it’s worth it.

Hopefully that will save us a few “How I got DDD wrong” talks. Or if we’ll have them, then maybe at least they’ll be based on facts, rather than myths slowly becoming the truth. Because Eric nailed it, right from the very beginning.

* Emphasis is mine.

DDD Ultra-Lite

Some people say that DDD is heavy and expensive and as such must be used with care. Some teams adopt so called “DDD Lite”, which means they use “tactical patterns”, but don’t do much in terms of strategic design (or in plain English – they use software design patterns described by Eric Evans in the blue bible, but ignore the ideas that are considered truely important).

Truth be told, I’ve never worked on a “real DDD” project (yet!). However, DDD inspired me and I believe it made me a better developer. I used bits and pieces, most of them wouldn’t be recognized as “real DDD practices”, but I remember exactly where the inspiration came from.

I believe that the true value of what Eric Evans wrote years ago lies in the fact that virtually anybody can use some of the things he proposed. They don’t require any special tools, money, approval or reorganization. Those are simple things that you can start doing from next Monday (or tomorrow). I call those ideas “DDD Ultra-Lite”. Some of them are not new, but I believe Evans did a really good job of finding words and metaphors that stick and he certainly provoked a few AHA moments.

So here they are (in random order):

1. Listen to what business is saying

I’m not joking. The advice is probably as old as programming itself, but Evans has an interesting perspective.

He said that if business experts don’t understand your models or think they are awkward, then it means that you have to work more on that. Sometimes business people don’t openly oppose your idea, but you can see that they’re not very enthusiastic about it and that something bothers them, maybe they are confused or maybe they simply say that it doesn’t feel right.

There’s the opposite situation too. Sometimes when you finally find a good model and you communicate your idea to business expert he looks at you as you were the stupidest person in the world. Yeah, you are right, that’s obvious, what took you so long to understand this simple concept? That indicates that you finally got it right.

2. Do just enough design

Both over- and under-engineering are problems. Finding the balance between deep design and just “shipping features” is not a trivial task. Evans gives us a few tips that I found very useful:

  • Use the simplest possible model that allows for solving current problem. Don’t try to model reality, you will fail.
  • Remember about clean code, make your code and design easy to change and improve in the future. If your project is successful then you will change your design many, many, many times. As such, you don’t have to get it perfect first time (and probably even can’t).
  • If code starts getting in the way and you notice that making changes becomes more and more difficult, it might be a sign that your problem has outgrown the current model. Time for re-design of this piece.
  • Redesign small pieces of the system as need arises. Again, strive for the simplest model that solves the new problem.
  • Collaborate. Go for a coffee with a group of devs and/or architects. Discuss your problem with them, brainstorm, sleep it over and go back for another session.
  • Don’t make it heavier than it needs to be. Evans suggests multiple iterations, short discussions (1-1,5h), lots of learning and humility.

3. Ask powerful questions

Sometimes I work on a new feature or modify the existing one and the design starts getting ugly. It was just fine right before this change, but suddenly it becomes very complicated or just looks bad. This is a sign that the design should be changed, nothing special there. However, in Evans book I found a couple of questions that helped me on few occasions: Am I missing some domain concept? Does this change introduce or uses a concept that doesn’t match the existing model?

In other words instead of adding a few more if-s here and extra helper class there, maybe it’s time to revisit the design and find something more robust, more general or simply different. Something that explicitly caters for this new concept that just crashed our beautiful model. This is especially true if you know that there are more upcoming changes in this area or you work on a piece of code that is modified frequently.

4. Don’t reinvent the wheel

Evans encourages seeking external inspiration multiple times in the book. He mentiones browsing through patterns calatogs, to find out whether we can use one of them (possibly with modifications). He encourages investigating how similar problems are solved in other contexts (e.g. in other industries).

What still surprises me is that I haven’t experienced this approach in many places. I know some people look for solutions on the internet, browse through blogs, watch presentations from conferences, but as far I haven’t heard anybody say “I read it in XYZ book”. Usually the “design” sessions I attended were pretty much random brainstorming meetings, few people even prepare for them or know what exactly the problem is (e.g. has numbers describing non-functional requirements). Then months later we come across some random presentation and it turns out that we could have used something else and avoid a few problems.

I know that people talking at conferences and scientists make extensive use of solutions used in other industries. They try to find common issues and adapt solutions to specific needs. However, I think that in “real-life” very often we rely on personal experiences in other industry (e.g. in previous job) rather than extensive research.

The improvement I personally made is to make the “research” phase more organized and extensive and to revisit some “classics”. Blogs and presentations are extremely valuable, don’t get me wrong, but books tend to be better organized and contain more time-proved material. Not to mention that some of the “brilliant” articles are just plain wrong and relying on random Google search for unknown subject is not a good idea. If it’s written by a respected expert that should be all right most of the time. But even experts disagree and don’t always explain their unique context when describing solution.

If I remember something that might be useful I go back to the source of this information to refresh my memory. I try to find related articles, books, presentations or case studies. If I absolutely have no idea where to begin, then there are a few alternatives that proved useful for me: going back to the theory (I’m still surprised how valuable that is), browsing through the catalog (e.g. design or analysis patterns), while focusing on context and problem descriptions or finding a good “domain guide” for IT professionals for a specific industry.

That might sound trivial but I encourage you to really try it “as you meant it”. You might be surprised (I definitely was:)).