Throughout my career, I have picked up a few practices to help increase the success of my projects and improve my own software development abilities. I will frame these practices through the lens of IVR systems, but most of them can be applied to any software domain.
1. Understand the Problem
Every software project is attempting to solve a problem or address a need. If you are lucky, the problem will be something you are intimately familiar with and you will be able to pull in your own experiences. More commonly, a client will bring a project to you which you are unfamiliar with. In order to properly come up with a solution, you will need to understand what the underlying problem is. If you do not take the time to figure this out, you may find that the solution you create does not completely solve the problem or makes it worse. Spending a little extra time up front to really understand the issue can go a long way to ensuring your project is a success.
2. Plan Test Cases and User Interaction Up Front
A software project, at a high level, is a collection of user interactions. A user could be someone calling on their phone to pay a bill, it could be someone on a computer looking up cat pictures, or it could be an automated server process connecting to an API to request how many widgets are left in stock. Regardless of the number of abstractions, a person is involved and cares about solving a problem.
When initially designing a project it is generally easier to think about the normal interactions or flows through a system. For example, a user calls into an IVR to check their account balance and pay any outstanding bills. Generally, it is harder to come up with exceptional cases outside of the normal flow. This form of thinking is usually more “What if…” based. What if the API is down? What if the caller’s credit card is denied? What if, instead of saying their account number, the caller starts singing Rick Astley’s Never Gonna Give You Up?
Once you have thought of all the normal and exceptional flows through your project, you can then write up the test cases that you plan to support. This step will give you a lot more confidence that you are building your solution correctly and provides a nice reference when you are ready to actually test out your implementation.
If you wait too long or do not plan your test cases at all, you are at risk of missing something important. Finding missing use cases that you need to support later will cause disruptions based on when the issue is discovered. In the best case, you will find the issue early in development and will be able to fix it without major rewrites. On the other end of the spectrum, you may never find the issue yourself and are instead woken up at 2 in the morning when the client finds it for you.
Planning test cases upfront, or at all, also makes it easier to implement automated testing. While they are not required for a project to succeed, you may find that having automated tests gives you peace of mind that your implementation works while you are developing it and later when you inevitability modify it.
3. Implement in Short Iterations
Software projects, regardless of size and complexity, can benefit from planning and scheduling work in short iterations. If you subscribe to generally accepted agile methodology practices, these iterations should be no longer than one or two weeks long. Short iterations allow you to quickly get feedback on your implementation by allowing clients or testers to play around with functionality as it is added. For example, if you are building a payment IVR, you may first want to build the functionality that looks up a caller by their account number. Once you have that functionality, you can show it to your client. From here, the client may say that they imagined something different and ask for changes. Changing requirements is, unfortunately, an inevitable part of all software projects, but you can reduce the disruption it causes if you can quickly find out when your mental model of the solution does not match your client’s.
When developing software, you will sometimes find that a customer is unable to fully articulate the problem they are trying to solve. Ideally, this will be straightened out before development starts. However, sometimes it can be helpful to create a quick and small prototype. The customer may not be able to describe the correct solution, but they may find it easier to point to something that is incorrect. Iterating quickly on this prototype can make it easier to nail down the actual requirements, and if you are lucky, you may be able to use the prototype as a starting point.
Projects that involve more than one person also greatly benefit from short iterations. These iterations allow you to integrate the codebases more frequently. The longer you wait to integrate diverging codebases, the more difficult and error-prone it becomes.
Outside of the actual implementation of the project, short iterations can help with planning and scheduling. They force you to break your software up into smaller chunks that can fit within the calendar time you have chosen. This process has the added benefit of making a large and complex project feel more manageable. If you have an IVR that needs to be able to take payments, activate accounts, and handle general customer support, you may find that breaking the project into smaller pieces makes it less daunting.
4. Never Stop Learning
Software development is a continually evolving field. Languages, programming paradigms, and frameworks quickly go in and out of style as developers look for better abstractions and more elegant designs. One of the most useful things you can do to improve yourself as a developer is to observe what others are creating. You do not have to and probably should not use new bleeding edge software for anything mission-critical. Instead, you should be looking to figure out what the developer’s goal is and how they go about achieving it. With this information, you can pull out the pieces that you find useful. You will also run into plenty of cases where you disagree with how a developer goes about their implementation or even the goal they are trying to achieve. This is still valuable information you can use and will shape how you go about solving your own problems.
These are just a few general practices I use to make myself a better developer. Take the pieces that you agree with, expand on them, and go out and build something great!