So I have a method that’s something like this:
-(BOOL)isSingleValueRecord
And another method like this:
-(Type)typeOfSingleValueRecord
And it occurred to me that I could combine them into something like this:
-(id)isSingleValueRecord
And have the implementation be something like this:
-(id)isSingleValueRecord {
//If it is single value
if(self.recordValue = 0) {
//Do some stuff to determine type, then return it
return typeOfSingleValueRecord;
}
//If its not single value
else {
//Return "NO"
return [NSNumber numberWithBool:NO];
}
}
So combining the two methods makes it more efficient but makes the readability go down. In my gut, I feel like I should go with the two-method version, but is that really right? Is there any case that I should go with the combined version?
2
There are occasions where returning different types is OK – those occasions are when you want to take advantage of polymorphism or some other mechanism that amounts to “the types you return will respond to the same operations” (templates, duck-typing, etc.)
Your example above does not fit that category. In this case you are creating an interface that is only more efficient for you, but has not saved the client of your class any work. A caller must still determine if it is dealing with a singleValueRecord.
There are a couple better options.
- Use a structure or tuple to combine the boolean and Type in a single return value.
- As mentioned by others, provide a boolean return value and an output parameter for the function that would hold the type information.
- If it is very unusual for you to return NO, you could throw an exception
Try to think about what is going to make life easiest for the calling code, not what looks best in the implementation.
2
What if you throw out both solutions and come up with a different design? For example, you could provide a single method like:
- (NSArray*)recordTypes;
If the record is a single-value record the returned array contains one type. If it’s a multi-value record, the array contains more than one type.
I’m assuming here that coming up with the record itself is difficult or time consuming. If it’s not, you could instead just provide the record itself, and let the client query it for it’s type or types.
1
I’m a Java developer, but in Java I would never combine those two.
Because a method called is*
suggests that you return a boolean value, while one that’s called typeOf*
suggests to return a certain type.
But you may use the one in the other to avoid code duplication, e.g. in typeOfSingleValueRecord do something like (pseudo code) if(isSingleValueRecord) return "type of record"
It looks like you are trying to return more than one thing from a single method, which is not an unusual thing. An unusual (and usually bad) thing is that you are trying to combine both items in a single value, which must be interpreted by the caller in a non-intuitive way (similar to the infamous “yes/no/file-not-found” mix-up).
A better signature for your method would separate the two values it returns as follows:
-(BOOL)tryGetSingleValueRecordType:(Type**)typePtr {
if (self.recordValue = 0) {
*typePtr = typeOfSingleValueRecord;
return YES;
} else {
return NO;
}
}
Now the caller would be able to call your API like this:
Type *srType;
if ([record tryGetSingleValueRecordType:&srType]) {
NSLog("Single record type: %@", srType);
} else {
NSLog("Not a single record");
}
The two items returned by your API, i.e. the YES/NO answer and the actual type, are returned through two separate mechanisms, without losing readability, efficiency, or type safety.
1