Broken Windows in Code
https://picjumbo.com/broken-windows-in-an-old-abandoned-building/

Broken Windows in Code

The Experiment

In 1969, a standard University psychologist named Philip Zimbardo conducted an interesting field study. He abandoned a car in a rundown town in New York City that was poor, dangerous, and had high crime rates. He also left a similar car in Palo Alto, California, an area considered well-off with less crime. The number plate was removed in both vehicles, and the hood was left open. 

For the car in New York, it was not long after 10 mins that it was vandalised. Windows were broken, and parts were taken or damaged. The car in Palo Alto, however, remained untouched for two weeks. Philip then smashed the car with a sleigh hammer. Not long after, passersby also started damaging and vandalising the vehicle.

Philip Zimbardo concluded that in high crime rate areas, where abandoned property is common, vandalism and theft occur more often as the community doesn't care much about it. But even in a nice neighbourhood, the same behaviour can occur once people think other people don't care also.

Broken Window Effect

Harvard political scientist James Wilson and criminologist George Kelling later popularised the theory in a 1982 article in The Atlantic newspaper, in what is now known as the "broken window effect".

In the article, they describe a building with a broken window. If the window is left broken, passersby will conclude that no one is in charge of it or cares about it. As a result, vandals tend to break a few more windows. Graffiti might then start to appear. Eventually, they might even break into the building. 

James and George argued that a city with minor crime and antisocial behaviour like graffiti, panhandling and public disorder are the "broken windows". If the police don't address them, they can slowly turn a well-off neighbour into a rundown one and attract major crimes, such as murder, rape, and robbery. And the opposite can be said, that a city ridden with severe crimes can be reduced by focusing on the more minor offences.

Broken Windows in Software Engineering

While the theory was used to explain decay in neighbourhoods, it can apply to anything where neglect can attract other destructive behaviour, which eventually deteriorates into something not easily repairable.

One noticeable area is software engineering. You might have seen "broken windows" in the project's source code. Poorly maintained code that doesn't follow best practices, lousy naming conventions, and fragile tests. There might be some 'hacks' comments or lots of "todo" that no one plans to address.

Poorly maintained code sends a message to other engineers that no one here cares about the code or is in charge of it. If the engineers who regularly work on it don't make an effort to keep the code clean and maintainable, why should you also? 

This creates a negative feedback loop where another engineer will tend to add more lousy code to the current mess, which then attracts even more crappy code. This can ultimately lead to the software becoming so messy and unmaintainable that no one can make any enhancements without requiring a big decision or risking breaking something.

Another negative side effect is good Engineers might leave as working in such an environment can be frustrating and technically unrewarding. So, in the end, the only engineers remaining are those who feel the code is "fine as is" and have no desire to improve it.

Broken windows can stem from poorly written code, shortcuts, or wrong management decisions. And it's never any single code commit that got it into this state, but a series of smaller changes over a long time. 

One broken window — a badly designed piece of code, a poor management decision that the team must live with for the duration of the project — is all it takes to start the decline. If you find yourself working on a project with quite a few broken windows, it's all too easy to slip into the mindset of "All the rest of this code is crap, I'll just follow suit." It doesn't matter if the project has been fine up to this point. - The Pragmatic Programmer by David Thomas and Andrew Hunt

But like broken windows in neighbourhoods, we can take action to prevent the codebase from becoming a software disaster. These can be done with the same approach of 'policing' the minor bad code to avoid the more severe issues.

Preventing Broken Windows

The first step is to stop continuing to commit lousy code. When making changes to the code base, always take the extra time to do things right and make sure you leave the code in a better state than you found it. 

Stakeholder Buy-in

It's vital to get stakeholders and product owners on board with the direction, as items can take longer to complete. One of the causes of broken windows is poor management decisions and focusing on short term gains. You might need to explain the importance of doing things properly now can save time later and reduce technical debt.

Reasons for not fixing broken windows

  • Cost and time to make changes increases
  • Risk of breaking something increases
  • Risk of 'good' Engineers leaving increases
  • Codebase being unmaintainable and even the death of the software

Keep it Simple

Whilst it's good to write efficient code, don't do it to just make the code smaller, do it so that the next person can more easily maintain it. Making code logic complex or over-engineering can negatively impact the team's productivity because the code is now harder to understand and maintain.

Well named Methods and Variables

It can be easy to overlook the importance of having a good variable or method name. After all, it doesn't affect performance as the compiler will convert it to machine code. And it can sometimes be challenging to think of a good name. But without a good naming convention, it can be even harder for another engineer (or yourself in a few months) to read and understand what the code is doing. Self-explanatory methods and variables make code more intuitive as developers can generally understand the code without going through it in detail.

// Example of Bad naming. 
// What does this process do? 
// Does 'enrol' mean if someone wants to enrol


var s = new Entity()

s.process();

if (enrol) 
{ 
  ...
}


// Better naming. 
// Easier to read and understand

var student= new Student()

student.Register()

if (isEnrolled)
{
...
}        

But on the other hand, don't be obsessed with self-explanatory names as it can lead to long methods. 

// Example of name that's too long

void GenerateLocalStudentAttendanceReportForMiamiDevConConvention() 
{
...
}
        

Large Classes

Generally, a class that is too large signals that it's doing too many things. The more responsibilities your class has, the more often you need to change it and any other code that references that class. This makes changes more complex and time-consuming and can introduce unrelated bugs.

SOLID principles are an excellent guideline for building software that is easy to maintain and extend. In particular, the 'S' in SOLID is the 'Single-responsibility Principle' and aims to reduce dependencies. If a bug is introduced with your change, it shouldn't affect other unrelated areas. 

 "A class should have one and only one reason to change, meaning that a class should have only one job." - Single responsibility principle, Robert Martin.

Too Many Comments

On the surface, comments sound helpful and the more, the better. It shows that an Engineer is thinking about the next Engineer maintaining it and taking pride in documenting their work.

But while intentions are good, comments can be lies waiting to happen. For example, will the next Engineer remember to update the comment when they change the code?

A better approach is self-documenting code. Try to write the code so it's easier to read and understand, removing the need for comments. However, even though developers can understand how a particular code works, they might not understand why it was implemented in that manner. Comments can be helpful here to explain why something was done a certain way. 

Duplicate Code

Because every line of code that goes into the codebase needs to be maintained, duplicated code decreases productivity. In addition, when Engineers update one part of the code, they must make the exact change to multiple locations. Then there's the risk that someone will miss one section and introduce a bug.

"it's not a question of if you'll forget about the multiple places to maintain, it's when." - The Pragmatic Programmer by Andrew Hunt, David Thomas.

Duplicated code stems from programmers copying and pasting code or having a poor understanding of how to apply abstraction. Fixing duplication starts by recognising where the duplication exists. Then, you can follow the DRY (Don't Repeat Yourself) software engineering principle and extract similar code into a method, service or class. 

For example, a "sending email" code snippet found in multiple locations can be moved to a single method or class called "SendEmail(address, subtitle, text)". Any future email protocol or logic changes are then isolated to one section.

Avoid Premature Optimisation

A common programmer mistake is spending time improving something that isn't needed. This results in wasted effort and extra complexity in the code and distracts the programmer from delivering value to the user faster. Furthermore, most software doesn't benefit from highly optimised code as modern CPU and RAM are powerful enough for general user usage. So instead, better use of time is to write 'OK performant code', focusing on clean and easy to enhance code. Then when you identify performance issues, fine-tune them.

"The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimisation is the root of all evil (or at least most of it) in programming." - Donald KnuthThe Art of Computer Programming

Methods Too Long

Long methods can be hard to read, understand and maintain. Large methods stem from having too many parameters, local variables, if statements or nested loops. The more things you need to follow, the more cognitive load you have to go through to understand the code. Long methods might also be doing more than one thing, which goes against the "Single responsibility principle" best practices. And they can be problematic for test coverage.

You can reduce methods size by using the Extract Method. Find chunks of codes or lines that work closely together, and pull them out into their own method. 

If there are many parameters or variables, you might need to consider abstracting them into their own class and properties. 

Code Smells & Static Code Analysis 

Broken windows in code indicate a deeper problem in the application. The software itself could be working fine and bug-free, but it's difficult to read and maintain because of poor quality code.

"Smells are certain structures in the code that indicate violation of fundamental design principles and negatively impact design quality." - Girish Suryanarayana. Refactoring for Software Design Smells. 

Static Code Analysis tools are a great way to automatically inspect the codebase for code smells, bugs and security concerns. It can also generate a report of all the issues and suggestions for addressing them. These can be the 'police' for your broken windows and should be incorporated into your CI/CD to set quality standards. 

Iterate and Refactor Often

If you are working on an existing application with many broken windows, don't try to fix them all immediately. It can be a waste of time, and you'll also probably make it worst. For example, there's no benefit in cleaning up a section of code that is working fine but rarely updated, even though it has many broken windows. Instead, identify the most significant pain points or commonly updated code and start there.

Like doctors who promote the importance of maintaining good health rather than just treating the illness, Engineers should be looking at keeping a clean code base without broken windows. Not only do they help prevent large technical debt building, but more importantly, they make programming more enjoyable.

Fabulous piece San Tuon, true. Imagine the horror when projects don't prioritise writing their tests? Sadly companies/consultants looking for a quick win, often overlook this, deliberately.

Like
Reply

Thanks San Tuon. This is really important, and at the same time not well appreciated.

Like
Reply

To view or add a comment, sign in

More articles by San Tuon

Others also viewed

Explore content categories