Pages

Thursday, August 20, 2015

High Performing Agile Teams: An Introduction

I debated whether I wanted to include Agile in this post's title or not. I'd prefer it to just be "High Performing Teams", but let's be honest, I need the Agile keyword for more people to be interested in the post.

I love Agile. I hate Agile.

I have a love/hate relationship with Agile:

  • I love its fundamental principles. I hate the large industry selling a shell of it.
  • I love the business results it can produce. I hate when it is an end in itself.
  • I love how it empowers people. I hate how it can be a tool for command-and-control.
  • I love how much I've learned from people in its community. I hate the incessant, useless noise that surrounds it.
  • I love when it includes its necessary components (planning, technical, business value, YAGNI, etc). I hate when it's reduced to daily standups, stories, and sprints.

I've sure you could create your own list like this one (I'd love to see it, so leave a comment if you've got one). There's so much surrounding Agile that it's easy to hate parts or even all of it. But its essence is still something to love. Its essence is what got everyone excited about it in the first place.

Agile's Essence: High-Performing Teams

Its essence is a set of values, principles, and practices that help teams flourish (thanks Kent Beck). Its essence is to create high performing teams.

The parts of Agile I hate are the parts that ignore this essence. High performing teams are the goal. Not practices. Not user stories. Not estimation. Not Scrum. Not the manifesto. Not TDD. Too often the practices become the goal while we lose sight of the real goal: high performing teams.

My goal is to recapture this essence with a series of blog posts about high performing (Agile) teams. There will be discussion of practices, but only as they fit into the greater goal to build high performing teams. But before I talk about practices, I will first cover the prerequisites for high performing teams. Stay tuned!

Tuesday, April 14, 2015

Dependency Elimination Example: Primitive Support

Last post, I showed a canonical example for the Dependency Elimination Principle. I want to show another Dependency Elimination example that solves another common pattern I see. I've given this pattern a name: Primitive Support.

Introducing: Primitive Support

Primitive Support is the natural outworking of the Code Smell called Primitive Obsession. Our code suffers from Primitive Support when it has these two parts:

  1. A primitive type (int, string, etc) representing a domain concept (megabytes, phone number, etc).
  2. A helper class that does something meaningful with that primitive (e.g. MegabyteConverter or PhoneNumberParser or FooHelper).

If we have classes named similar to MegabyteConverter or PhoneNumberParser or FooHelper, we might be suffering from Primitive Support. Now let's look at an example.

A Simple Example: E-mail Address Validation

Let's say we're working on a user signup experience. A valid e-mail address is required for new users. We need our API to enforce that the e-mail address is valid. One way we might do this is like the below1:

This is actually pretty good as is. It's relatively easy to test and easy to read. There is, however, a lack of cohesion. First, UserSignup is worrying about validating e-mails when it really should just sign up the user. Second, email validation is off on its own in a general EmailHelper class. We will improve this soon, but first we'll take a detour in the wrong direction.

A Slight Rant

Unfortunately, some of the SOLID and TDD literature will lead you away from this design towards a more complicated design. In the name of separating concerns (good), standard practice will tell you to extract e-mail validation to its own concern and pass it as an interface to UserSignup (less good). Similar to this:

Now we have an IEmailValidator and an EmailValidator to separate the validation concern. To test UserSignup, we'll mock IEmailValidator and make sure it's called with the given emailAddress. Standard unit testing practice.

Testable, But Complicated

Let's evaluate the code. It's testable. We've separated our concerns. But it's more complicated. And we still have a cohesion problem: Email address validation is still a concern of UserSignup, and the validation implementation lives in its own EmailValidator world. We can do better than this.

Address the Root Cause: Kill the Primitive

The fundamental problem is that our system cares about e-mail addresses, but it doesn't represent e-mail addresses as first class citizens. We've split the e-mail address concern across UserSignup and EmailValidator. To fix this cohesion problem, we need to stop using string for e-mail addresses and start using EmailAddress for e-mail addresses. Watch how the complexity melts away:

First, note two important pieces:

  1. EmailAddress is a new type that is now a Whole Value for e-mails.
  2. The EmailAddress constructor throws when it is invalid. This makes it impossible to create an invalid e-mail address.

Now, note the supreme wins we get from this approach:

  1. We've completely separated the concerns. UserSignup has no validation calls or implementations. It just uses an EmailAddress like it should.
  2. We've improved cohesion. E-maily things live on EmailAddress. UserSignupy things live on UserSignup. No overlap.
  3. EmailAddress validation is now a compile-time concern. You can't make a bad one, so type-checking will guarantee that the thing you pass in is valid2.

What We Learned

Code with Primitive Obsession will usually lead to Primitive Support: introducing dependencies to do meaningful things on primitives. We can eliminate these dependencies by replacing the primitive with a Whole Value for the concept it represents. The supporting dependencies go away, the code is more clear, and the compiler catches bugs for us. Wins all around!




Footnotes

1Note: you might do this more simply via your library/framework validation system, but I'm leaving those out of this conversation for educational purposes.

2I know, I know we can still technically pass null. But if null makes it this far into our system we have bigger problems.

Monday, February 9, 2015

The Dependency Elimination Principle: A Canonical Example

There's been quite a bit of discussion so far on the Dependency Elimination Principle. One thing obviously missing from my posts is a code example. This example illustrates a common class of unnecessary dependencies.

I'll use application configuration as the example. I'll uncreatively title the class of unnecessary dependencies: "The thing that gets the thing you need". And I'll uncreatively title the remedy to this problem: "Pass the thing you need, not the thing that gets the thing you need".

The config example


Most applications we write have a configuration defined via some XML or JSON file sitting near the executing code.  We want to keep the system modular and testable so we make sure the application code doesn't depend directly on this configuration file.  A common way we implement this looks similar to this:

Then when one of our application classes needs a value from the application's configuration, we give it a dependency on IConfigurationReader and let it read a config value in one of its methods. For this example, let's make a class that generates invoices. We have multiple environments and don't want to mistake test invoices for real ones. So we decide to put a watermark on invoices generated outside of production. One way to accomplish this would be to create a "invoiceWatermarkText" config setting that is set in test/staging and not set in production. Here's what this might look like:

This is SOLID, decoupled code. InvoiceGenerator rightly doesn't know about the details of how configuration works. And it's testable because you can stub out the configuration reader. However, there are still problems.

Loose coupling is still coupling


Although InvoiceGenerator doesn't know about how configuration works, it still has to know there is such a thing as configuration. This makes things more complicated. When you test, you have to provide a stub. And when you create an InvoiceGenerator in the production code, you have to provide a real configuration. InvoiceGenerator is still coupled to configuration, thus making it impossible to use it without supplying some sort of configuration reader.

Eliminate the coupling


We can improve this with a simple fix: Pass the thing we need (the watermark text), not the thing that gets the thing we need (the IConfigurationReader). It will look something like this:

Now we can painlessly use an InvoiceGenerator literally anywhere in any application. And there's less to think about when reasoning about it.

But...we still need the config part


You're probably wondering, "Ok, so I still need to read that text from config to give it to the InvoiceGenerator. Where does that code go?". You have a couple options here:
  • Just read it from config on the line that is calling GenerateInvoice
  • Create a one-line overload to GenerateInvoice that reads from the real configuration reader.  No need to test that line.

Wrapping it all up


We often introduce a dependency so we can get the thing we need.  However, we usually only need the thing we need.  So we pass the thing we need, not the thing that gets the thing we need.