Penny-wise and Pound-foolish

What a time to be a software developer! I'm always amazed that even in an industry with high salaries and intense competition for talent, companies find a way to shoot themselves in the foot with cheapness.

There's a great thread on Hacker News today where people are chiming in with their experiences of company cheapness around basic things like coffee and bathroom cleaning. The common lesson being that when you see a company attempting to cheap out on basic things, it's time to leave.

Early in my career I read Joel Spolsky's A Field Guide to Developers and it painted a picture for me of how good tech companies treat their developers. And it taught me early on to pay attention to the anti-patterns of companies that were less enlightened.

At one of my first jobs, I asked for a book about a new technology that was important for projects I would be working on. I'll never forget the development manager making me feel bad that in a time where the company was trying to save money that I would ask for a $30 book on a technology they wanted me to learn. Keep in mind this was a company that was paying me tens of thousands of dollars in salary in addition to full benefits. It's in small moments of cheapness that you learn a lot about a company.

In the early years of .NET, when Visual Studio was less packed with nice productivity features, the 3rd-party extension ReSharper was more or less ubiquitous amongst respectable developers in that space. It was always very telling to see which .NET shops assumed you would want that tool and provided a license on your first day, and which ones treated that extra cost of a few hundred dollars with suspicion.


In fact, the way that employers view licensing costs for software of the daily-use variety is always enlightening. One company I worked at had developed an impressive build system around a popular source control system you've definitely heard of. At some point someone in management decided they didn't like paying for an open source product that could be had in a free edition, so they downgraded to a "community" edition of the source control system that was free (as in beer), requiring the company to allocate developer hours to re-implementing features of the paid edition that they relied upon heavily but no longer had in the free version, not to mention training everyone to use the new bolted-on system in their daily workflow.

Training is another area that speaks volumes about an employer. Companies that believe in the importance of training will make it as easy as they can for you to get that training. How onerous is the process to get training courses approved? Companies that want to provide simple, default training options will subscribe every developer to Pluralsight, Safari Books Online, or other popular all-you-can-eat educational resources. Some companies are aware of these resources but will try to save money by buying only a certain numbers of licenses, so that employees have to keep bugging each other to release a license. Some companies will force employees to sign up using their own credit cards and then submit expense reports every month to get reimbursed. These are money saving measures that put barriers up and ensure that most people will simply stop caring about getting training because it's too much of a hassle. Employees aren't dumb—they know the company had ways they could have made these things easier, and chose to go the penny-pinching route that shifts burden to the employees.

These are just a few examples I've personally witnessed, but there are myriad ways that companies turn off developers with moments of cheapness. In a period of unprecedented mobility among developers, where employers routinely pay six-figure salaries to entice and retain their people, it's a bad time to be penny-wise and pound-foolish.

Ron Jeffries on Prediction

It is common practice to make a list of essential features, think about them for a while, and then decide that they define the next release of our product. The next question, of course, is “when will all this be done?”

The answer is that no one knows. We could do a lot of work to improve our not knowing, and in some areas and at some times some of that is worth doing, such as when there’s a large contract waiting to be bid. But when we’re in the business of developing solutions for internal or external customers, we do best to provide small amounts of value frequently, not wait for Big Bang releases that seem often to recede indefinitely into the future.

You’re trying to get into a frame of mind where you think “If we just did this one little thing, Customer Jack could actually use this”. Then, do that little thing and let Customer Jack try it. We want to move as quickly as we can to continuous delivery of value.

We want to make the value of what we’re doing so visible that our Product Owner and other stakeholders can’t wait to get it out there. Then … we’ll be doing the right thing, with, or without, story estimates. 

Ron Jeffries - Story Points Revisited

Bring Engineers Problems, Not Solutions

I read a great article posted to Hacker News this week called Effective Communication With Software Engineers by Simón Muñoz.

He made some wonderful points that rang true for me, as a software engineer, that I wanted to discuss here.

What resonated most with me is this idea that as engineers, we want to know the high-level goals of the product we work on, why they're important, and be given the leeway to design solutions.

You don’t present a solution to an engineering team; you bring them a problem to solve. The best engineers won’t willingly accept implementing a solution if they have not participated in defining it.

I've written about this idea before in my post Goals, Not Tasks. Engineers don't want to be treated like highly-paid instruction followers—they want to understand business objectives.

And not only do we want to know what the high-level objectives are, we want to know why they are important to real users of the product. Simón continues…

Starting with the problem is not enough. You have to demonstrate how solving this problem fits with the vision and strategy of the company. Your team also has to understand why you want to solve this particular problem and not any other.

It's so much more motivating to work on a product when you can see that real people are benefiting from it, and you're not just fulfilling some manager's dictum. Simón mentions the importance of proving to the engineering team that the work they are doing is "moving the needle"…

Your engineers want to know if their work impacts the organization. A huge smell that they are working in a feature factory rather than as product engineers is when you don’t define how to measure the success of an initiative.

We don’t measure success by the number of story points that the team manages to get each sprint... We measure success by moving the needle on the metrics that matter to the business.

If you don’t obsessively communicate the importance of these and can’t get your team interested in them, you’re losing much of their value.

We engineers want to know what are the important problems to solve, why are they important, and be given the freedom and respect to invent solutions to those problems.

Finish Things

In Lean, there's a lot of talk about reducing work in progress (WIP). It's interesting to me that even though it seems that Lean concepts have permeated the software industry, so many teams struggle with finishing things.

Speaking from the point of view of a developer, I can say that there's a real drag on morale when it feels like no one particularly cares about receiving the value of my work. Obvious bottlenecks in a team's process that persistently go unaddressed are not just a waste of money, they're a reason for people to check out. Add to this malaise the tedium of fixing the continuous merge conflicts that come when we create code branches that we can't merge for a long time. Ugh.

Some common impediments to finishing things:

  • Slow code reviews
  • Exhaustive manual testing
  • Distracted product owners

Slow code reviews

I've long been of the opinion that most code reviews are hardly worth the time spent on them by the reviewer and not worth the interruption to the flow of work that they cause. It's really hard to do good code reviews and it's a major bummer to wait a long time for someone to review your code only to get a rubber stamp. I like to call this "Quality Theater", where a checklist of procedures are half-heartedly (yet religiously) performed that don't actually improve the quality much. I would encourage teams to look at metrics in whichever code review system they use to see how long code reviews are taking, and how many significant changes to code occur as a result of the reviews. Be honest if they're resulting in long delays that usually end in a rubber stamp.

Exhaustive manual testing

If the team has dedicated QA people, is it taking a long time for work to make it through testing? Why? Is there a large amount of manual testing going on for every story? Can we automate more of the tests? Are stories hanging around in the "QA in Progress" stage waiting for clarification from the product owner about an edge case that's not really central to the story? Are stories being rejected by QA because of a small issue that does not detract from the value of the story?

Distracted product owners

Is the product owner plugged into the project fully and making it a priority? Are we waiting a long time for them to accept the work we've done? Are stories being held up because of ambiguous requirements where the team can't agree if they were met or not?

So how do we finish things faster? Other than recognizing the impediments above and having some earnest discussions about why they're occurring, there are some general concepts that apply broadly.

The common thread is in identifying what is our unit of "done"?

  • Make stories that are small increments of value
  • If a story is being held up because of a tricky aspect, consider splitting off the hard part and finishing the easier part cleanly
  • If we discover a story has a subset of the requirements that is contentious or poorly defined, can we finish the obvious part now and put a story in the backlog for the wishy-washy part?

The idea is to focus on finishing things. What is slowing down our process of getting units of value to "done"?

Challenging the Pull Request Orthodoxy

A thread showed up in my Twitter feed the other day from Dragan Stepanović about the low efficiency of pull requests for small changes and refactorings.

I think we've all felt that hesitancy to refactor something because it didn't seem valuable enough to push through a whole pull request approval process.

In the comments on Dragan's thread, someone mentioned an article on Martin Fowler's blog called Ship / Show / Ask. The author, Rouan Wilsenach, proposes that instead of requiring every change to be approved before it can be merged into the mainline, we can decide on a case-by-case basis whether to Ship (merge with no discussion), Show (merge and then discuss), or Ask (discuss and then merge).

My experience on teams that use pull requests has always been that every change follows the Ask path. For any change, no matter what it is, we submit a pull request, it has to be approved by one or more other developers, and only then can it be merged. But this process is not really worth the trouble and delay for some changes, depending on context such as who made the change, how much the change is like other changes that have been made many times, and where the change has been made.

As Rouan explains, some good candidates for the Ship option are things like:

  • I added a feature using an established pattern
  • I fixed an unremarkable bug
  • I updated documentation
Some candidates for the Show option would be:

  • I would love your feedback on how this code could be better
  • Look at this new approach or pattern I used
  • What an interesting bug! Look how I fixed it
Finally, the Ask option (a traditional pull request) could be reserved for things like:
  • Will this work?
  • How do we feel about this new approach?
  • I need help to make this better please
Always going with the Ask option, as most teams do, has some downsides that can be avoided with this more flexible model, as the articles explains:
The unavoidable thing about waiting for approval is that it takes time. If too many changes are in the queue for feedback, either the quality of the feedback goes down or progress slows down. 
The reason you’re reliant on a lot of “Asking” might be that you have trust issues. “All changes must be approved” or “Every pull request needs 2 reviewers” are common policies, but they show a lack of trust in the development team.
Pull requests are a great tool for modern software development, especially when contrasted with a free-for-all approach where nothing is reviewed. But it's important to remember that they're not necessarily appropriate for all situations.

Methodologies Are Descriptive, Not Prescriptive

In all my years in the software industry, I've never seen a team where I would say the methodology they professed to use actually mattered.

The siren song of methodology is that you can take a poorly functioning software development team, "install" a name brand methodology, and they will turn into a highly functioning team.

The way a new methodology is minted is a person or group of people with experience in the software industry decide to write down the characteristics, philosophies, and practices of teams they've experienced in the wild that were good at making software.

They write a book about it, design training courses, and offer up their services as a consultant to organizations that want to "do" this methodology so their teams can be good like the teams that inspired the methodology.

In a paradoxical way, methodologies are useless for the teams that actually need them. Before people were buying books about Scrum, there were effective teams keeping track of the work they needed to do, maybe as a list scribbled on a whiteboard in the office, an Excel spreadsheet, a series of index cards tacked to a bulletin board. They didn't need to be told about "Product Backlogs". They were releasing updates to their software on some quasi-regular cadence without knowing anything about "Sprints".

Scrum, XP, Kanban—you name it—cannot help your team with these problems:

  • We don't have the budget to hire good software developers
  • The manager of this team is a jerk and people don't want to work for them
  • The product owner is spread too thin so nobody knows what we're supposed to build
There may be some value is "adopting" a methodology if nothing else so that a group of people have a shared terminology in which to communicate, but I'm not sure beyond that. No methodology will make a team "good."

Never forget that a methodology is a description of one type of high functioning team—it's not a playbook for making a poorly functioning team into a high functioning team, and set your expectations accordingly.

Incomplete, with high quality

In a presentation I gave at a past job, I summarized the Agile philosophy as: "Deliver business value to real users faster."

Maybe because I came up as a developer around the time of the Agile Manifesto, I feel like I have Agile in my bones. I've never known any other way of looking at the process of creating software.

Get valuable, well-tested things to real users as fast as possible.

If you work for a company that makes hiking boots, then it's a big problem if you ship a product that has no soles attached. Hiking boots without soles are useless.

But hiking boots of the wrong color are useful. We can change the color of future iterations of the product if people like the hiking boots, but don't like the color.

Hiking boots of the wrong color are better than no hiking boots for someone who wants to hike, while hiking boots without soles are useful to no one.

When it comes to software, poor quality and incompleteness are not the same thing. All the hypothetical features we believe our users would want do not need to be present for them to get any value out of our work. The thing that we put out into the world does not need to be perfect, in fact, it would be weird if it was perfect.

I guess I'll be explaining this concept until the end of my career, but in software we must be okay with delivering the wrong thing quickly. Let's strive for making something incomplete, but with high quality.