Solving Problems & Saving Time through Software and Crushing Entropy
Powered by Cecil & Hyde.
It feels like whittling. Even though “construction” is the most frequently used metaphor for trying to describe what we do all day at work, it doesn’t feel right. I also don’t know why we only use wood-working metaphors. Any psychiatrists in the house?
It feels like whittling to me because of something called “composability.” Composability is all about combining pieces of code to create something bigger, that does more work. There are several ways to do this, and times there are very real technical challenges. But this is a lot harder than it sounds.
When we think of construction the first attribute we think of is its composability. Any weekend warrior can go to Home Depot and get what they need, and so long as they’re paying attention, asking the right questions, and checking the specs—all the pieces will work together very nicely. As a software engineer that would be amazing. I dare to say we experience the opposite.
Very few things “Just Work”. Many commentators have lamented that a lot of programming tasks “these days” are just writing “glue” code to put various things together. I don’t disagree, but I also don’t think that is a Bad Thing™️, and its not easy to do well either. Because composability is hard.
In fact, its so hard there are many times we have to pass on re-using working services and code because retro-fitting it to our new purposes would actually take longer than just doing it over, precisely the way we need it. Composability can be harder than making something brand new.
This is why I chose whittling as my metaphor. Sometimes you get to simply take something you’ve already done and re-use it, whole-cloth. But, more often than not, you have to start from a blank slate, and mold the code/chisel the piece of wood until it works/looks just the way you need it to for what you’re doing.
Read more: What Building Software Feels Like
There are tons of opinions and ideas on how to get software engineers to work together, and I’ve shared some of my own before. I think the crucial one to get right is coming to the idea of a Directly Responsible Individual. Whether it is a bug, a feature, a service, part of a product, or the whole product (for smaller products) there should be one DRI.
I believe this the most effective, and most natural way to do our work. I believe this is, more or less, how open source projects tend to work. Single individuals own features, parts of the project, bug fixes, and processes. And decisions flow through those individuals.
It is very simple. The DRI is the source of truth for that indivisible thing. And “indivisible” is how you decide how many DRI’s you need to have. The DRI is where the buck stops. They are fundamentally responsible for what they are given to work on. For a sports example; the coach is the DRI of the team, when the team fails to perform the coach gets fired. Why? Because there was zero question who was responsible for the on-field performance of the team.
The DRI gets the final say. You can imagine this as if they have a 51% voting majority on every part of their project. Ownership in the strict sense of the word. They should, of course, ask for input, feedback, and opinions from others on their team and others not on their team. The individual knows their piece is but one piece of the greater whole, and everyone is working towards reaching the final goal. But the decisions ultimately rests with them. Why? Because the responsibility of delivery rests with them. You cannot give them full responsibility without full autonomy, otherwise you’re sabotaging them from the start.
The list of responsibilities you give to the DRI is up to you. If TDD is important to you, make it their responsibility too. If you want them to fully document their project, from goals to decisions to user training, go ahead. If you don’t have a dedicated DevOps team you can make it the DRI’s responsibility to manage the project in production. Of course, if you have a DevOps, or a product team responsible for documentation, or a QA team, etc, those teams ought to have their own responsibilities. Make the lines crystal clear.
Whether everyone works on their own, is paired up, or a mix of the two there should still be a single DRI. If you’re pairing, give them each a related thing to own. And they can switch during the day as to whose project they are working on, who is making the final decision.
Whether you have teams of three, or teams of eight, or twenty, you should be able to chop up the work into indivisible pieces. Naturally, there will be pieces that have to work closely together; two different pieces sharing the same data store and data models, many pieces using one API service, etc. But so long as you have defined and documented interfaces, you can surface discussions around a ChangeLog when things need to change.
I believe this works because owning what you’re working on gets you invested in doing a good job. It’s yours, no one else’s. Since it doesn’t belong to anyone else, it will reflect you and your choices.
There can be no buck-passing; “Oh, I thought someone else was going to do that,” and there can be no wondering about why something didn’t get done. There can be no disagreement as to how something ought to work, because one person makes that decision. The only question becomes: is it performing?
This makes management’s job much clearer; they now have one job and that job is to set context. Your manager, or lead, doesn’t have to wondering whether or not they should “jump in” and help you out. You can ask them. When you feel they are deciding things for you, you get to say: Thank you for your input, I will make the decision. Both micromanagement and drive-by-management need to be shut down, because it is no longer their job to make decisions. Their job is to set the context.
Management needs to give you the reasons why we’re doing this work. They need to give you the end goal, the job your software needs to do. They need to tell you what you’re starting with, and where you’re headed. They don’t get to decide the path you’re going to take.
Read more: A Responsible Individual
An adjective everyone wants to claim: resilient. “Our service/platform is resilient.” Resilient infrastructure is a topic that many have gone into detail to teach us all how to achieve it.
But I think we have skipped over something. Something more fundamental. Conway’s Law:
[O]rganizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations.
If you’re looking to build a resilient system, you better have a resilient organization, and communication, otherwise you’re going to be ice-skating up-hill all the time. You may yet achieve your goal. And then one day you’ll realize you’ve slipped and lost that resiliency.
It comes down to actually creating a culture in your organization that truly values resiliency. That is the only way you can be sure you’ll continually reach your goal.
The biggest success story for this topic is Amazon. The first goal wasn’t resiliency, it was about pleasing their customers. But, Bezos knew without a resilient system the customer experience was always subject to volatility. We all know what he did. He separated his teams.
He demanded that when his teams communicated with one another they did so through official channels. Just like any other customer would. In order to be absolutely sure the customers would be treated well—he turned teams at the same company into customers. This is a rather extreme, and useful, form of “dog fooding” (using what you build).
Rather than just telling everyone to “Be More Resilient”, as if that is a thing you can expect to work, he introduced a constraint that resulted in changed behavior. And the result of that behavior was very resilient systems that are highly regarded by everyone in our industry.
Read more: Resilient Microservices
I don’t think I have to convince anyone that reading code is hard. Often its so hard we throw up our hands and rewrite it. There is a saying that “tech-debt is any code that you didn’t write”. Because reading code is hard.
I don’t think I’m going out on a limb when I say: rewriting shipped-and-working code just because you find it hard to read is absolutely the wrong move. You are actively destroying learned knowledge embedded in that code. Knowledge is value.
Engineers who know that learned knowledge is value document their code. They document code because reading code is hard. Reading sentences describing why the code does what it does is easy. That is a way to protect your code from being rewritten and discarded—a way to protect the value you’ve created through your learning. When you find yourself learning about why an existing piece of code does what it does, and there isn’t documentation—go ahead and document it. Even without changing code you can add value to it.
I have the good fortune to be volunteering some time helping folks learn to code. I’m coming to a realization that—they actually know how to “code”. Or rather, they know how to think through a problem in its constituent steps. And they can break steps into smaller steps. What they don’t know is “how to speak computer”. The syntax trips them up constantly. And they don’t have a good map of concept—>syntax. This is why reading code is hard. And its why junior engineers out of college have, largely, the same problems. They may be better with syntax purely out of having spent more time with it, comfort, but they still lack a map that translates a concept into syntax. That is something that comes with confidence and experience.
When people say “Good code is eas(ier) to read” they aren’t saying that reading code is hard. They are saying that; this code is probably documented, and this code clearly demonstrates the concept the code is implementing. Bad code obfuscates what is really happening. Good code makes it front and center. Good code plainly states what was learned in order to write it and why it was written.
Read more: Reading Code Is Hard
Whenever someone uses the acronym MVP, Minimum Viable Product, I feel that we should make them explain what they are actually talking about. There are lots of things folks call an MVP, that totally miss the point. Here are a few humorous ones I’ve encountered:
And then of course there is the engineer backlash against MVP concepts, which is totally justified:
Okay so we’re gonna do the mvp of this bridge. Just enough engineering to stand it up. Once we get a few thousand cars going over it a day we will hopefully get a seed round and go back and fix the tech debt— Scott C. Reynolds - My Name is Already Fairly Long (@scottcreynolds) February 14, 2019
And then of course, this graphic, which kicked off a giant bike-shedding session:
Engineers were talking about how neither of these two sequences “are really an MVP”. I think they’re wrong. Here is why: the second sequence does not describe the “MVP of a car”. It describes the MVP of “how can I get people to buy a transportation product to go from A—>B”. You don’t even know if people will pay to go from A—>B, so don’t build a car. Build a skateboard, on the cheap, and see if you can market that as the solution that people will buy. Once you’ve proven they will pay for a solution to the problem then you can start building more expensive things.
For Scott, talking about building a bridge, the MVP of building a bridge is not a smaller bridge made out of duct tape. The MVP of a bridge is probably a row boat. Then a ferry. Then a bridge. If you look at history that is, quite literally, how many bridges came into being. In both Boston and New York the bridges across their respective rivers were only built after ferry services had operated for decades showing that if the cities wanted to build a bridge, it wouldn’t go to waste. Obviously the financing was different—but imagine being a politician who puts forward a public works project like a bridge with the associated tax to build it without proving its what people want?
Minimum viable products are not “the smaller version of the real thing.” They are not “what I can afford right now.” MVPs are the testing of a theory. Testing a theory should not be expensive. And you don’t even need a full blown application to test a theory. You can literally use excel if you have to; or something else, it doesn’t matter.
We engineers get confused thinking that people actually give a crap about the technology that goes into what they buy. They don’t. They buy solutions to their problems. If you are offering a service, and use excel to fulfill it, customers don’t care. They won’t wince. They won’t go to the next shiny application. If you solve their problem well, at a price they are willing to pay then you have tested the theory that someone will pay for that service. That is all an MVP really is.
Craigslist is a real-world example. What was the MVP for his website? An email newsletter. Not even close to the same thing. Not scalable. Not automated. But it proved that he could get eyeballs for classifieds on the internet.
I propose that we come up with different terms for the other things that people are using MVP.
Read more: MVP means lots of different things.