Write code to be read.

Software code and tests are read much more than they are written.

Some people write code with the sole intent of making the program work. After all, that is the immediate goal, to deliver business value through working software. Most of the time, though, the creation of software is merely the beginning of a very long life. Good software will be used and expanded upon for decades.

Software is only written once. Over the next few decades, it will be read hundreds of times. If the software is written well and clearly communicates its intent to the reader, that software will be expanded and improved upon. If readers have trouble understanding the code, it will be more likely that the code will be replaced.

Take extra care to make what you write a lot easier to read. Both the main code and the tests. Well-written code should be a joy to work with and easy to expand upon.

This will make it easier to change later. There will always be a need to make changes later.

Avoid 3D effects.

Don’t use clever 3D effects in pie charts and bar charts.

You will often see 3D effects on pie charts and bar charts in the news media. They like to do this because the colors pop and the 3D effects make it look like the statistician partnered with a graphics artists to make the story more interesting. In these cases, the mode of delivery is more important than the actual content. If they retain your interest, you’re less likely to change the channel. They really don’t care if you actually understand the statistics.

When you are making a presentation of data, you should endeavor to show the truth. Communicate what the numbers truly mean. Sometimes, this is more simply done in a table of data. Often there is no need to resort to charts and graphs.

The problem with 3D pie charts is that the portion on the bottom shows more surface area than the other slices. This can exaggerate the value of the bottom slice compared to other slices. Often it is difficult to have a good sense of the relative sizes of the slices when 3D effects are used.

Similarly, 3D bar charts make it very difficult for the reader to tell what the numerical values of each bar are. It’s hard to tell where the zero line starts, and whether to use the front, back, or center of the top of the bar when comparing against the axis. Furthermore, some bars can block the view other bars. These difficulties lead to the hiding of information and making the reader confused.

If you are in a business situation where you feel you need to deceive the reader by creating these poor charts, you should reconsider your position. The numbers are the numbers, just deliver them as they are.

Don’t get clever.

Don’t write complex software just because the technique looks cool.

From time to time new techniques will appear on the web, and then everyone will start over-using them for anything and everything. A couple years ago it was the repository pattern. This pattern has its uses, but when working with a framework that already has Active Record in it, it often gets abused. Next thing you know people are creating an in-house active record on top of a repository on top of a real active record on top of the data access layer. Needless complexity.

This is especially true for simple models where using the framework’s Active Record alone is all that is really needed.

Another example is where a very intelligent programmer will invent some clever algorithm that saves several lines of code or shaves a few milliseconds off the compute time. It’s valid, it passes tests. It does what it is supposed to do. The problem is that when other developers revisit the code later, they can’t make heads or tails of it. As a result, to add new functionality, they sometimes have to replace the whole class. Or worse, the clever algorithm is spread across several classes like a cancer, making it extra hard to replace or extend.

Software engineering does take a significant amount of intelligence. Don’t treat it like a contest to see who can create the most obscure code. Software that is more easily improved and extended in the future has much more value.

So don’t get clever with your code. It will confuse the future people who have to support it.

Welcome revisions.

Don’t be offended when your code gets refactored.

Some developers get upset when they find out the software they spent countless hours working on has been refactored by a new programmer. They take pride in their work and consider it a personal offense when their code is replaced. Perhaps they feel that their code was perfectly fine and shouldn’t be altered.

There are many things wrong with these lines of thought. First of all, software is a living document. As time goes on, new developers are always adding to it and improving it. New techniques and libraries become available over time, and this leads to many opportunities for improvement. One should not expect software never to change.

Secondly, pride is not a virtue. You simply have to admit that you’re not the best programmer in the world. Your code isn’t perfect. It may run, it may pass tests, but it can always be improved. Accept this and embrace the idea of improvements.

Finally, be thankful that someone found the time to make your code better. They’re doing you, and everyone else, a favor. It’s not a personal attack. It’s an improvement on the foundation you built. Be honored that you’re part of a team that continues to deliver the best software.

Agile Principles #12: Review and improve.

At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.

If you never learn from your mistakes, you’re doomed to repeat them. Suffering the same problems over and over is a miserable situation. The first time you go through a failure is fine; it’s a learning experience. After that, you’re not learning anymore. You’re just plodding through a suboptimal existence.

This is where reflection comes in. The team needs to stop from time to time and examine their recent problems. They also should consider their processes and procedures. Are there changes the team could make which would lead to a more productive outcome? Can improvements be put into place so that certain failures no longer occur?

Sometimes it helps to have reminders of agreed-to improvements posted in a highly visible place. It would be quite unfortunate to have people revert to the behavior that causes problems. Learning often requires reinforcement of ideas, especially if a message can be delivered in multiple methods. State it vocally, agree to it in writing, post the message on a poster, add it to a code review checklist, and find other ways to drive the message home.

We all learn from experience. How well we respond to failures depends on our capacity and desire to improve ourselves, our teams, and our systems.

Agile Principles #11: Don’t micromanage.

The best architectures, requirements, and designs emerge from self-organizing teams.

Some managers feel they need to control every action and decision. By micromanaging every detail, they have a stronger feel for the status of the project. They believe that they know better than the staff on what course to take for every decision. This allows them to write up nice status reports and Gantt Charts and deliver updates to their own managers.

There are many problems with this.

The first mistaken assumption is one of knowledge. The manager is not knee-deep in the code like the engineers are. There is no way the manager can understand the difficulties to come as well as the people who actually have to overcome them. The people with the best information about the challenges ahead are those with the boots on the ground.

The next issue is one of intelligence. Just because someone is a manager does not mean they are the smartest person in the room. Given that you generally want to hire the most intelligent people, it should be a safe assumption that you’ve managed to hire people smarter than you.

Finally, there is the matter of responsibility. When the manager makes all of the decisions, the team feels less responsible for the outcomes. It is much preferable to want the team to own the responsibility for the delivery of the software. This often does not occur when the team is being micromanaged.

Instead, decisions should be made by self-organizing teams. Have the right people come together and come up with a plan of their own. Because they are making the decisions, they will feel more responsible and be more invested in the outcome.

There are some related ideas to this which go beyond management. One of these is never to work alone. Software engineering is a team sport. Developers that work solo fail to benefit from the knowledge of their peers. Their bad decisions are not caught until much later. Always work with others.

When working in teams, remember that everyone is valuable and can contribute. Some teams prefer that only the senior people talk and make decisions. This is a mistake. Just because someone has less experience than others does not mean that they can’t have good ideas.

Empowering others and supporting your co-workers is good leadership. Dictating their every move is not.

Agile Principles #10: Keep it simple, stupid.

Simplicity — the art of maximizing the amount of work not done — is essential.

One of the biggest problems with developing enterprise systems is the amount of needless complexity that inevitably is added by well-meaning engineers. For various reasons, they will add tons of code and features that aren’t absolutely necessary. Some of it will be speculative, some of it will be out of ignorance, but all of it will cause headaches down the road. And it’s sad, really, because much of that pain could have been avoided.

A simpler system is almost always better. There’s less code, and therefore fewer things to go wrong. Being simpler, it’s easier to fully understand, which helps to prevent logic errors. It also requires fewer tests to cover.

To get a simpler system, build only what you need for the current requirement. Don’t speculate about possible future features. Don’t add extra parameters to the API unless they are absolutely called for. Keep it as simple as possible. Write tests to cover the requirement. Write code to satisfy the tests. Clean up the code. Then stop.

Additionally, use your framework and libraries instead of writing your own code whenever possible. This requires a thorough knowledge of the capabilities of your tools. It’s a challenge at times, but anytime you can replace some complex in-house code with a call to a well-supported library, it improves your code. And whatever you do, never invent your own frameworks.

Agile Principles #9: Commit to mastery.

Continuous attention to technical excellence and good design enhances agility.

Be awesome. The best way to become awesome: always be learning. Take every opportunity to learn more about your craft. Read books and blogs. Watch video courses. Attend conferences. Discuss technical issues with your peers.

Learn the SOLID principles. Commit yourself to writing clean code. Study and follow the best practices of software engineering. Avoid writing brittle code.

Work with a plan. Application architecture isn’t just a fancy word. Developers who plot out an intelligent plan and follow it through have more success than those who blunder through problems blindly.

And most of all, try to minimize the creation of technical debt. Sometimes it is unavoidable; the world is not an orderly place. Whenever you can, you should pay down technical debt while delivering new business value. Maybe you can include some high-quality refactoring as part of the delivery of a new feature.

Agile Principles #8: Maintain a healthy pace.

Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.

For most projects, the duration is measured in months or progresses endlessly. The team is always developing new features and expanding the product offering. In such environments, it is crucial that the team can maintain a healthy pace and never exhaust itself.

A long-running project is similar to a marathon; you can’t run full-out, or you’ll collapse and fail to finish. A marathon is not a series of sprints. Too many teams try to push extra hard every two weeks, with the last couple days having a bunch of stuff jammed in recklessly. Other teams have managers who crack the whip put the team on a death march for months at a time, to be followed by yet another death march.

These same managers also find it difficult to recruit great people and often have to deal with high turnover rates. Word gets around. There are many places to work in software development. People have a variety of options.

Another key factor in team longevity is the physical health of the team members. It is important for everyone to eat healthily, get some exercise, avoid illnesses, and reduce stress. Healthy developers will be more productive and will be able to put in more hours than those who are frequently exhausted or sick. Anything the team can do to promote a healthy lifestyle should be encouraged.

Agile Principles #7: Measure the right thing.

Working software is the primary measure of progress.

The entire purpose of the enterprise is to assemble software that the business can use to drive revenue. Towards that end, only working software will suffice. There are many byproducts of the software development process; lines of code, collections of tests, pages of documentation, processes, procedures, closed tickets, and more. None of these things matter. Only working software matters.

Some development teams will get hung up on other metrics. What is the code coverage? What is the developer velocity? What is the closure rate on feature tickets? How many defects per release? What is the cycle time? How many unit tests are there? What is the average cyclomatic complexity? The statistics are endless.

These statistics have a purpose. They guide the developers towards better development practices. They give managers some measures to determine the effectiveness of the team, both at the group level and at the individual level. The statistics have value within the development process.

All of this is secondary, though, to the ultimate goal. The team needs to deliver working software. Only through the delivery of working software will the business make money.

A related topic to this is the concept of “done”. For some, a ticket is “done” when they finish development of the story. For others, it’s done when it passes code review and enters the mainline. Maybe it’s done when they pass a feature over to QA. The problem with these is that the code is not delivering business value until there is working software in production. Since working software is the measure of progress, then a feature is not done until the software is in production, working for you.