I was discussing the use of typesafe ENUM's with a co-worker today when we got to a point where we couldn't agree on how to implement some of the behavior. We have this AssessmentItemType class that holds different types of assessmentitems like MULTIPLE_CHOICE, FILL_IN_TEXT, DRAG_AND_DROP_WITH_TEXT, etc that looks like this (some of the content is stripped).
-
...
-
-
private static var TYPES:Array = new Array();
-
-
private var id:Number;
-
private var name:String;
-
-
-
public static var MULTIPLE_CHOICE:AssessmentItemType = new AssessmentItemType("multipleChoice", 1);
-
public static var FILL_IN_TEXT:AssessmentItemType = new AssessmentItemType("fillInText", 2);
-
public static var DRAG_AND_DROP_WITH_TEXT:AssessmentItemType = new AssessmentItemType("dragAndDropWithText", 6);
-
public static var DRAG_AND_DROP_WITH_IMAGES:AssessmentItemType = new AssessmentItemType("dragAndDropWithImages", 7);
-
-
-
private function AssessmentItemType(name:String, id:Number){
-
setName(name);
-
setId(id);
-
-
TYPES.push(this);
-
}
-
-
...
These types are assigned to an instance of the AssessmentItem class when we are parsing the assessmentitems from XML files. But during the parsing, we need a way to look up the correct assessmentitemtype in the ENUM. All we know about the type of the assessmentitem is its name, "multipleChoice" for instance, or its id, "1" for instance. The id is used for backward compatibility with the previous system.
The first solution was to create a separate helper class to look up the assessmentitemtype by looking into the available types, exposing the TYPES array. We figured we needed a getByName() and a getById() method in order to look up the type both ways. The second solution was to add these 2 methods to the AssessmentItemType class itself and not to create a separate class. I personally thought that the second solution was the best because creating a separate class to look up values would be overkill in my opinion. We were also showing some the class' internals by making the TYPES array public in order to access it from the helper class. We couldn't end the discussion because my co-worker had to catch a train, so I was wondering what you guys were thinking.
PS: This might not be a critical design question, but both solutions might have there pros and cons where we didn't think of.
Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
Christophe Herreman is a software developer living in Belgium. He's working on high-end Flex and AIR solutions at
August 16th, 2005 at 9:38 pm
Well in your case I would definately go with the second not only because it keeps private’s, private, but because its just more natural. However why didn’t you stick to ID’s? When using strings like that on a larger scale you would have to actually localize your code rather than defining them as a constant (or as close as you can in AS)
-Greg
August 16th, 2005 at 10:01 pm
Hi Greg,
thx for the feedback. About the id’s: using strings as assessmentitem identifiers just felt better when reading or correcting the XML files. The QTI standard also uses strings as identifiers (”choiceMultiple” for multiple choice assessmentitems for instance), though this is not the reason we chose strings.
Mentioning QTI, I was just thinking that in order to assign one of the types to an assessmentitem parsed from a QTI XML file, we would need to extend the constructor of the AssessmentItemType to accept the QTI identifier as well. And what if more XML structures needed to be used…I think we’ll need to rethink the design.
August 16th, 2005 at 11:54 pm
One thing I would do, strings or not, is make all those identifiers constants that way if and when they change they are all in one place. It also helps identify uniqueness since all of the constants are defined in one place. I personally try to not use node names at all as identifiers but always have an id field that is used. The nodes define the structure and their attribute define the metadata, I don’t mix them.
August 19th, 2005 at 12:22 am
I think you are missing the woods for the trees - the AssessmentItemTypes surely are value objects, so adding themselves to a static array etc. seems to go about it the wrong way.
Just create an AssessmentItemTypeCollection, which in turn contains the static TYPES array and has getByID and getByName entries (and can contain further structures to speed up access to these two) - and it is this class which creates and adds new item types to the TYPES array.
(and use getters/setters for the AsessmentItemType class :))