Question

As the sole developer in a startup, I had the luxury of being able to make a lot of decisions in the architecture and frameworks of our application.

Fast forward 4 years and an acquisition later, I have a team of 5 and a lot of times it feels like the wild west. People making whatever design decision pleases them: integer and enums for DB types in one place and string another, this framework for a problem and then a different framework for the same problem elsewhere, etc.

How do I go about enforcing consistency? It feels important to me but my team members seem to subscribe to the "if it works, it works" methodology.

I guess a big part of my question is: is it unrealistic of me to expect standards like this? I struggle with the idea of coming across as a dictator that stifles creativity but doing whatever they want seems to not be scalable.

Was it helpful?

Solution

What makes you so special?

My CPU says it works and I want to go home. Why are you bothering me?

You can deal with this attitude by forcing everyone to issue pull requests. But now the deadlines are looming. Bad code presses on the gates of your pristine castle and you finally give in to the pressure. Or you win only to find everyone leaves and no one uses your pristine castle.

There are plenty of tools that help with this issue. Source control, code reviews, coding standards, etc. but the heart and soul of the problem is your subjective opinions about what is best have to be seen as relevant. For that you have to earn and maintain their respect. Do that and this is much easier. Fail to do that and no tool or practice will save you.

The best way to do that is communicate early. Don't tell me "we don't use strings for our DB types in this shop" 6 months after I settled on the idea. Telling me it's been buried in the documentation for 2 years is no justification for letting me do that.

For whatever reason you have things you care about. If you care about them and have a point get those things communicated clearly before, during, and immediately after the coding of every module.

Code stalking is a wonderful practice. Invest in whatever tools and practices you need so you can review code within minutes of it being written. Pair program and the tool is simply a guest chair.

Why? Every second that passes after I write code exponentially increases the cost to change it. That's because my memory of the code has a half life. I start forgetting it the moment my bladder demands a break.

Reduce the things you care about to their underlying principles. Rather than hit me with a list of 101 rules to follow, give me the 10 principles that they violate so I can figure out what rule 102 should be on my own.

Empower me to impose my own vision by helping me see yours and we'll get along great.

is it unrealistic of me to expect standards like this? I struggle with the idea of coming across as a dictator that stifles creativity but doing whatever they want seems to not be scalable.

Then don't dictate! Make this a positive experience. This isn't some new age hippy nonsense. It's basic psychology. You are trying to modify human behavior. Random and positive is the most reinforcing (just ask Las Vegas). If you go negative you have to be consistent with your reinforcement. That's an unobtainable pain. Be positive as you spread the wisdom and you can be casual about it.

I know where you're coming from because I've been there. You had control and now it's gone. You want it back. Well get over it. Now you have a team. They don't need to be controlled. What they need is leadership. What you need isn't control. It's influence. It works better and is a lot less work. Master that and relax. This should be fun.

Do it right and you can go on vacation and this will still work. How? By not just being a leader but by getting the others to be leaders as well. Once you've instilled your vision in the team they can work while you're gone simply by imitating what you've been doing. Mentor the newbies and encourage them to step up and influence others as well.

I know it's hard. We didn't go into this profession because we're good at dealing with people. We communicate best with code. That's fine. Just do it quick and often. Show me why yours is better. Listen if I say it's not. Do this while I'm still thinking about it. I love to code. There are few people on the planet that I can talk to about it. Be one of them.

OTHER TIPS

First, get people to maintain things they didn't write. It's very easy for a developer to get into habits of using frameworks and techniques they are used to. It's jarring to have to switch between frameworks and methodologies. If someone is forced to move outside of their own corner of the code and experience that often, it will prompt some complaining and hopefully some productive discussion that can lead to people wanting to standardize on something.

Next, pull requests and code reviews. Never allow code to be merged to your main branches without a code review first. Anyone can do it. Again, when someone sees something that's different than what they would have done, it can prompt discussion and teamwork to come to a better solution. It also makes everyone a caretaker of the code base, which (hopefully) gets people to care about it and the state of the code that goes into it.

Finally, have design discussions. They can be formal or informal, but have them. Let those that want to participate do so. Discuss what frameworks you want to use, the pros and cons of enums vs ints, etc. Then come to a decision and document it somewhere (like a standards document). Then you have something to point to when problems arise. Also, don't be afraid to revisit a standards decision. Technology changes (quickly) and so can your needs as a team and as a company.

Help people to see what you see and feel like they have a stake in the quality of the code. Then gently prod discussions towards finding a standard when differences of opinion come up.

Perform code reviews every time someone wants to merge code into the main branch/trunk and hold people to those standards when reviewing the code.

And I don't mean that only you should perform the code reviews. Everyone should review everyone else's code. This disseminates knowledge about the system across the team but also creates a situation where Carol reviews Bob's code and says, "I see you used an integer there. I always use an enum." They discover the discrepancies that you've seen and, assuming they care, they will realize that everyone's got to get on the same page.

The accepted, agreed-upon standards will emerge, at which point you document them and make sure people follow them. This would include things like "enums in the DB for ...", etc. You can also include documenting which frameworks to use, etc.

Where possible, you can write tools/scripts to automatically analyse your projects and determine which standards, tools and approaches the project is using. You can do this by running a custom tool as part of a CI build.

Have the output from the tools written to a 'scorecard' document, e.g. a google sheet with a row per unit (e.g. per 'application' or project or api or whatever), with columns for the various metrics/standards followed. This will give people visibility about what standards there are, how well adopted they are etc. and provide some order to the chaos.

You can have manually updated columns too, but good luck keeping them up to date :D

In addition to the answers provided I say you should educate your team of what you expect of them as software development professionals, starting from the moment they're interviewing to join the company.

1 - Create and follow codebase conventions

This is one of the most basic yet beneficial measures you can adopt to improve code quality. As a result of following conventions source code will be uniform throughout the codebase, reducing the cognitive effort for searching and reading code files.

2 - Implement clear software architectures

The codebase of a software project that doesn’t follow a clear architectural style, whatever it may be, deteriorates gradually as new, unstructured code is added to it, becoming harder to modify. Hence the importance of putting in the hours for the design and conservation of an adequate software architecture.

3 - Fewer is better: Languages, Frameworks and Tools

With each additional language, framework and tool you introduce into your system comes an additional development and operational cost. You should always evaluate the long-term costs of a technological decision before making it to solve a short-term problem. Avoid redundant technologies, and take most out of your current stack.

4 - Involve your team in system design decisions

The most effective way to build a shared knowledge environment is to involve the team in all system design decisions. The benefits are plenty:

  • Individuals feel valued and part of the team
  • Important decisions are challenged by the entire team before being made
  • System design strengths and weaknesses are more clearly understood by everyone
  • Creates a sense of collective accountability and trust

5 - The All-in rule

I hold the view that efforts to refactor a system design should be conducted to completion (all-in), rather than being partially concluded. There’s a great risk of eroding your system design if developers feel free to apply different coding styles and architectural patterns locally whenever they see fit.

By this point, if you've successfully implemented the previous suggestions, your team will mostly likely evaluate this rogue developer behavior as unprofessional and irresponsible.


I've recently written a blog post about this subject, you can find detailed information on these topics there: https://thomasvilhena.com/2019/11/system-design-coherence

Licensed under: CC-BY-SA with attribution
scroll top