There are some principles in software development that are taken for granted among, say, Java or Objective C developers, that seems to escape a large number of Flash / Flex developers. The reason for this is possibly that a lot of Flash devs are actually designers who have moved into development (I would say “failed designers” but that sounds a little harsh - so let me soften it by saying that I am quite average at graphic design myself).
Whatever the cause, the result is that there are a lot of Flash devs floating around who have learnt how to build websites and make things happen in ActionScript, and take the attitude that it’s all good “so long as it works - nothing else matters”. I have heard this many times, and read it many times on forums and the like. Allow me to gently correct this view. The fact something “works” is not good enough - it’s a meagre baseline. A professional developer (by which I mean anyone who gets paid to code) should make sure that not only does the software work, it is easy to maintain and extend, and that another developer can pick up where s/he left off. Always strive to make yourself redundant - if the client or employer needs you and you alone to maintain the code, because you “know where things are” then you have done a terrible job and do not deserve to be paid.
OK, enough lecturing. What’s the biggest thing you need to learn in order to write good software? There are many things, but the one I find most commonly lacking is a very simple one. Think of it as the First Commandment:
Avoid unnecessary dependence.
What does this mean? A piece of code (an object, a module, whatever) depends on another piece of code if it needs to access it in order to work properly. Let’s take a simple and practical example: in an application, there is a remote proxy object that fetches data from the backend, with a requestData() method, which takes a JSON object as its argument. It implements IEventDispatcher and dispatches an event containing a JSON object - the data from the backend. There is also a toolbar object with some buttons on it. When the user clicks the button, data needs to be fetched and displayed on a display panel. The toolbar object contains a reference to the remote proxy object, and so does the display panel. When a button on the toolbar is pressed, the data is requested; when it comes back, the display panel handles the event, decodes the JSON object, and displays it.
How does that sound? (It’s not an artificial example, I am actually describing a small part of a legacy system I once inherited - by no means the worst code I’ve seen.) If the problems are not already glaring out at you … read on.
The problems are these: imagine you have to change the backend from JSON to remoting, or web services. What things have to change? In my example, all three main objects: the toolbar, the display panel, and the remote proxy. In a good system, only the remote proxy should change. The toolbar should not even know what “JSON” means, and nor should the display panel. There is an unnecessary dependence there. Another problem. You have spent quite a while on your toolbar and now you want to use it in another project. But you have to rewrite a substantial amount of code, because it depends on the remote proxy and its specific implementation. Third problem: the user navigates away from the display panel, then comes back. The data is missing. Because the system depends on the display panel staying in memory when it blatantly should not need to.
There are many approaches to solve these kinds of problems: the MVC pattern, Inversion of Control, Façade, Proxy (I am not suggesting these are equivalent; the common thread is that they all solve problems relating to dependence). None of these is a silver bullet that will cure your code. Get the basics right first: the idea that your objects should know as little about each other as possible, like Leibniz’s monads, should be ingrained in the fibre of your being. Get yourself into good habits. If there must be dependence, it should be on an interface, not on an implementation. Only make methods public if you have to. Avoid globals. The Singleton pattern when used as a pseudo-global is an anti-pattern. Avoid dynamic objects - this is the worst kind of dependence - dependence on runtime behaviour.
I could keep adding specifics, but they are all just manifestations of the First Commandment. Learn it, live it. And stop building legacy horror shows for the next generation of developers to inherit.




Recent Comments