What is an Object as a Struct?
If I have an object which has been loaded with certain data, what should I return if I call asStruct() to return a struct representation of the state of the object. The unthinking answer might be just to return the instance data stored within the object. Something like:
<cfreturn variables.InstanceData>
</cffunction>
A little more thinking would suggest that while there might be use cases for that, most of the time what you're going to want to do is to loop through the gettable list of properties for the object, calling the getter for each one and putting the values of all of those getter calls into a structure. For the special case of an object without a gettable property list I'd just return the internal state.
That then gives the following code:
<cfscript>
var ReturnStruct = StructNew();
If (len(GettablePropertyList) GT 1) {
For (key in GettablePropertyStruct) {
ReturnStruct[key] = variables.InstanceData[key];
};
return ReturnStruct;
}
Else {
return variables.InstanceData;
};
</cfscript>
</cffunction>
I think I quite like this as all I have to do is provide a gettable property list for an object and when I asStruct() it, I get the collection of externally shareable properties which will use any custom getters as appropriate so if the internal state has a FirstName, LastName and DateofBirth but the gettable property list is FirstNale, LastName, Age, providing there is a custom getAge() method, I'll get the users first name, last name and age as a struct just by calling User.asStruct().
Simple, but I can see where that would be useful. Thoughts (other than "duhh") welcome!



The struct will behave like an object, but be a struct.
I know that's not your point, but it was a fun programming exercise. =)
That's my only feedback as I like your ideas.
For the goal of going over the wire, I've had luck using an external serializer (mine relies on <cfproperty> tags, but I imagine with your DSL you can do someething similar) that relies on conventions to turn an instance into a different format (JSON, an amf-specific struct using __type__, etc). I typically wire it in via AOP.
Good point. I think you're absolutely right that the object shouldn't know about JSON and XML and the like - I briefly considered addint toJSON and toXML to my base object before realizing how terrible an idea that would be! However, at the other extreme I'm not sure that I want my external serializer to ask the object for a list of properties and then call each of the getters - the rule of thumb is that if you're asking an object for more than two or three things maybe you should tell it to do something for you instead, so I want considering allowing a toStruct() method in the base object and an external serializer would then take the struct and transform it into the appropriate format for sending over the wire.
What do you think? Does your external serializer ask the bean for a bunch of stuff or do you have an equivalent of the toStruct() it can call? Might this be a case where asking the bean for lots of things is appropriate? Is toStruct() a reasonable responsibility of a base object?
I'd appreciate any more thoughts you might have on this one . . .