AS3 Best practices for a method that could return two types
I've been developing a framework for ActionScript 3 and have come across a peculiar scenario where I want a method to be able to return either an AvFrameworkObject
or an Array
containing multiple instances of AvFrameworkObject
.
Take this method which is used to register one or more instances of AvFrameworkObject
:
public function register(...objects):Object
{
var reg:Array = [];
var i:AvFrameworkObject;
for each(i in objects)
{
i.fw = this;
reg.push(i);
}
return reg.length > 1 ? reg : reg[0];
}
A few things on the above:
- This seems extremely sloppy to me. Is it really?
- I could use a wildcard (asterisk *) as the return type as well, which makes more开发者_开发知识库 sense?
- Is it possible to actually define two return types only? Just for the sake of readability etc.
In some strict sense yea this can be sloppy but I've seen much worse.
You should always have the return type as narrow as you can. So a * as a return type is worse IMO than Object.
No you can not have two return types.
If you have good tests around it and document it well then it can be ok to use.
But how about you always return an array, if there is only 1 result, then you return an array of size 1?
As far as I know, all objects are passed by reference:
In ActionScript 3.0, all arguments are passed by reference, because all values are stored as objects. However, objects that belong to the primitive data types, which includes Boolean, Number, int, uint, and String, have special operators that make them behave as if they were passed by value.
You don't have to return anything, just setting the fw
variable member will work.
That being said, you have some options on how to return multiple variables.
- A common approach is to return the count of the array returned, and use an argument to set the array. A call would be like
var length:int = register(out, object1, object2, object3)
. Then you can use thelength
variable in a for loop. - Another approach is to return the entire array. I think it doesn't need more explanation, but I want to make it clear that you can use the returned array directly, if you want a specific member. For example, if you want the first object, you can write
t:Thing = fw.register(new Thing())[0];
. Take note of the [0] at the end. - You can also use above methods but using
Object
insted ofArray
.
Personally I don't prefer to return an abstract object, normally I choose to return the entire array.
Hope this helps.
Personally in this case I would return the 1 item array for consistency. That will make for a much more sensible interface; the caller can always expect to be returned an array, rather than having to make the code more convoluted by responding differently to different returned objects.
Now there is also the situation where the code will respond in exactly the same way to the returned object no matter what it's type is, in which case that means the returned objects inherited from some common base class. In that case the return type should be the common base class.
(I suppose I'm assuming here that you won't respond in exactly the same way to an Array and an AvFrameworkObject)
精彩评论