6 effective ways to deal with Brooks’ Law

Frederick Brooks wrote in The Mythical Man Month that “adding manpower to a late software project makes it later”. This is also known as Brooks’ Law. One of the reasons for this is that each time you add more people to a project, the communication overhead increases.

Here’s why: Imagine your entire team needs to work on a new feature. To be able to work on that feature, they need to understand what to build and how to coordinate building it. This requires sharing context. When you have a team of one, that team member does not have to communicate with any other team members. When you have a team of three, there are three people that need to coordinate. But if you increase the team to eight people, there are twenty-eight paths of communication to make to coordinate work. This image from a stackoverflow post explains the concept well:

"Communication Overhead"

Obviously there are advantages to having teams larger than one, otherwise every team would be a team of one. A team of one has to wear many hats. For example, a developer will have to gather requirements if a product manager is not doing it on their behalf. That might make sense sometimes, but any time spent gathering requirements is time not spent developing. It almost always takes more time to develop features than to gather their requirements and not everyone can develop. Therefore, the team as a whole would produce more if the developer(s) could spend their full day developing.

There’s also the issue with the bus factor. If a team of one quits or gets sick, progress abruptly stops. If there are multiple developers with a shared context, the others can fill the role of the absentee.

So how do you know when a team is too large and should be split? That’s not an easy question to answer. Obviously if developers are spending more time communicating than developing, the team (or its boundaries) are too large and should be split. And if the communication overhead negates the benefits of a larger bus factor number, the team should be split.

I don’t have better heuristics than this, I’d like to hear your ideas. But, I do have some suggestions on reducing the cost of the communication overhead.

Clear goals and requirements are a must for the project. For example, each developer should know “why” they’re building the feature they’re building. If they don’t, they can’t read between the lines when requirements are vague. They’re going to have to communicate more to get clarification. Or, they’ll end up building the wrong thing and have to communicate more to build the correct thing later.

It helps if the team is working on a complete bounded context. If you’re unfamiliar with the phrase, that article should help and so should this image:

"Bounded Context"

Imagine your project encompasses two bounded contexts like the image demonstrates. You’re going to frequently need to clarify which “Customer” and “Product” you’re referring to. That’s going to slow down communication.

It’s also important for the team to own a complete bounded context. If team X owns half of the Sales Context and team Y owns the other half, they’re frequently going to step on each others toes. Coordination will require a lot of inter team communication. This should also be considered when you’re thinking about how to divide a team that’s too large.

Another way to reduce communication overhead is to come up with a ubiquitous language. This means that when you’re working in the Sales Context, everyone is on the same page as to what a “Customer” is. This also means that the team agrees it’s called a “Customer” at all times. It’s not called a “User”, “Guest”, or “Patron” sometimes. This agreement will reduce the time it takes to communicate concepts. To learn more about Bounded Contexts and Ubiquitous Language, you should read Domain Driven Design.

Communication can be greatly reduced if there’s a communication gateway: A person where a lot of communication flows through so that everybody doesn’t need to communicate with everybody else. For example, if the Product Manager is the “requirements master” and that’s known to the team, I don’t need to ask the rest of the team for clarification of requirements. I can just go directly to the PM. I wrote more about this in my article titled, A Good PM is a Communication Gateway.

Last and least, if everyone has a high level of skill, the need to communicate is reduced. Imagine a new team member joins that doesn’t even know how to use the programming language of the project. A lot of communication will be required to catch that person up to speed.

Pair programming makes interruptions tolerable

Every programmer knows that interruptions are frustrating because it lowers their productivity. But now, there’s empirical evidence showing this:

Game Developer Magazine analyzed 10,000 programming sessions recorded from 86 programmers using Eclipse and Visual Studio, and surveyed 414 programmers, and discovered that a programmer needs up to 15 minutes to start editing code again following an interruption.

Unfortunately, managers don’t always realize the way these interruptions affect developers. In a manager’s mind, there’s one less thing on their plate when they communicate it to a developer. A more effective form of communication would be to write down the thought and talk to the developer in a scheduled meeting. If there were some way to avoid interruptions, that would be ideal.

But some interruptions are unavoidable. When you do feel like you’re being interrupted too frequently, pair programming can be a way to offset the damage caused by these interruptions. Here’s why:

If you’re soloing and someone interrupts you, 100% of your context is lost. You have to shift gears to deal with the interruption alone. But if you’re working as a pair and someone interrupts you, you can choose to split the pair and only let one of the people get interrupted. Meanwhile, the other person continues working on what they’re working on with 100% of the context. When the pair reforms, the one that stuck will fill in the context for the one that left.

If both pairs choose to be interrupted, pair programming helps with that situation, too. Pairs are more resilient to the context switching cost. As soon as the pair gets back to work, one of them will ask, “What were we working on?” and they’ll each remember a piece of the context so they can get back to their work faster. There are social pressures that prevent one of them from reading email or checking Facebook before they continue with their work. When you solo, those social pressures aren’t there.

Another reason pair programming helps with interruptions is that people are less likely to interrupt an active collaboration. This is more likely to be true in an environment where only some people pair. All things being equal, do you interrupt? The people in the middle of a conversation or the person who’s sitting alone by their desk?

Interruptions kill productivity but they’re also a fact of life. Pair programming should be considered as a tool that can be used to reduce the negative affects of these interruptions.

An in depth guide to the Extreme Single Responsibility Principle

Note: This is a more in depth look at an article I previously wrote titled, Intro to the Extreme Single Responsibility Principle. The previous article is not a prerequisite.

I’m going to talk about a technique I picked up that I’ve never seen done anywhere except for where I currently work. Because I’ve been programming professionally for over a decade and this is the first time I’ve seen this, I figure it must be relatively unfamiliar to others. This is a technique I’ve been calling “Extreme SRP”. But before I explain what the Extreme version of SRP is, I should explain what SRP is:

SRP stands for the Single Responsibility Principle. It means that a class should only have one reason to change. If you want to learn more, this link is a good reference.

Extreme SRP, surprisingly enough, is taking SRP to the extreme. Before I talk about what it is, I want to preface the description with a suggestion: Keep an open mind. When I first saw this technique my immediate thought was, “That’s not idiomatic”. But, I went with it to see how it’d turn out. In the end I had few complaints but I thought I would have many. It’s easy to think, “That looks weird so it must be bad” but unless you try it, you don’t really know if that’s true.

Extreme SRP converts your code base to look like a tree of nodes and leafs. A leaf contains the “meat” of your feature. It’s where your code actually does something. A node, on the other hand, merely delegates to other nodes and leaves. It never has any “meat” in it. Visually, here’s how the nodes and leaves look:

Tree

Note that the tree in the image also has arrows. These are nodes calling other nodes/leaves. When these calls occur, “data” is passed from a node to a node/leaf and “data” is returned by the call. So far this description is probably a little vague, so here’s a code example to make things a little more concrete:

With this example in mind, I’m going to describe Extreme SRP with a set of rules. Here are the rules for nodes and leafs:

  1. Every class can only have one method.
  2. That method must be public.
  3. Every field of the class must be dependency injected.

Here are the rules for data:

  1. There must be no logic.
  2. It must be possible to get each field.
  3. It must be possible to set each field.

Here’s how that OutputData class might be defined:

Lets look at another example. Here’s some code that changes a user’s email address written in the Extreme SRP style:

This class does not know if it’s delegating to nodes or leafs, but it does not have any logic in it besides delegating. That’s how you can tell it’s a node. I would imagine the EmailAddressChanger is a leaf. It probably creates a new User that’s a copy of the input but with a different email address. That logic is “meat”, not delegation. So that class would be a leaf. And the User class itself is data. It only has fields and no logic.

Now lets look at the pros and cons of this style of programming:

“Extreme SRP” has all the advantages of SRP:

  • Code complexity is reduced by being more explicit and straightforward
  • Loose coupling
  • Improved readability

The methods are very small and easy to understand. But, if you’re looking for a specific leaf and you don’t know its name, you have to traverse the tree to get there. Using traditional object oriented techniques, this code would often be inlined into one place so it would be easier to find. This is one of the downsides you have to live with when you practice “Extreme SRP”. But this cost brings the benefits mentioned above.

This code is not very idiomatic, at least for most object oriented languages. It’s more procedural/functional in nature. But because of the rule above that says every field must be dependency injected, the entire code base is extremely easy to test. The non-idiomatic code threw me off originally, but the ease of testability makes it worth it, in my opinion.

Wouldn’t it be better to just use a functional language for this instead of an object oriented one? A lot of functional programming concepts are in vogue right now and this technique comes to terms with that. Yes, a functional programming language would be better, but that’s not always an option. If you have to maintain a large legacy code base, you usually don’t get the luxury of rewriting it in a new language: You have to gradually refactor it and add new features. In my experience, an Extreme SRP code base is easier to maintain than a traditional object oriented one. So if you have to use an object oriented programming language, you should consider writing your code in the Extreme SRP style.

But, why not just use functions? If your language makes it convenient to write pure functions, by all means use them instead. But if your language doesn’t make that easy, I prefer the Extreme SRP style because it has code seams (the classes and the calls between them) to make everything unit testable. When your leafs have side effects, it’s good to have a way to mock out the side effects when you’re testing other parts of your system. This isn’t always easy to do with impure functions and Extreme SRP can be thought of as an alternative way of achieving this important testability.

The way you go about creating a system like this from start to finish has a lot of advantages. You think about a node and what it directly delegates to instead of the whole tree at once. How you go about thinking this was is documented in another article I wrote. But to summarize the idea behind this, look at the ChangeUserEmailAddress class. When that class was created, you didn’t have to think about the implementation details of finding a user, changing its email address, and saving it back into the database. You just delegate to classes that have that as their sole responsibilities. Then you focus on the implementation details of one at a time. As long as the plumbing of the method signatures hook up, you can thinking about how to implement how to save a user before you’ve thought about how to find a user. This is a useful way to deal with complexity: Divide and conquer.

There are no cyclical dependencies where A depends on B and B depends on A. This simplifies a lot in your code base and makes it easier to modularize your code. The code base requires minimal refactoring. Usually I can throw away a node and rewrite it instead of refactoring it into what I want. Or I simply have to connect one node to a different one, etc. Whereas using traditional object oriented techniques, refactoring feels built in to the process and is the first and last step of adding a new feature.

This technique does create an explosion of classes and you have to come up with names for all of them. It’s not always easy but whenever I struggle with this I feel like there is a concept that needs to be named, I just can’t think of the name for it. It’s rarely a situation where the rules are forcing me to think in unnatural ways.

Because of this class explosion, you have to be really good with your namespaces to organize your code. Otherwise, you’ll get lost and it’ll slow you down to browse your code base.

Other than that, I’m really happy with “Extreme SRP”. I recommend that readers put their biases aside and give it a try on your next hobby project and see how it turns out for you. I’d love to hear your feedback on how it turned out!

5 simple ways to plan better deadlines

I’ve been programming for more than a decade and what seems to be a sore point for other software engineers is deadlines. This can be because a Product Manager set an unrealistic deadline in the past and they had to go on a death march to deliver. If you’re a Product Manager, these tips should help you set better deadlines in the future:

Avoid them completely

If you can avoid a deadline all together, that can be ideal. Instead of a deadline you can establish the most important thing to work on next, work on that until it’s done, then repeat. There’s actually a #NoEstimates movement that’s gaining traction right now. You can google for more information and this is a pretty good introduction video.

Avoiding estimates can be tough or impossible if you’re integrating with other companies that schedule work in traditional ways.

Don’t make artificial deadlines

Never make an artificial deadline. A lot of PMs do this as a motivation technique. Without a deadline, the programmers will take as much time as they can to finish their features, right? Actually, I find that most programmers try to do the best job they can and when rushed, they’re forced to cut corners and build poor quality software. A culture of artificial deadlines is going to lower code quality and the end result will be slower delivery on features in the future.

Any good developer will ask why the deadline is set at the date that it’s set. When a good developer does ask you’ll have to admit the deadline is fake and lose credibility on everything you say in the future. Or, you could lie about the deadline but sooner or later you’ll be found out and lose even more credibility.
“Buffers” for the real deadline are also artificial deadlines. If something needs to be delivered in March, don’t tell developers it needs to be done in January so you have enough time leftover if the deadline slips. You’ll lose credibility for doing this for the same reasons as above.

You should avoid this completely by only setting real deadlines.

Deadlines must be planned with developers

If you don't plan with the people that build it

Deadlines must be planned with developers. This is worthy of its own article, and I have written one on the topic. In summary, developers have a better idea of how much time it will take to build a new feature than anyone else at the company. When you exclude them from deadline planning you’re either going to get unrealistic deadlines or you’ll need to be incredibly lucky.

Remember, telling everyone, “I want nine women to make a baby in a month” doesn’t make it more likely to happen. The amount a team can deliver over time should be projected to get realistic deadlines. An aggressive deadline might temporarily increase the amount the team will deliver over time but at the cost of morale, trust, and code quality. Sustainable pace is a better strategy and for that you need developer input.

Don’t plan deadlines in a vacuum

A common mistake is to plan a track of work and set deadlines around that track of work without considering everything else. e.g., you want to do three things in a month, but you only build a gantt chart for one of those three things. That’s ok to do if you’re going to work on the other two things after the first thing. But, if you assume that all three will be worked on in parallel, your gantt chart should include deadlines for all three.

Delay telling external parties as long as possible

When developers are involved in planning deadlines, they are giving estimates. Estimates are just guesses. Some things will take longer than planned, especially if the deadline is far out in the future. It’s difficult to tell an external party about a slipping schedule. But, if you never told them a solid date for when it would be done, you don’t have to tell them about the slipping schedule.

This goes back to the #NoEstimates topic. If you can avoid telling the external party about the deadline, do you really need one? Instead, you can prioritize the work as the most important thing to be done. Then you can tell these external parties that it will literally be the next thing we do. That can be satisfactory in some cases, and it’s a lot easier on the development team.