3

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
  • 1
    When your entire logic in a method is based on an non-validation if statement at the top, then that is your sign! Seriously, don't over complicate simple things for no big reason.
    – NoChance
    Commented Oct 31, 2012 at 7:31
  • "combining the two methods makes it more efficient " what do you exactly mean by "efficient"? Functions should do ONE thing. From your code this function does more than one thing and moreover its name is misleading. Functions' names should clearly state WHAT the function is doing. In its current format it clearly is misnamed :)
    – Songo
    Commented Oct 31, 2012 at 16:24

4 Answers 4

4

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
  • This is somewhat misleading. It's not possible to "return different types" -- a method or function declares its return type, and returning anything else is fundamentally incorrect. All you can do is declare a more generic type, like a common base class or id, so that all values that might be returned are covered.
    – Caleb
    Commented Oct 31, 2012 at 18:20
  • That is true for Objective-C. I tried to generalize to other languages a bit since the issue comes up in multiple languages. e.g., Ruby or C++
    – Ben
    Commented Oct 31, 2012 at 18:52
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 really like this solution, but I accepted the other answer because he more directly answered the question. Anyway, thanks!
    – pasawaya
    Commented Oct 31, 2012 at 13:44
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"

1

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
  • That's actually exactly what I'm trying to do! Thanks
    – pasawaya
    Commented Oct 31, 2012 at 18:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.