More Digestion, Less Ingestion

I set my 2016 book goal on Goodreads to half what it was last year. I felt/feel like I often use reading books and articles as a form of procrastination. I should spend way more time reflecting and digesting and reviewing and applying what I learn. Less time consuming/ingesting.

Unfortunately, I hit my 2016 book goal a few days ago, just about halfway through the year. “Josh has completed his challenge” went out on my feed, and a few even friends starred it. But, of course, my goal was to change my behavior and I’ve mostly thus far failed at that.

Try, try again.

Bounded Contexts

The first thing I learned about domain-driven design was “ubiquitous language”: the idea that the business users and the developers should work together to create a common language to describe and model a domain. You’d use that language in the spec and in the code. You’d use it to drive your design, elegantly expressing and solving your business problems.

It sounded like a pretty good idea. But I don’t know how well it can work yet, because I’ve only seen it done poorly.

Here’s a way I’ve seen it done (and done it) poorly: Trying to create a single, unified model that will work for a large, diverse set of functionality.

It’s hard to create a model for a large domain. It’s hard to make one model that works for everybody. It gets harder as the size of “everybody” increases. Details from one subdomain are irrelevant to another. Or just slightly different. But every detail is in there. Because everything is in there. This introduces complexity and confusion and pain.

Bounded contexts are a solution to this. More simply put: Use multiple models. Use a model that makes sense for a given context. Don’t try force everything into a single model.

A model, after all, is useful because it helps your brain: It helps you think about only the details relevant to the problem at hand. When details are included that are irrelevant to the problem at hand, the model stops being so helpful.

With bounded contexts, you might have a half dozen models different in your domain, with a notion of Customer in each and every one of them. And that’s fine. Each of those Customer models should be tailored to the needs of that context.

Yes, that makes your “ubiquitous language” less pervasive, but your ultimate goal isn’t to have ubiquitous language, it’s to build good software.

And, yes, you have to identify what your bounded contexts should be, how to split your domain up. That’s part of designing your domain.

(And perhaps you can benefit from it beyond just designing a useful domain and domain language. I would think the descriptions of those bounded contexts will end up looking a lot like high-level descriptions of the business problems you want your software to solve.)

Identity, Outcome, Effort, Improvement

There seems to be a movement among parents and teachers that values praising effort over outcomes. I think that’s valid. (Both are better than praising identity, too.)

But perhaps improvement is the thing to praise.

  • Identity: “You’re so smart!”
  • Outcome: “You got an A on the test!”
  • Effort: “You worked so hard!”
  • Improvement: “You really focused on x and did much better than last time!”

Improvement tends to come from not just effort, but right effort; from looking at the gap between where you are and where you want to be, then working hard and smartly to bridge it.

Not Invented Here

Programmers are constantly tempted to build things ourselves.

You could bring a third-party library into your application for logging or graphics or testing or any number of other things… or you could probably write one yourself. And you could build exactly what you need, as opposed to doing things the way the library authors thought was best.

You could install WordPress or you could write your own custom blog/CMS, just the way you like it.

You could buy Quicken or write your own personal finance stuff, just the way you want it.

You could sign up for Evernote or you could write your own personal productivity thingy, finely tailored to your needs.

You could register for Pinboard or Instapaper or Flickr or Dropbox or whatever… or you could write your own versions of these. It’s probably well within your capabilities (especially if you take away the need for it to scale).

Yes, you can do it yourself. But there’s an opportunity cost to that, always. What else could you be doing? That free library might not be perfect, but it might very well be good enough.

Silos

The developers don’t get along with the test team, so they don’t work closely with them. The developers do all their work and then throw it over the fence to the testers.

The designers think the developers are jerks, so they never ask for feedback. They send them docs when they’re finished.

Maybe the devs hate the DBAs. Or the UX team thinks the product owners don’t know what they’re talking about.

When functional silos form, feedback loops get longer. Effort is wasted. Or worse: Sometimes technical or creative decisions are actually driven by avoidance of people problems. That’s profoundly dysfunctional.

First-Order Cheap

Cheap developers are more expensive.

Why? Think long-term. Think total cost of ownership.

Cheap developers are only first-order cheap. You pay them less, whether salary or hourly. Sure, they’re probably not as skilled as more first-order-expensive developers, but they can “crank out” code. They’re making your features work.

They’re not higher-order cheap, though. No way. There’s a high probability that any and all code they write will be difficult to maintain.

Some people might call this technical debt. It’s not. It’s simply a mess. Technical debt is a tradeoff that comes from conscious choice. A mess is the result of negligence and/or incompetence.

As your first-order-cheap developers’ mess grows, you’ll want to make changes to your software. But when you try to add features, or to make even small changes, you’ll find the pace of development plummets. Because now they need to decipher their previous mess in order to change anything. And that’s not easy — it’s a mess, after all. Seemingly unrelated things will break when changes are made. Frequently. Trust and morale on the team tend to break, too, at this point.

So I’ll say it again: Cheap developers are more expensive.

A Chair In A Room

“Always design a thing by considering it in its next larger context—a chair in a room, a room in a house, a house in an environment, an environment in a city plan.” — Eliel Saarinen

For our purposes, perhaps: A variable in a line, a line in a block, a block in a function, a function in a module (or class), a module in a library, a library in an application, an application in a solution. A solution to a problem.

Your mileage may vary.

Two Things

It’s cool that you know a lot of stuff.

Here are some awesome things you can do when you know stuff:

  1. use it to make or do other stuff
  2. tell people the stuff

That is to say: There are two useful things you can do with knowledge: apply it or share it.

Better In Theory, Better In Practice

It’s helpful to separate your study of better ways to do things from your study of helping other people improve the way they do things.

On the one hand: When you’re focused on helping others, resist the temptation look at a situation and say, “Well, this is all wrong; it should work like x-y-z.” That tends to be poorly received.

Incremental improvement is better: “What if we tweak this one little thing?” Rinse, repeat.

It’s also less presumptuous. The more steps removed you are from whatever “better” state you have in mind, the more likely you are to be wrong.

On the other hand: When you’re focused on improving yourself, appreciate the heck out of not having to worry about hand-holding or protecting anyone’s pride. (Well, other than your own, perhaps.) You can say “this is all wrong”. Be brutal. Go nuts. Refactor and restructure all you want. Throw it out, rewrite it from scratch.

Hope To Finish

I hear this in daily status meetings: “I hope to finish X today.”

(I’ve said it, too. I’m not immune.)

Best I can tell, “I hope to finish X today” really means “I want to tell you that I will finish X today, but don’t actually have confidence that I will finish X today.”

Commit. If you have to commit to less, so be it. And don’t be afraid of being wrong. With practice, you’ll get better at knowing what you can commit to.