More for my personal future reference, but perhaps this may be useful to someone.
I’ve been trying to improve my programming, striving for clean, elegant, maintainable, readable code. Over the last couple days, I tried to understand how a one-off PHP page might be coded in an object oriented manner. Each possible architecture resulted in classes that were purely containers for smaller code snippets. They weren’t particularly testable and weren’t easy to read. There was also a lot of them, resulting in a ton of code for a small app.
On a whim, I decided to learn more about procedural programming, the very thing I was trying so desperately to avoid. I discovered that I may dislike procedural code simply because it always turned into spaghetti in my hands. But it was probably my fault, rather than the fault of the methodology. Here are some thoughts…
I made all of my code exit at the bottom. This meant making sure that all my code flowed to one exit point. This worked rather nicely, since the code really was designed to output a page at the end, unless an error occurred.
I caused all error states to throw exceptions, which I handled at the bottom. This is the part I’m least sure about, as far as best practice goes. The main flow of the code was all in a try block, with a series of catch blocks at the bottom. I created a number of simple subclasses of Exception in order to categorize types of error states. Individual error types were handled by codes which I set as constants in the exception classes to make it easier to follow. Since all errors should output an error page, this made it very easy to reduce code duplication within a catch block. It also allowed me to easily handle more errors. Prior to refactoring, I disliked checking for and handling possible issues, since it involved another level of if/then statements and a bunch of code inline which made the main flow very hard to follow. By simply checking for an issue and then throwing an exception which was handled at the end, the main flow of the application wasn’t interrupted by error handling, and I was happy to be more careful and check more things. Hopefully this will result in a more robust application later.
I eliminated most functions. My reason for this was to try and reduce code duplication within main flow of the application. It also made the code easier to read. By writing all of the code as one large block, it was easy to follow the logic, and easier to debug.
This code was essentially procedural and small enough for this methodology to work well. I needed an easily readable, robust, maintainable set of code, and embracing procedural programming helped in this endeavor. If the application were larger, I think it would fall apart, and I would go back to a properly architected OO methodology.
Hopefully, a step forward in my development as a software engineer, and another tool in my proverbial toolbox.