I have previously already touched on the development methodology I'd like to follow for my projects and it's time to revisit that. To be quite honest, I did not actually follow that approach until quite late in development and the consequences of this are already showing their ugly faces.
There are a lot of different mindsets or methodologies for programming out there, all of them with their own sets of supporters and opposers. I'm not really one to go learn about a way of doing things and then trying to force myself into this mindset to see if it works well. I need something that sits well with me and feels right and comfortable from the start. A methodology is only productive when it works for you and forcing it because of its supposed productivity margins is the wrong way to go about it.
When writing programs there is a constant issue of re-usability. This issue leads to the desire to make code extensible and encapsulated. What this means is that components should be self-sustaining and keep interaction to other components to a minimum so that they can be re-used at a completely different part in possibly a different application altogether without any adjustments. It also means that the application should be pluggable, you should be able to simply “attach” new parts and it should neatly integrate with everything else while sustaining a minimal effort. Of course this is purely wishful thinking. Nevertheless, the desire to go this way is strong and it is an evil mistress at that.
Making code extensible is, while it sounds extremely nice, a trap. It is a trap because it takes an immense amount of time to do it, while not actually solving any problems. It lures with the promise of solving problems in the future, but it won't solve anything right now. This would be all fine and dandy if coding was an entirely linear process. Sadly we cannot predict the future well at all, so this promise is a false one and it will be neglected. Estimating what issues might arise in the future is a very futile task and by extension so is making your code extensible. You may spend hours and days figuring out an architecture and interfaces to make the system neat and well extendable, just to end up never using it. Worse still, you will end up tripping over your own building blocks as the design will most likely end up being way too complicated.
It is certainly required to make your program extensible at times, but this should only be thought of when it is the primary goal at hand, never because of some issue that might arise at some point in the distant future, maybe. Usually this is non-issue because you simply lack the time to create such a complicated system. After all, you have deadlines to meet, angry colleagues or superiors to fear or you simply cannot waste time due to another circumstance of your life. While this push to forget about the beauty of a program and simply get on with it is always a nagging annoyance in the back, I see it as a necessity.
I've spent most of my time working on projects of my own, for myself, with no one else to care. This gave me the ultimate freedom to work on whatever I wanted for however long I wanted and however I so desired. I've had the over-architecturing problem in almost every single one of my projects. It is high time I learned to avoid this time sink and force myself, at least a bit, to do the right thing.
The right thing in my mind is to think from top to bottom, rather than from bottom to top. The key thing to do is to interact with the system itself, to be able to use it and build from it. This holds true whether it is an API or user application. In the case of an API the first thing to do is to write down the last function call or set of calls that you want to be able to execute to do all the work. At this stage it is of utmost importance to think about making it as easy and simple as possible, while retaining enough flexibility to go down as deep as you might desire. In the case of a UI I would think about how to make the layout pleasing to look at and easy to get around, but also try to keep customizability and settings to a maximum without being obnoxious to the user.
This approach forces you to think about what your actual goal is, what you want to achieve. It also frees you from any thoughts about architecture or any of the complications that arise within the system. Creating a well defined interface like this helps enormously with encapsulation and gives you a clear goal to look forward to: Being able to invoke this function and have it just do all the magic on its own.
In case you're worrying that this approach would undermine the importance of architecture design and it would somehow result in unmaintainable code, fear not, as that is not an issue. This methodology does not concern itself with anything past the point of the interface. It merely demands that this is the first thing you think about and give the most importance to. However you want to implement this functionality inside the black box is free. However, you can also draw it further and apply this methodology to functions and interfaces inside your application as well. Split up the work into small pieces and work your way down until there's only a small jump required to the underlying interfaces you're basing yourself on.
As I mentioned in the beginning, I have not followed this approach for a large part in Radiance's making and I am rather ashamed and angered about this. I have already wasted a huge lot of time with overcomplicated architecture, just to realise that it is all bollocks. I then spent a few nice minutes dreaming up some sweet interfaces, just to realise that they are actually quite simple to implement and would make everything so much more pleasant. After that I had to tend to the dreadful task of cleaning up my previous mess and going over everything to migrate it to the simpler system.
I want to minimize having to repeat this rubbish as much as possible, so I really want to get myself to follow this interface-first mentality. I don't expect to be able to switch immediately, I too will have to get used to it. Regardless, it seems already more than evident to me that this mentality is a good one and one that will help me in many situations to come.
Next time: Building a Radiance module from the ground up with a simple example application.
Written by shinmera