| « Cliff Hall on PureMVC - Video | Genetic Algorithm Evolves Better Car Using Flash » |
At my last job I met a software architect who, for a Flash project, jumped in and learned ActionScript in what must have been a few hours so he could work on the domain logic for a complex application. Just for background, I believe he primarily worked with .NET but you know how programming works… hours spent * natural ability = language independent skill.
Suffice to say he was indeed an extremely good coder and I’m grateful he spent some time passing on a few tips and tricks that apply to all languages, and some nice demonstrations using Haskell, ActionScript and of course C#. One such tip was the use of “pure functions” for example, which is always in the back of my mind now. (As a side note, I think learning a very different language like Haskell or in my case Ruby is a great way of keeping your mind open and it will help with your “daily” language).
Another of those tips went something like this: “hey, you know these switch statements, you can pretty much get rid of switch statements in an OO application using polymorphism". For those a little unfamiliar with that term, in ActionScript this could be achieved by subclassing a superclass several times. This statement turns out to be, on the whole, true. A switch statement can a lot of the time be reflective of a problem in the architecture, a coupling of code, and by simply introducing interfaces and polymorphism into the equation you can refactor it down to maybe 2 lines from however many switch-cases. Overall there may be more code in separate classes, but it’s a lot more elegant, maintainable, extensible, readable, and most importantly, testable.
That brings me to the subject of this post. Making testable code is actually one of the best ways of writing *better* code. The Google Testing Blog has some of the best posts I’ve ever read on the subject of better coding. The latest post is on the very subject discussed in this post.
The Google Testing Blog.
12 comments
Comments are closed for this post.
Follow me on Twitter
Thank you
The reason for limiting a function to one or the other is to reduce the amount of things that can go wrong when you call it. The function is perfectly isolated from external influences and as such you can accurately predict the pre and post conditions for calling this function (you can usually do that anyway but this guarantees it). The result is a more stable application that is more easily tested and experiences fewer exceptions.
Perhaps one example of a side-effect you may have experienced when starting out programming would be the "remove these values from this array" conundrum. You have an array of 15 numbers ranging from 1 to 5, you want to remove all "5's". At first you attempt to loop through the array from 0 to array.length, and when you find the value you splice() it out. Only in doing so you've now altered the length of your array and the next iteration through the loop will mean you might end up overshooting the new length of the array. The solution is as simple as looping through backwards instead of forwards, but it illustrates the perils of operating on an object whilst at the same time querying it.
In the context of a complex application, these inter dependencies can manifest themselves in much worse and hard to track down ways.
For another reason also see Referential Transparency:
http://en.wikipedia.org/wiki/Referential_transparency
For even more reading see how functions in Haskell are pure:
http://www.onlamp.com/pub/a/onlamp/2007/07/12/introduction-to-haskell-pure-functions.html
I hope that helps!
Thank you for your time.
http://www.as3dp.com/2008/11/09/actionscript-30-strategy-design-pattern-under-no-conditionals/
I love the idea of not using if/switch/conditionals. Makes your coding so much cleaner and easier to maintain.
It's old news I know, we were all doing this in Flash 5 but a lot of new dogs might wanna know some old tricks.
http://www.moock.org/asdg/technotes/bitwise/
http://www.elitecoders.de/mags/cscene/CS9/CS9-02.html
Thanks for the tip though, I had to step back from learning the patterns as I found myself getting a little pattern happy : when you've got a shiny new hammer everything looks like a nail and all that.
Top Blogging Richard.
I've been reading quite a bit about unit testing / TDD etc recently, and I can see how it would be very useful on full scale software products, but can't really see how to apply it to the kind of Flash stuff I do. Automated testing of user interfaces seems futile, and there isn't much business logic within my Flash code. Any thoughts on that?
@Ian, funny you should mention that, I was just running FlexUnit on an AIR app I've started the very second I got the comment. There were actually two guys who came from a more classic development background that I was working with on the project mentioned in the post (this was quite some time ago now so if I got any details wrong hopefully they forgive me), anyway both of them vehemently supported TDD... I fought it at first but it makes total sense for applications, well actually it works extremely well for anything that is very "data" driven, it was in fact the ONLY way we could possibly implement the level of complexity/business rules required and have confidence in it with the thousands of boundary cases and combinations possible. Ultimately the test suites were the thing that (having taken what I considered too long to write), led to a very rapid development workflow that paid for itself many times over in developer time, particularly when adding features or working in a team.
So I can totally agree that for a lot of websites, particularly the creative stuff it doesn't make sense at all to shoe-horn TDD in there, however possible it might be.
But anything that does fit nicely into the MVC paradigm might also be a good candidate for TDD, because you can always test the "M" independently, but as you say, this really involves being able to test the business logic. You can also use tools to test UI's with Flex, but in Flash it's not so feasable nor particularly useful in the context of an "experience" piece.
For the most part I find that in almost any Flash work, website, game or application, there's something testable. For example in a website I might load data from XML or CMS, and parse that data. Here are my candidates for testing, my domain model and my parsers which are in almost all websites.
I second all that, exept
>polymorphism
>readable
in a switch statement you at least see at a glance what's happening, otherwise you'd have to sift through a couple of classes first.
Occasionally an advantage in our fast-paced agency biz.. particularly when dealing with other people's code. ;)
That is, if the number of cases is huge and likely to increase you should avoid switch, of course.
Cheers, Dan