Give a Safe Space to Express Ideas

When leading a team, it’s important to create an environment where everyone feels safe to express their ideas regardless of their experience level.

Early in my career, I was leading a team of six. One of the software engineers approached me with an idea; I knew it wouldn’t work. Instead of telling him, he’s wrong. I told him to set up a meeting with the rest of the team.

In the meeting, the team agreed his approach wouldn’t work, but they took aspects of his solution and incorporated them into the final solution. If I had told the software engineer no from the get-go, the engineer wouldn’t have felt heard, and we would’ve had a less robust solution.

Scrum is Overrated

Most companies follow some type of Scrum process. Typically this entails 2 or 3 week sprints. At the end of each sprint changes are demoed, retrospectives are performed and the backlog is groomed. During each sprint task completion time is captured, which allows management to project into the future when projects will reach completion.

Many of the Scrum projects I’ve been apart of emphasize “committing” to tasks or “taking ownership.” At the end of the sprint many engineers are held accountable for incomplete tasks. Sprint velocity is another idea that is hammered home. We have to keep our velocity! It’s like creating software is a race, it’s not. If engineers are held accountable by a metric, they’ll optimize for the metric, this isn’t want you want.

Scrum creates an easy to understand framework for teams to follow and it gives management the tools to predict the future. Teams that have practices waterfall find Scrum easy to grok.

Many of Scrums practices aren’t needed. For example, most issue tracking software allow managers to run reports on the frequency of ticket completion. With this information, managers are able to infer velocity, instead of baking velocity into the process and making it a big deal. Taking ownership is a farce, we do it naturally, to make it explicit is insulting. All the projects I’ve been a part of each engineer has a corner of the application that’s their space.

Other ways to improve software delivery:

  • If you need weekly deployments, schedule them. Deploy what’s ready.
  • Keep the backlog groomed; then engineers never run out of work.
  • In my opinion, retrospectives are the most essential non-development activity. Without it, you have no chance of becoming a better and more efficient organization.
  • Automate, automate, automate
  • Committing to a list of features is ridiculous. Rank the tasks and complete what you can. Fretting over why “task A” wasn’t complete is a waste of time. It’s clear the task was either too big, or higher priority work was taken on.
  • Demos are a waste of time unless the client cares and provides feedback. 
  • Daily meetings may or may not be needed. I prefer meeting every couple of days.

At the end of the day it’s about providing value to the client in the most efficient way.

The Benefits of Using a Build Framework

Continuous Integration (CI) and/or Continuous Delivery (CD) is the norm on software projects these days. There are many build servers such as Azure DevOps, TeamCity, Jenkins, and Cruise Control.Net. Most of these servers use proprietary languages to define build steps. But is codifying your build steps in a proprietary language a good thing?

Some applications are simple, with a few build steps, others are more complex with many build steps. When you define build steps in a proprietary language, the more complex the build steps (in sophistication or in number) the more coupled to a build platform you become. This becomes an issue when you want to switch build platforms. For example, you’re using JetBrain’s TeamCity in your on-premise datacenter, but the company decides to move to the cloud. Now you must re-write your build scripts because TeamCity isn’t supported in the new cloud platform.

Instead of writing your build scripts in a proprietary language, consider using a build framework.

Build frameworks have two benefits:

  1. Allowing transportability between build platforms.
  2. Allowing you to version your build scripts alongside your application code.

Transportability between platforms gives you the flexibility of moving between build platforms with minimal effort. There will always be some configuration on a new build platform, but build frameworks keep the effort low.

In my opinion, the biggest benefit to build frameworks is the ability to check-in and version your build scripts alongside your application code. Having the option to pull code from any point in your source control’s history and having that code build is well worth any downsides of a build framework.

There are two popular frameworks in the .Net space: Cake and Nuke Build. Both frameworks have been around for a while. I’ve used Nuke Build and enjoy it. I’ve heard great things about Cake and encourage you to look at it before deciding which is the best framework for your project.

So the next time you’re creating a new build definition for your application, consider using a build framework and checking it in source control with your application.

Understanding Begins with Expressive Names

In 2018, I joined a large project halfway through its development. The original engineers had moved on leaving behind convoluted and undocumented code. Working with this type of code is challenging because you can’t differentiate the plumbing from the business domain. This makes debugging difficult and changes unpredictable because you don’t know the impact. It’s like trying to edit a book without understanding the words.

Many engineers believe the measure of success is when the code compiles. I believe it’s when another engineer (or you in six months) understands the ”why” of your code. The original engineers handicapped the future engineers by not documenting and using obtuse names. The names are sometimes the only window into the previous engineer’s thought process.

Donald Knuth famously said:

Programs are meant to be read by humans and only incidentally for computers to execute. – Donald Knuth

Naming

Naming is hard because it requires labeling and defining where and how a piece fits in an application.

Phil Karlton, while at Netscape observed:

There are only two hard things in Computer Science: cache invalidation and naming things.
— Phil Karlton

We see our code through the lens of words and names we use. Names create a language for the next engineer to comprehend. This language paints a picture of how the author bridged the business domain and the programming language.

Lugwid Wittgenstein, a philosopher in the first half of the 20th century, said:

The limits of my language mean the limits of my world. – Ludwig Wittgenstein

The language of our software is only as descriptive as the names we use and using vague names blur the software’s purpose; using descriptive names bring clarity and understanding.

Imagine visiting a country where you don’t speak the language. A simple request such as asking to use the bathroom brings bewildered looks. The inability to communicate is frustrating maybe even scary. An engineer feels the same when confronted with confusing, unclear, or even worse, misleading names.

This feeling is best experienced.

Experience

Examine the first snippet of code, what does this code do? What’s the why?

Take your time.

public class StringHelper
{
    public string Get(string input1, string input2)
    {
        var result = string.Emtpy;
        if(!string.IsNullOrEmtpy(input1) && !string.IsNullOrEmtpy(input2))
        {
            result = $"{input1} {input2}";
        }
        return result;
    }
}

The above code is a simple concatenation of two strings. What the code doesn’t tell you is the “why.” The “why” is so important, without it, it’s difficult to change behavior without understanding the impact. Of course, investigating the code’s usage will likely reveal it’s “why,” but that’s the point. You shouldn’t have to discover the code’s purpose, instead, the author should have left clues, it’s their responsiblity to do so.

Let’s revisit the code, but with a little “why” sprinkled in.

Again, take your time, observe the difference you feel when reading this code.

    public class FirstAndLastNameFormatter
    {
        public string Concatenate(string firstName, string lastName)
        {
            var fullName = string.Emtpy;
            if(!string.IsNullOrEmtpy(firstName) && !string.IsNullOrEmtpy(lastName))
            {
                fullName = $"{firstName} {lastName}";
            }
            return fullName;
        }
    }

The “why” brings the code to life, there’s a story to read.

Communicate

Communicating the intent and the design to the next engineer allows software to live and to grow because if engineers can’t modify the software, it dies. This is a tragedy, even more so when it’s a result of poor design and lack of expressiveness — each is preventable with knowledge.

Do the next engineer a favor and be expressive in your code. Use descriptive names and capture the “why” because who knows, the next engineer might be you.