Monday, September 22, 2008

Darren on Flex: Overloading the Constructor - Revisted

This is just a follow up to Overloading the Constructor to elaborate on my response to a comment made by Ben. I show how to:
  • Hide the public constructor by hiding the implementation class.
  • Expose the class via an interface.
  • Provide arbitrary factory methods in a factory class.

The Interface

//example\IPerson.as
package example {
    public interface IPerson {
        function get fullName():String
    }
}

The Factory and Implementation Class

//example\PersonFactory.as
package example {
    public class PersonFactory {  
        public function newPersonWithFirstName(firstName:String):Person {
            return new Person({firstName: firstName});
        }  
        
        public function newPersonWithLastName(lastName:String):Person {
            return new Person({lastName: lastName});
        }  
        
        public function newPersonWithFirstAndLastName(firstName:String, lastName:String):Person {
            return new Person({firstName: firstName, lastName: lastName});
        }  
        
        public function someDudeWithOnlyMiddleNames(... middleNames):Person {
            return new Person({middleNames: middleNames});
        }
        
        public function andTheFullShaBang(firstName:String, lastName:String, ... middleNames):Person {
            return new Person({firstName: firstName, middleNames: middleNames, lastName: lastName});
        }
    }
}

import example.IPerson;

class Person implements IPerson {
    private var firstName:String;
    private var lastName:String;
    private var middleNames:Array;
    
    public function get fullName():String {
        return firstName + (middleNames ? " " + middleNames.join(" ") + " ": " ") + lastName;
    }
    
    public function Person(params:Object) {
        for (var property:String in params) {
            this[property] = params[property];
        }
    }
}  

The FlexUnit Test (for good measure)

//example\PersonFactoryTest .as
package example {
    import flexunit.framework.TestCase;

    public class PersonFactoryTest extends TestCase {
        public function PersonFactoryTest(methodName:String=null) {
            super(methodName);
        }
        
        public function testCreatingBenjaminNortier():void {
            var factory:PersonFactory = new PersonFactory();
            
            var ben:IPerson = factory.newPersonWithFirstAndLastName("Benjamin", "Nortier");
            
            assertEquals("Benjamin Nortier", ben.fullName);
        }
        
        public function testCreating21stCenturyCodeWorks21ccwblogspotcomBenjaminNortierWith():void {
            var factory:PersonFactory = new PersonFactory();
            
            var ben:IPerson = factory.andTheFullShaBang("Benjamin", "Nortier", "21st Century Code Works", "21ccw.blogspot.com");
            
            assertEquals("Benjamin 21st Century Code Works 21ccw.blogspot.com Nortier", ben.fullName);
        }
    }
}
... and the results snapshot: Cheers

Sunday, September 21, 2008

Darren on Flex: Overloading the Constructor

Prologue

Back on the 3rd September 2008 some of my colleagues at Zuhlke unvailed StuffPlanner at a BCS SPA evening talk. StuffPlanner is an Agile estimation and planning tool with an opinion. Recently, I found myself ramping up my involvement in the development of StuffPlanner. Consequently, I have resumed my study and assessment of the technologies involved and their corresponding conventions and recommended usage. Henceforth, I blog briefly on the topic of constructor overloading.

Wait! ActionScript Does Not Support Overloading!

No, it doesn't... but please, keep reading. Sometime this week I received a communicade from a local colleague who is doing some pretty interesting work on the continent on the Flex platform. He asked me how to, or rather can you, overload a constructor. We (the locals) had (less) recently had a debate about this after realising that AS3 (ActionScript 3) does not support overloading, so I was primed to make a suitable response.

Default Parameters

Basically, in lieu of overloading AS3 gives you default parameters
public function DefaultValueExample(required:String, andTheCommonCase:String="DEFAULT") {
    if (!required) {
        throw new ArgumentError("You must specify required arguments");
    }

    // construct something with the required value andTheCommonCase
} 
Obviously the API designer needs to know the complete set of parameters, that is, those that must be specified and those that can have a default values. So far my references to the common-case are just to the concept of it, a place holder. The common-case represents the design challenge in using this language feature while, simultaneously, it represents the design limitation; the common-case(s) is prescribed to all the API clients irrespective of client needs. However, in practice the common-case is not a difficult trade-off to figure out and tends to be only a minor inconvenience. For example, in my experience, such cases tend to crop up during unit testing, which I anticipate will be less of a problem with TDD (yes, I am still homing my skills with TDD on Flex/AS3).

Variable Arguments

It may also be useful to use varargs to replace constructor overloading.
public function VarArgExample(... args) {
    for each (var arg:* in args) {
        // process arg...
    }
    //... then do construction
}
I reckon this has less application than default parameters as it only makes-sense/works when the (signature of the) things you are using during construction have parameters of no-type (* or Object) or a common super-type. Then you can either leverage duck-typing or polymorphism, respectively, to do smart things, which I won't discuss here.

The Factory Pattern

Oh yes, that old gem! I am a growing fan of using intention revealing names for variables and methods. It is perhaps a more common/old practice for variables (although you'd be surprised, even today), where variables are named to reveal the state it represents and/or for what it could be used to achieve. With methods, on the other hand, I sense a stigma, a taboo, in using this technique in any progressive way. Thus I feel there is a general hesitance to use this practice, as if it would imply some mediocrity in the coder's skill at writing good code. I do feel TDD development has gone some way to alleviate this, specifically, where test method names describe the example situation being tested; this some how seems more socially acceptable. And, while I'm at it, I'd like to suggest that this technique encourages you to write more cohesive methods w.r.t. what an object's methods do to contribute to the object's overall task. The reason I discuss this here (I did not plan to get into it that much) is because AS3 does not allow you to reuse method names i.e. no overloading. So rather than settling for less, why not combine intention revealing names with the Factory pattern. Now I have said it, I bet you are realizing you do this all the time (I anticipate) during testing, where you might have refactored some creational code for some objects used commonly in your tests. So what if we drop the usual XxxFactory's getInstance(), newInstances() and createInstance() cruft and adopt something more revealing?
//Person.as
public class Person {
    public function Person(firstName:String="", lastName:String="", ... middleNames) {
        // do somthing
    }  
}

//PersonFactory.as
public class PersonFactory {
    public function newPersonWithFirstName(firstname:String):Person { return new Person(firstname); }
    public function newPersonWithLastName(lastname:String):Person { return new Person(null, lastname); } // A little inconvenient
    public function newPersonWithFirstAndLastName(firstname:String, lastname:String):Person { return new Person(firstname, lastname); }
}
So what's the runtime overhead? Just the extra PersonFactory class, where the would-be constructor overloads are replaced with simple methods; let's face it, negligible. And the API overhead? Well interestingly, a problem has emerged and a pattern has been used to solve it. Furthermore, our intention revealing names should improve readability of the code and identifies a good place to refactor/relocate creational code that gets used over and over again... like, for instance, in your tests. Comments welcome.

Saturday, September 20, 2008

Darren on Flex: New FlexUnit 0.9 Out!

FlexUnit-0.9 has been released by Adobe Cosulting. I believe this is the first release since the projects move from Google Code to Adobe open Source. I have browsed the source code and nothing seems to have changed; obviously, community, please can correct me if I am wrong. There is still a lingering reference to the flexunit.extensions.TestSetup class which is still nowhere to be seen. Indeed I discovered the update while trying to find the standard approach to test-suite setup and teardown; subquently deciding it is is not the solution to my problem anyway. The most significant change, if only change, is the UI. We have:
  • An active search filter that narrows down the displayed list of test methods, matching on test (method) name.
  • A combobox with three result options: All Results, Empty Tests and Failures & errors; this replaces the tabbed view in the old version.
  • A red cross or green tick indicating the obvious, with a fat red cross or green tick to indicate overall (test-suite) pass or failure; it's a sad day - we've lost our beloved red-bar-green-bar.
  • In the event of an error/failure, improved diagnostic feedback. Just the other day I was getting frustrated with the old version, scrolling through the stack trace to find what class and which line of code I wrote (as opposed to FlexUnit code) that caused the breakage; well, it seems I won't have to suffer that anymore.
Overall, it just looks a lot more charming. Check it out, literally.