5 Tips For a More Effective Development Team

Being a software consultant means spending a lot of time with different development teams and environments. You need to be able to quickly get up to speed with the existing projects before you can really start making big contributions.

I’ve noticed that generally, high-performing teams have different processes from those that are lower performing. Here’s five things you can try which can improve both team productivity and output. They start off technical but become less so by the end.

1. Give Code Consistent Style

This is (almost) a no-brainer. Choosing a consistent style guide for all of your projects relieves the cognitive load on programmers. They no longer need to think about reconciling different styles of code. Should a curly brace should be on the same line or the next? How should a variable be named? Do we use camelCase or snake_case? Should we allow empty tags in JSX? All these problems can be solved by having a definite code style.

For your language of choice there is probably a tool that will do the formatting for you.

Some of theses tools will also lint your code too, that is, check it for uninitialised and unused variables, unnecessary imports or calls to methods that don’t exist.

Clean Code (and Desk)
Clean Code on a Clean Desk.

I said code style guidelines are almost a no-brainer. Deciding to be consistent with styling is easy. The hard part is choosing which style to use. Take for example, ESLint. When setting it up on a project you’ll be prompted to choose which style you prefer, Airbnb, Standard, or Google. Which should you pick? Here’s the thing: it doesn’t matter.

Yes, there’ll be arguments how many spaces to indent with, single vs double quotes and every other trivial thing (see: bikeshedding). But give it a day or so, everyone will be used to it and you’ll never need to have that argument again.

2. Add Type Checking

Continuing on with the theme of letting software help with software development: if you’re not using types in your development, you should. Developers of Rust, Java, Go, C++, Haskell and other statically typed languages, you can skip this section. These languages won’t compile if the types aren’t used consistently. The dynamic languages that are being used nowadays are a lot more forgiving, at least until you need to run them and they break in production.

Some dynamically typed languages have introduced type hints. For example, Python added type hinting from version 3.5. Check the hints using mypy. You can mix and match annotated and non-annotated code without issue. Obviously mypy won’t be able to tell you about type errors in the non-annotated parts of your code. Also your code will still run when type annotations are violated, it’s up to you to remember to check your code using mypy.

Robot Using Computer
Computers can’t write programs (yet) but they can validate them.

Other languages can be bit more involved. Rather than just trying to annotate JavaScript, you’ll need to use TypeScript. It’s basically statically typed JavaScript that compiles to regular JavaScript that can then be used in the browser or with NodeJS. If you want, you can just write JavaScript code and add annotations to it as you choose, so it can be easy to integrate a bit at a time into existing projects. Since TypeScript is its own language that needs to be compiled, type mismatches are caught at compile time. That is, unlike mypy, you can’t interpret “bad” code because compilation will fail. Of course you could still have runtime errors from code that has no type annotations.

Once you have types your IDE will be able to assist you better with autocompletion or automatically picking up errors while you work. From a developer standpoint, having the available types right at your fingertips reduces cognitive load which allows more brain-time for real problem solving. There’s also the fact that you’re more likely to catch certain problems before you reach production, which I suppose is nice.

3. Learn Design Patterns

A lot of developers have never encountered design patterns. These are platform-agnostic and reusable concepts that can be applied to solve a lot of common problems. However, many developers have implemented a named design pattern before, without realising it.

For example, what do you do when initialising a variable is costly, so you want to do it one time at most? But you also don’t want to waste time initialising it if it’s never used. You might implement something like this:

let thing = null

function getThing() {
    if (thing === null) {
        thing = setupTheThing()
    }

    return thing
}

That’s just the Lazy Initialization Pattern

How about when you want to combine a set of low-level operations into some higher-level steps that make the process easier. Say, wrapping open/write/close operations into a single writeToFile() function? That’s the Facade Pattern. What about if you only ever want a single global instance of an object? You must have heard of the Singleton Pattern.

Design Blueprints
Design patterns are like blueprints for your code.

The seminal book Design Patterns: Elements of Reusable Object-Oriented Software is required reading, but a quick look at the Wikipedia’s list of design patterns can be a good jumping off point if you’re stuck on a problem.

You may find that different generations in your team may have different experiences in regards to knowing what design patterns are, and this brings me to my next point.

4. Foster Cross-Faction Collaboration

Too often I see developers self-siloing themselves into technology teams, even if they’re working on the same product. For example, the frontend team’s only interaction with the backend’s tech is when they’re making API calls. Likewise the backend views the frontend as just building a pretty GUI for their database.

Sure, there’s good collaboration during meetings and often no problem with friendship between members across these teams. But the tech understanding doesn’t go very deep. Do your frontend developers understand why it’s so slow for the API to provide a list of business names for a dropdown list (because you have to join across three tables in the backend)? Likewise do the backend team know why the GUI is making the same API call multiple times a row for a single screen load (because the frontend devs haven’t used Lazy Initialization)?

You probably do show-and-tell to demo new features to business stakeholders, but do you do the same to other developers, and maybe give a more in-depth description of how you solved the problem? As an up-and-coming fresh-faced developer you may be surprised as to what secrets those old and “outdated” languages may hold. Similarly, the latest language de jour may have some new techniques that will inspire even the greyest of greybeards.

Collaboration
Stop, collaborate & solve problems!

5. Try Check-Ups instead of Stand-Ups

Daily stand ups are basically ubiquitous now. The intention is that everyone can get brought up to date with everyone’s progress and blockers or other issues can get nipped in the bud immediately. In my experience, managers get more value out of these than developers do. They sound good in theory, but it raises some questions. If a developer runs into an issue, should they put their work on hold until the next day when it can be brought up during stand-up? If managers need updates on an ongoing issue, to provide timely feedback to stakeholders, should those also wait until stand-up? If these interruptions are going to exist anyway, then why do stand-ups exist?

A method that I’ve found to be much more effective is daily check-ups, where managers can make the rounds and individually find out the status of various tickets. This leads to an interruption of, say, a minute per developer instead of a minute x n developers (n - 1 minutes of which is only interesting to any one particular dev).

So managers, consider ditching the stand-up. You may find your developers are better than you think at sorting out what they’re doing.

One on One Meeting
A on-one-on check-up in action.

In Conclusion

  • Don't think about how your code should look, let a code styling tool do the work for you.
  • Add type hinting where you can, catch errors earlier.
  • Learning design patterns helps you to apply existing solutions to common problems.
  • Ask all types of people to help solve problems or review your solutions.
  • Consider one-on-one time instead of meetings involving everyone.

About Tera Shift

Tera Shift Ltd is a software and data consultancy. We help companies with solutions for development, data services, analytics, project management, and more. Our services include:

  • Working with companies to build best-practice teams
  • System design and implementation
  • Data management, sourcing, ETL and storage
  • Bespoke development
  • Process automation

We can also advise on how custom solutions can help your business grow, by using your data in ways you hadn’t thought possible.

About the author

Ben Shaw (B. Eng) is the Director of Tera Shift Ltd. He has over 15 years’ experience in Software Engineering, across a range of industries. He has consulted for companies ranging in size from startups to major enterprises, including some of New Zealand’s largest household names.

Email ben@terashift.co.nz