RubyConf 2012 keynote about how the communication pattern within your team impacts the code you write.
I'm very happy to be here this morning. I submitted this talk, seems like a long time ago now, when the RubyConf call for
papers was open. After I submitted it, I thought, “Yeah...they’re not going take that.” Mostly because the abstract I wrote for the
conference proposal was essentially a rant.
But what I had forgotten, of course, was....
...that no one likes a rant better than Rubyists do. With the possible exception of the major political parties this close to the
But don’t worry, after Tuesday we’ll be back on top.
I was still surprised, though, a few weeks after they accepted the talk, when Evan Phoenix asked me if he could make this talk
a plenary session.
I did have to look up what "plenary session" meant. But I was super excited when he asked, because I love RubyConf. I love
you guys!!! This is my fourth RubyConf, and every time I come I have a marvelous time, I meet awesome people, I learn all
the things, and it’s great. So I am thrilled that I have tricked Evan into giving me this hour to rant in front of you.
And I did trick him - because, despite the abstract, this talk contains absolutely no ranting whatsoever.
What I want to talk about today is the set of factors that affect whether or not we write good code.
No one writes good code all the time. Ah, present company excepted, of course. And the factors that go into whether or not
the code we write is good at any particular time - there’s a lot of them. And it’s complicated.
Now - I like to write good code. I could say that it makes me happy to deliver business value, or it makes me happy to create a
product, and those things are somewhat true. But really - I like to write good code just because good code makes me happy.
This picture makes me pretty happy, too, because clearly, this middle developer in this picture has just gone into code she
wrote two months ago and finished a very satisfying refactoring.
So for me - code makes me happy when I can understand it two months after I wrote it. Code makes me happy when it’s easy
to read, easy to use, and easy to modify.
But I don’t always feel like that. I want to feel like that more. I want to write good code more of the time. And that’s what this
talk is about. Maybe I should have retitled it,
And maybe I should have, actually, because that sounds even more rant-like.
Anyway - that’s what we’re going to talk about.
Now I started research for this talk by looking into how other people define “good code.” Personally, I like my defintion, but it is
subjective. It’s qualitative. So I wanted to see if there was a quantitative way to evaluate the quality of code.
And helpfully, academia has been working hard for like forty years to get a more quantiﬁed deﬁnition of good
code. And it turns out that good code is computable.
In other words, it is possible for a computer to take two pieces of code, and grade them against each other, and
say which one most developers will think is BETTER.
It’s a very complex computation. The one thing that is useful for us out of it is that good code is deﬁned by its
pattern of dependencies.
So. Let’s look brieﬂy at what a dependency is and how we incur them.
@stuff = Stuff.find(params[:id]
Here some code that many of us have written. This is a Rails controller with a show action, and on line 3 we incur
two dependencies. First, we depend on the Stuff model existing, and second, we depend on the Stuff model
having a class method called “ﬁnd.”
Dependencies are important because the dependencies in a project dictate whether or not code is easy to change.
Let me explain a little more what I mean by that.
Here’s a conceptual diagram of a Thing that lot of other modules depend on, so A, B, C, X, Y, and Z all depend on
Thing. This code is said to be tightly coupled to Thing, because if it changes, then potentially, all the modules that
depend on it also have to change. And then all the modules that depend on those have to change, and that’s how
we end up with a codebase where changing code breaks something far away that seems unrelated.
Now I should point out that not all dependencies are equal.
This is a piece of the Pont du Gard aquaduct in France. It was built by the Romans in the 1st century AD, which is almost 2000
years ago. There are many interesting features on this bridge, but one of them is that it was mostly built without mortar. The
stones in those arches are not cemented together. Their weight, and the physics of arch structures, keep them in place. So -
this bridge has incurred a dependency - on gravity.
So if the way gravity works changes, this bridge will need some refactoring.
But given how often gravity changes, the Romans probably made the right decision when they tightly coupled their bridge to
the force of gravity.
So coming back to our software example, depending on things that don’t change very often, such as pieces of
your framework (hopefully), is safer then depending on things that change more often.
The PM has
this part of
our app actually
This, for example, will only cause you pain.
Good code is deﬁned
by its pattern of
So the key to keep in mind here is that good code is deﬁned by its pattern of dependencies. And that seems to
work equally well whether it’s a computer or a person deciding whether the code is good.
Right now, since we have a computable deﬁnition for good code - though I personally still like mine better - let’s
back up and take a look at the factors that affect whether or not a particular person will write good code.
1. OO design principles
One important factor, for sure, is their knowledge of object-oriented design principles. There have been several awesome talks
about object design, actually, during RubyConf so far. Knowing about OO design means both knowing the actual principles,
such as SOLID, the Law of Demeter, and so forth, as well as knowing when it is appropriate to use the principles. And certainly
people do write good code without knowing all of the principles. But in general if you want to write good code in an object-
oriented language like Ruby, these things are quite useful, and worth studying. At their core, all of these object-oriented design
principles are advice on how to manage your dependencies so that you end up with good code.
Let’s look at the Law of Demeter for a moment so you can see what I mean.
Law of Demeter
The Law of Demeter says, in its very brief form, that if you have an object, it’s ﬁne to call methods on it directly,
but if you start chaining methods you should think about whether there’s a way to get the information you need
And the reason is that the second line incurs a single dependency, but the third line incurs a whole chain of them,
and if any of those things changes, including the intermediate ones that we’re not interested in, this code might
So the Law of Demeter helps you avoid the far-reaching dependencies that characterize bad code. And if you
analyze other OO design principles you’ll ﬁnd that they’re pretty much all little patterns that help you incur the
right kind of dependencies in your code.
Now if all this talk of “design principles” is a little too abstract, or if you just want to brush up,
1. OO design principles
2. Development practices
Book cover copyright Addison Wesley
There’s a fantastic book that came out recently - Sandi Metz’s book Practical Object-Oriented Design in Ruby. This helped me
see object design differently, and is very, very concrete. Highly recommend.
So - knowledge of object-oriented deisgn is ONE factor that affects whether or not we write good code. Another big factor is
the development practices that we follow. Over the last 15 or 20 years, we as an industry have decided that we write better
code when we use agile development practices. Now that’s small-a agile - not any particular flavor of it, but in general -
focusing on the user of the system, and keeping feedback loops as tight as possible. Test-driven development falls into this
category, as well as pair programming, fine-grained user stories, all that stuff. You need to pick the ones that work for you.
Now I suppose those two factors are fairly obvious, and easy to identify. They are the ones we focus on when we’re trying to
improve the quality of our code. Because there’s always another screencast about object design, and there’s always another
blog post about agile.
But there’s a third factor that affects the quality of our code, that we typically we don’t think much about in this context, but it
actually has the biggest impact overall on the quality of our code. And that factor is, of course, other people.
Because to build anything interesting, you do, usually, have to work on a team. And in a team of this size - seven
people, probably about average - just by the numbers, a single person will personally write less than half of the
code in the project. Probably signiﬁcantly less than half. Most of the code you encounter every day will have been
written by someone else.
So in some sense, if you want to work with good code and write good code, you and your team sink or swim
Now the team itself is more than just the individuals that compose it. It’s also the communication patterns between
Now that’s an interesting thing. Because while you can’t affect the other individuals very much, one person can
have a huge impact on how communication works within the group.
And it’s been my gut instinct for a while now that it’s the communication patterns in the group, rather than the
individuals within it, that determine whether or not they produce good code together. So I set out to see if science
could help me conﬁrm or deny.
One of the difficulties in studying this type of thing is that the communication patterns within a team are often not
as obvious as the arrows on this diagram.
Formal lines of communication, such as manager-report, are easy to see, and to visualize.
But informal communication, which science tells us is more powerful within the workplace, is very hard to see.
I like this quote that Jim put up yesterday, so I’m going to put it up again.
The aspects of things that
are most important to us
are hidden because of their
simplicity and familiarity.
Formal communication is when you’re just talking about work and usually occurs at work. Informal
communication includes things like chatting in the kitchen or on campﬁre, going out for lunch, and having drinks.
Emails and conversations can include both types and may switch back and forth rapidly.
Informal lines of commuication are ad-hoc and ﬂuid. They’re constantly changing, and they are largely invisible to
But if you can’t see it, you can’t measure it, you can’t diagram it,... how do you know if it’s good or bad? And how
can you improve it?
To answer that question, we have to go BACK IN TIME... to 1968.
In 1968, the hippies were drifting towards Golden Gate Park to hang out and stare at the trees, and computer labs looked like
A computer scientist named Melvin Conway wrote a paper called "How Do Committees Invent?" which is now - I”ll save you
the arithmatic - 44 years old, and definitely still worth reading. In the paper, he outlined Conway's Law, which says:
Any organization that designs
a system will inevitably
produce a design whose
structure is a copy of the
Text of paper: http://bit.ly/RrHWvp
It’s a bit of a mouthful, so I kind of like the way Eric Raymond restated it -
If you have four groups
working on a compiler, you’ll
get a four-pass compiler.
Now over the years many people have interpreted this as kind of funny, and not quite serious, perhaps in the same vein as
And so many people have looked at Conway's Law and thought about it as the computer science equivalent of "people look
like their dogs."
But it's actually quite serious, and useful. One Conway’s most interesting examples from the paper is from a joint software
project between Army and the Navy.
Here's what their team structure looked like. They had a set of coordinators, and then they had a group from the army, and
they had a group from the navy. The software that they produced looked like this. They had a group of common functions, and
then they had an army-specific module, and they had a navy-specific module. They built software whose structure was
identical to the communication patterns of the teams that produced it.
When I read that, I thought, “huh. that’s interesting.” But I wasn’t completely convinced that it was still relevant, A, because
people came up with some crazy stuff in the 60s, B, it’s over 40 years old and computing was a different thng back then, and
C, I wasn’t entirely sure that something that applied to the military would necessarily apply to the kinds of smaller, less-formal
organizations that we find ourselves in today.
But then I thought back over the jobs I’ve had....and I realized that several of them provided me with perfect object lessons in
Conway’s Law. I used work in a big company once...
Not this one actually, but our campus looked kinda similar.
The project I was on was new & innovative, and the team was actually amazing. We had a few people who had been around
since the starting days of the company and had built some of its larger products, we had people who wrote books about
programming. I mean - we even had the guy who wrote Freecell.
So I ask you - HOW COULD WE POSSIBLY FAIL??
At first, things were great!
My first day, they gave me a copy of this book. Now, at the time, Code Complete was pretty cutting-edge. It’s still pretty good,
and I recommend it if you haven’t read it. Don't let this, ah, put you off too much.
So it started well but as we got going we found ourselves really struggling.
It felt kinda like this. We each had a piece of the project to work on, and once the pieces were “finished,” we started the
“integration” phase and try to get our pieces to talk to each other. If you’d like to know how that integration phase went, you
may refer again to the above diagram. Months of unbudgeted work. And trying to get these interfaces to line up required hacky
changes to the internals of these components, which we did quickly because we weren’t supposed to be spending that time at
And the whole thing felt terrible. I knew I wasn't doing good work. But I didn’t understand how we had gotten to that place.
And for years after that experience, after I had left the company even, I wondered: how did our code get so bad? We were
smart, well-intentioned, knowledgable developers, but looking at our output - you really wouldn't have known.
How did we manage to build modules that completely failed to talk to each other?
This was the first time I saw Conway’s Law in action, because we - the developers - didn’t talk to each other. The company
...that every developer should have an office, an individual office, with a door that closed. And they also weren’t big on
meetings. Now this sounded great to me, before I joined - because it sounded like I'd have lots of time to focus. And I did - I
spent a lot of time in that flow state, being super productive, and completely focused.
Sadly, I was usually focused on the wrong things. Now, I thought they were the right things. Certainly last time I’d talked to
anyone, they were. This culture feels like a bizarro other world - because it’s so different from what I do now - but I could go
entire days without talking to any of my coworkers, except maybe awkwardly passing them in the hallway.
We had one or mayyybe two meetings a week, and those were the only times we really talked to each other face-to-face. We
wrote a lot of email, but of course it was easy to misunderstand. So in the end,
The developers who didn’t talk to each other built modules that couldn’t talk to each other. We built a copy of our dysfunctional
Another project I was on, more recently but before I joined Pivotal, was another priceless example of Conway’s Law in action.
This was a small company...
...whose hiring philosophy for developers was to get really smart people from top schools, and then let them do whatever they
wanted. There were eight developers.
Their application had a service-oriented architecture consisting of eight services…
…written in eight different languages.
Now that’s clearly that’s a pathological case, but really, I wanted to show you that Conway’s Law, despite being 44
years old, is in effect today in organizations of all sizes. Even, probably, the organizations that you’re a part of.
And it’s really obvious at the architectural level. Conway’s Law says that organizations draw technical boundaries
where the team boundaries already exist. But what we’re interested in, is what happens inside one of those teams?
Well as it turns out, there was a paper in 2007 from Carnegie Mellon, where researchers studied exactly that. They
took Conway’s Law as a given, and looked at what happens inside one of these architectural boundaries.
Good Code Predictors
• Technical qualiﬁcations
• Experience with the code base
• Good communication
Specifically, they were trying to figure out what characteristics of a team led that team to produce good code.
They found a bunch of characteristics that mattered, as you might expect, including the technical qualifications of the
individuals - makes sense, a team where the individuals have some experience with the technology will do better.
Another significant factor - their previous experience with the code in question. That also makes sense, right? If you’ve seen
the code before, you’re familiar with its patterns and can more reliably put things in the right place.
But the strongest predictor of good code out of a team was good communication between the team members.
patterns are the best
predictor of the
quality of the code
So here’s the ﬁrst thing I want you to remember.
Now this is fascinating. A, because it’s pretty awesome to have science back up my gut instinct, and B, because if good
communication leads to good code and bad communication leads to bad code, then...that sounds a lot like the code reflecting
the communication structure. Conway’s Law is fractal.
It's most visible at the architecture level, where we see technical boundaries forming along the team boundaries.
But it’s also reflected, in a more obscured way, inside a single codebase.
It is definitely less obvious. At the macro level, you can look at the organization, and match it up with the software they
produce. At the micro level, the structure it’s reflecting is less visible, so you can’t start there and look for mirrored structures in
But - you can go the other direction. You can start with the code, and let it tell you things about your communicaiton.
Let’s look at a really simple example.
I came on to a Rails project once where the view helpers were cartoonishly enormous. Dozens of ﬁles, hundreds of
methods in some of them. They were all included in all the controllers and all the views, and it was horrendous.
Now I was going to just dive in and start factoring out the stuff that didn’t belong. But before I got started, I got
curious. Why would anyone do this?
So I poked around a little bit, and I discovered that they had an absentee architect. They called him the seagull
architect, because he’d ﬂy in, crap on everything, and ﬂy off. One of the pearls of wisdom he had dropped was
“thou shalt not put things in the lib directory.”
Now...I appreciate the sentiment, actually, because for a long time I thought of Rails’ lib directory as every app’s
And these guys had taken the architect at his word - lib was nice and tidy. But they’d just moved the junk drawer
into the view helpers.
I learned two things:
First: that I needed a way to make the seagull architect less disruptive.
Second: we had a rule of thumb that was generally good, but needed more context and explanation as the
developers who were using it gained more experience.
I let the bad code point me towards the communication issues that had caused it.
Let’s look at another, more concrete, example.
class Stuff < ActiveRecord::Base
Here's a piece of code from a completely different project, and I would characterize it as slightly smelly. We have a Rails
model that is including the URL helpers so that it can put its URL into its as_json method. Now this is *not* how you actually
include the URL helpers, but it doesn’t matter because you shouldn't be doing it anyway.
Now when I came across this code, at first glance, it was a simple object design problem. This code violates the single
responsibility principle, which means, it does more than one thing. Models are for persistence-related code - that's their main
purpose. But this stuff has nothing to do with persistence.
So, what that means is that there's probably another object trying to get out here, maybe a presenter of some sort, like this.
class Stuff < ActiveRecord::Base
class StuffPresenter < Presenter
That's a pretty straightforward refactoring, uncontroversial these days. The objects would be better factored, and in general
we’d be improving the quality of the code.
But before we actually do the refactoring, it's worth asking - is there anything else we can learn from here? Let’s go back and
look at the code.
class Stuff < ActiveRecord::Base
Well, this code came from one of my former teams, and I learned two things actually from looking at it.
The first thing was that the presenter pattern hadn't made it far enough out of my head. In this codebase I already had
introduced presenters for other models, but it was a big enough team that obviously not everyone had seen them. I hadn’t
communicated that decision effectively.
The second thing I learned was that some of the developers on my project were ready to hear the more nuanced version of
“Skinny Controllers, Fat Models.”
Let me explain a little bit what I mean by that. The developers who wrote this code had been programmers for a long time, but
had only been doing Ruby and Rails for a few months. One of the things we talked about was “don’t put model-related logic in
the controllers." Right? Skinny controllers, fat models. And they had done that, which is awesome. Because they totally could
have put this code in the controller...
class StuffController < AppContro
like this. But they had listened, so they moved it to the model. So the second thing I learned was that instead of giving them
the short version of this rule of thumb...
Skinny controllers, fat models
Skinny controllers, models that
only have code related to their
main purpose: persistance.
Move other stuff out to non-
I should be telling them the long version.
Yeah. I guess that last one doesn’t roll off the tongue quite as easily as the ﬁrst one.
Decoding Smelly Code
1. Hidden silo
2. Developers ready for more nuance
2.1. Developers actually listen to me o.0
So looking at this "software design problem" and really digging under it showed me two specific problems in my team's
communication structure that I didn't know we had - the hidden silo, and the new threshold.
And as a corollary to that, I also discovered that other developers actually listen to me! That might be the most amazing thing
We used Conway’s Law in reverse, to let this code smell shed light on our otherwise-mostly-invisible communication structure.
And what we got back was really valuable. If I tell everyone about presenters, and I revisit where you put model logic, then I
address the root of those code problems. Whereas, if I had just refactored the code, I would have just fixed the symptoms.
Over time, fixing the code AND fixing the communication difficulties that the code helps you identify pays way more dividends
than just fixing the code.
Or in short -
Every piece of bad
code is trying to
tell you something.
Every piece of bad code is trying to tell you somethng. When you figure out what it is - fix that. Because fixing those
communication problems increases the quality of the code that all of you write.
Now ﬁnally, I’d like to put the last piece of this puzzle together, and talk about how you ﬁx communication
I’ve been at Pivotal Labs for almost three years. If you aren’t familiar with our process, we do all pair
Photo copyright Pivotal Labs
Pair programming turns actually writing code into an act of communication. It means I sit with someone, all day,
and we talk about the code we’re writing. It’s actually really fun.
So for almost three years, minus vacation and holidays, I’ve been pairing eight hours a day, ﬁve days a week.
And in that time I have become the carpenter who has any tool you want, as long as it’s a hammer.
My hammer of course is pair programming. And a lot of these communication problems sure look like nails.
Now I did SAY that I wasn’t going to rant.
But why is it...
why is it that some developers are so rabidly opposed to pair programming? I mean, leaving aside whether or not
it’s effective, since there are have been loads of studies conﬁrming that. I mean, why is it that some developers
just don’t want to do it?
And what I think is that they don’t want to do it because they don’t know how to talk to people and they think it
will be awkward. And I think that because I thought that before I started doing it. But, I have some news for you:
you are a human being. And learning how to talk to other human beings is a skill that you should learn.
Easily talking to people is not a talent that you either have or do not have. It is not. It is a skill that you can learn,
and get better at. And I think you’ll ﬁnd that spending your day talking to another developer is signiﬁcantly easier
than spending that time talking to a normal person. But - the practice still counts!
About 3 months after I started at Pivotal, I went to an alumni event for my university where there were normal
people. And I was shocked to discover that I could make small talk with them, which I’d never really been able to
do before. And not only that - I was pretty good at it. I asked them questions about themselves, kept the
conversation going...I went home that night and I sat down and I said, what just happened? Am I becoming an
Now I won’t tell you it’s not difficult. It is exhausting at ﬁrst to spend all your time talking. The ﬁrst few months I
was at Pivotal, I was so exhausted that I really don’t have clear memories of that time. The only other time in my
life I’ve been like that is after I had a baby.
So, it is hard. But it is worth doing. No matter how awkward you are now, you can learn to talk to people. Because
that skill, that ability to connect with people, is what makes us human.
And that’s all I have to say about that. (breath) Ok, We’re back on script. So!
• Pair programming
So the ﬁrst thing I’m going to tell you is that if you are really serious about increasing communication among your
team, pair programming - even ad hoc, even part time, even temporarily - is a very efficient way to get you all to
talk to each other more.
There are, of course, other ways to get people talking so let’s go through them. The ﬁrst one is create
opportunities for informal communication.
Create opportunities for informal communication
Photo copyright Pivotal Labs
Science tells us that informal and accidental communication are critical parts of your team’s structure. People need to have
opportunities to have conversations with people that aren’t totally about code.
There are lots of ways to create this space. One of the most effective is to sit together in the same place. You overhear each
other talking about what you're working on, and can contribute if there's something you know about. This works for distributed
teams too, via campfire room, irc channel, google hangouts….any number of options.
Another way is to create a space in your office for people to relax. Sometimes it's as easy as bringing in a couch to the office,
or a buying a fancy coffee machine that people have to show each other how to use. Look for ways to bring up the ambient
communication in your work space.
Deliberatly use high-bandwidth communication when you need to talk to someone. Face-to-face is still way higher-bandwidth
than any other form of communication we have. You get lots of meta-information, along with the actual information - meaning
the body language, the facial expressions - which in this picture I love, because they’re so goofy - the voice intonation, and so
on. If face-to-face isn't an option, then in descending order, of usefulness, we have facetime/skype/google hangouts, phone,
IM, tracker comments, email, ...carrier pigeon. I don’t really recommend those last three if you can avoid them.
Keep in mind that communicating easily with people is not a talent that you either have, or do not have. It’s a skill
that you can learn, and practice, and get better at.
• Pair programming
• Create opportunities for informal
• Use high-bandwidth communication
Now one thing I will say about these is that you will have the most impact if you’re a team lead, but they’re still
effective if you’re not a lead or a manager.
I don't know how many of you ever read Dear Abby - as a kid, we had these things called newspapers that showed up at our
house every day.
And Dear Abby was the one thing I read in the newspaper every day, long after I decided that funnies were a waste of time.
Dear Abby is an advice column, and people wrote in, usually asking advice about problems in their marriage, and Abby's
advice to those folks was remarkably consistent: go to couples' counseling. If your partner won't go with you, go by yourself.
Now that sounds weird, to go couples' counseling alone. But Abby knew that learning communication techniques and taking
them back home often improved the relationship, even though only one person was going to counseling.
And these communication techniques are very similar - you can do them yourself, and both you and the rest of the team
Hack your team
So. The last thing I want you to remember, is hack your team! You have more power than you realize. A single
person has remarkable power over the structure of communication within a team.
• Think about team
• Use code smells to
• Fix them!
So go forth! Do these things!
If you do, I think you’ll ﬁnd you’ll spend more of your time writing good code. And I hope that makes you as
happy as it makes me.
Thank you very much.