Tuesday, May 11, 2010

Fluent Sort builder example in ActionScript

After reading Growing Software i created a factory to create sort objects in ActionScript. It allows you to create sorts like this

var s : Sort = new SortBuilder().byField("status").asString().ascending().byField("date").asDate() .descending().build();


I think, it makes the creation of sorts much more readable. However, now i have to refactor the whole codebase and to educate my coworkers to use it. That's the worst part of it ;)


PS. Xavi published a nice introduction to fluent factories.

Thursday, April 1, 2010

Memory leaks? Yes indeed!

Phase I: Memory leak? No way!
I wasn't convinced when the testers said our Flex app has leaks. I thought it has to do with their machine's configuration or browser or whatever. Even when people came and said, they can see the app leaking in the Flex profiler i wasn't convinced, because i thought the profiler would be lying. In the past i rarely saw our apps leaking so i really thought it is false alarm. Also the randomness of the garbage collector helped to keep me in this mood of false safety.

Phase II: Memory leak? Indeed!
Since the potential bug had a huge impact on the success of the project and we were in the stabilization phase of the project, i had to find out, if it was real.
So what i did to convince myself, was to isolate a small part of the app and create a test app from it. And boom, the leak was clear to see in the instance counts of the profiler.

Phase III: Memory leak? The hunt is on.
First you need to find a set of steps, which clearly demonstrates the leak in the profiler. Ideally you automate this, because during your hunt you will execute these steps again and again.

Then you need to find the leak. Finding out about a memory leak in code, which otherwise looks perfectly good, needs a special mindset. You need to be suspicious about everything really. For me the best way to find it, is to reduce the search space by commenting as much as possible code out, until the leak doesn't show any longer. Then you go backwards by commenting pieces back in, until you see the leak. You can use a approach similar to binary search. You start with commenting in bigger parts until the leak shows, then you split this part and comment out smaller parts until it is gone and so on. Eventually you will find the leak hiding under a place you would never expect it ;)

Phase IV: Memory leaks? The candidates.
So now you have a suspicious line of code. To make 100% sure it is causing a leak, you create a small test project now, which demonstrates the leak in isolation.

Phase V: Memory leaks? The fix.
Now that you know what is causing the leak, you can go through your codebase and fix all the places which contains the suspicious code. If you are lucky, the leak is fixed now. Most of the time there will be no change at all though, because there are other leaks left. So you need to iterate this process and start again with Phase III.

It is a daunting process. I found it useful to pair with a colleague, so when you find something, your colleague can try to reproduce and confirm your theory. Eventually all the leaks are fixed and your app is ready to shine! Puh.

So much for the general process. More specifically we found leaks in our usage of BindingUtils. You need to make sure, that unwatch is called. Also some listeners needed to be removed or to be changed to weak listeners. We found that the SetEventHandler tag in a mxml state was leaking. And last but not least the Degrafa library was leaking, which is used for skins.

Halali (the german death-haloo),
Ralf

Wednesday, March 17, 2010

Testing all permutations of calls to setters via functional programming

Today i had this class, which has multiple setters and updates bindable properties from the values of these setters. When i wrote a unit test for it, i realized, that i don't know in which order the setters are called. So in principle i had to test all the different orders in which the setters can be called. Al different orders of a list, that's permutations. The class had three setters, which makes for 3! = 6 permutations.

I didn't want to do it manually, so tried to find a way to let the computer do it for me. What i did is to create a function for every call to a setter and a function for the assert. These functions are passed into the assert function like so:


[Test]
public function whenSearchFormIsUsedInStoreContext_thenCountryChooserShouldBeSetToCountryOfTheStore():void
{
storeShortcut.countryCode = country2.code;

var setter1:Function = function():void
{
pm.countriesList = new ArrayCollection([ country0, country1, country2 ]);
};
var setter2:Function = function():void
{
pm.currentContext = RecordsModel.IDENTIFY_CONTEXT_STORE;
};
var setter3:Function = function():void
{
pm.currentStore = storeShortcut;
}
var assert:Function = function(permutation:Array):void
{
assertThat("country2 should be selected, permutation <" + permutation + ">",
pm.selectedCountryIndex,
equalTo(2));
}

assertThatAllPermutationsOfSettersHaveTheSameResult(setUp, [ setter1, setter2, setter3 ],
assert);
}



Now the method can calculate all permutations of the setters array and call the setters accordingly. Works like a charm.

But beware. Faculty is a fast growing function. 7! is 5040 and 8! is 40320. So this method works for a small number of setters only.

Saturday, February 27, 2010

Selfdocumenting code vs generic names

Some people like their generic names. Every method is named like update() or handleEvent() or init() etc. These names are not very much selfdocumenting. Therefore these methods come with comments very often. The comments explain, what the method does. However, comments are evil, as we all know.

The ideal method does one thing and has a name, which clearly identifies this thing. A proper name helps the reader to understand what it does, without having to read the code. Or at least it gives him a hint about your intentions.

Actually that's another good point. Expressing the intention of the method gives the maintainer the possibility to change the code while keeping the intended functionality.

Sometimes the methodnames are declared by a interface though. In that case you have to use the more generic names. However, inside the method you can call your nicely named methods again. So you still get the benefit from properly naming them.

And don't be afraid of long methodnames. However, try to avoid to use "and" and "or" or something similar to connect disparate things. This is a hint, that the method does more than one thing and probably should be refactored.

Friday, February 26, 2010

Refactoring vs business

In our current project the business officially hates the word refactoring. And right so.
Today every attempt to "improve" the code is called refactoring. However, the original term, as introduced by Martin Fowler's book "Refactoring", ment something different. It ment something much more narrowed than just improving the code.

Refactoring means improving the code in tiny and clearly defined steps, while always keeping the original functionality.

First of all, most of the projects i have seen so far, do not have enough test coverage. So you can't really be sure, if the functionality remains intact. Secondly, a lot of people don't even bother to add new tests while they refactor. Which means they don't even know, what functionality is there after the refactoring. And last but not least, the approach of tiny little steps, hasn't really made it into the devs mind at all.

The outcome of this adhoc "refactoring" doesn't come unexpected. Most likely you will see many things breaking or even missing after the refactoring. And this makes the business crazy. They don't like to pay somebody for breaking existung features.

So what can we do about it? First of all, don't use the word refactoring if you mean a plain rewrite. Secondly, avoid the word refactoring when talking to the business. They don't really understand what quality of code can buy them. This way you don't have to use the word refactoring when you talk to the business.
Imho we should be refactoring all the time, if we see some smell in the code. However, newcomers might see smells where oldtimers don't. So, before you refactor, talk with your fellow developers about it. Last but not least, if you refactor, make sure you do it right. Don't leave out the tests. They might not cover everything, but they should give you a good baseline of confidence in your code.

I promise, if we all follow these practices, one day, we will see the business beeing happy about refactoring :) At the latest, if they ask you for new features and you can build and integrate them easily without breaking things.

More than 10 years in Flash. Great time!

Wohoo. When i woke up this morning i realized, that i'm doing Flash related work for more than 10 years now. What a journey. It was great fun and the time just flew by. However, I wonder, what the future brings? Will there be a Flash player in ten years from now?

Thursday, February 4, 2010

Hellfire -> multicore flash compilation

I've been playing with Hellfire lately. It is a interesting project, which uses a compilation server to achieve faster Flash/Flex compilation. Have a look for yourself at http://stopcoding.org/. Clement is very responsive, if you need help.

One particular interesting configuration, which is made possible by Hellfire, is to run FlashBuilder on your laptop and delegate the compilation to some other, maybe more powerful machine under your desk or somewhere else in the world :)

Tuesday, February 2, 2010

Downloading from Flex

In you case you didn't know as i did, it is simple to create a download link in Flex using FileReference.download( request );

Monday, January 25, 2010

Making it obvious is hard to do

It is always interesting to join a project which has some code already. Our code is supposed to be self documenting and easy to read. However some of the code i have seen so far is not. Let me give you one example.
The following code is part of a search feature. It contains two different forms and a result screen. The two different forms allow the user to either search by the details of a person, eg. name and address or by some ids, which are assigned by the system. The following method is part of a presentation model for the forms. It is called, whenever one of the forms dispatches a change event (user tabs out of a input field.)


public function handleSearchFormChange() : void
{
if ( ( detailedSearchFormPM.criteria.isValidForSearch() || uidSearchFormPM.criteria.isValidForSearch() ) )
{
if ( detailedSearchFormPM.validatorGroup.validate( true ) )
{
searchEnabled = true;
}
else
{
searchEnabled = false;
}
}
else
{
searchEnabled = false;
}

if ( detailedSearchFormPM.criteria.isValidForReset() || uidSearchFormPM.criteria.isValidForSearch() )
resetEnabled = true;
else
resetEnabled = false;

}


What does this method do? The name doesn't tell us. Instead is is named after the event it is supposed to handle. So instead of abstracting away some concept, this method makes the code even less abstract by introducing additional information, which is not needed here. Is there a bug in the first part? Should the search button only be enabled if the detailed search contains valid data?

In the mxml code you can see the method beeing used like so


<... change="pm.handleSearchFormChange()" .../>


So at the level of the mxml code the information is pretty much duplicated. By looking at the mxml code alone, we are not able to guess, what this method is doing.

Now lets look at the code of the method. It updates two properties searchEnabled and resetEnabled. These properties are bindable and are connected to enabled property of the two buttons search und reset. However, what rules are used to calculate these properties, is not obvious from the code. The code accesses inner objects of the FormPMs, not good, because it ties us to the implementation of these PMs. (Law of Demeter)

Let's see, if we can refactor the code a bit.


public function handleSearchFormChange() : void
{
enableButtonsIfFormsContainInput();
}

private function enableButtonsIfFormsContainInput() : void
{
enableSearchButtonIfFormContainsValidInput();
enableResetButtonIfFormContainsAnyInput();
}

private function enableSearchButtonIfFormContainsValidInput() : void
{
searchEnabled = detailedFormContainsValidInput() || uidSearchFormContainsValidInput();
}

private function detailedFormContainsValidInput() : Boolean
{
return detailedSearchFormPM.criteria.isValidForSearch() && detailedSearchFormPM.validatorGroup.validate( true );
}

private function uidSearchFormContainsValidInput() : Boolean
{
return uidSearchFormPM.criteria.isValidForSearch();
}

private function enableResetButtonIfFormContainsAnyInput() : void
{
resetEnabled = detailedSearchFormContainsInput() || uidSearchFormContainsInput();
}

private function detailedSearchFormContainsInput() : Boolean
{
return detailedSearchFormPM.criteria.isValidForReset();
}

private function uidSearchFormContainsInput() : Boolean
{
return uidSearchFormPM.criteria.isValidForSearch();
}


This would be start to make it a bit more readable. Now a next step would be to move some of the methods to other objects. All the methods which are concerned with the inner details of one of the FormPMs should be moved to the FormPMs. The resulting code looks like this.


public function handleSearchFormChange() : void
{
enableButtonsIfFormsContainInput();
}

private function enableButtonsIfFormsContainInput() : void
{
enableSearchButtonIfFormContainsValidInput();
enableResetButtonIfFormContainsAnyInput();
}

private function enableSearchButtonIfFormContainsValidInput() : void
{
searchEnabled = detailedSearchFormPM.containsValidInput() || uidSearchFormPM.containsValidInput();
}

private function enableResetButtonIfFormContainsAnyInput() : void
{
resetEnabled = detailedSearchFormPM.containsInput() || uidSearchFormPM.containsInput();
}


Now we have to decide if we really want to know, when the entry method is called. Instead of the method name we use the event parameter to tell us when the method is called.


public function enableButtonsIfFormsContainInput( event : FormsInputChangeEvent ) : void
{
...
}


and in mxml it looks like so



<... formsInputChange="enableButtonsIfFormsContainInput(event)" .../>



Now the code reveals much more about its intention. If somebody needs to fix this code or to add another feature, it is much easier to do so, because it is obvious, what the code is supposed to do.


Best,
Ralf.

Saturday, January 9, 2010

What i'm up to: C++, Qt, Release It

I have a few days of, which allows me to spend some time on learning a new language. I choosed C++ this time. For the GUI i use QT, which has some nice abstractions like signals and slots.

On my book shelf i have "Release it" by Michael T Nygard. It is about architecture for production versus architecture for the ivory tower.