TheInnerParty
TheInnerParty

Reputation: 406

Using Empty Class as Data Type

I'm writing a program that has a SecretNumber Class which holds a number and has a method that returns whether a guess is too low, too right or correct.
The Method returns an object of one of three objects, defined like this:

@interface TooHigh : NSObject
@end
@implementation TooHigh
@end
@interface TooLow : NSObject
@end
@implementation TooLow
@end
@interface JustRight : NSObject
@end
@implementation JustRight
@end

The SecretNumber Guessing Method is then implemented like this:

@implementation SecretNumber
{
    int Secret;
}
-(id) guessSecret:(int)g
{
    if (g>Secret) {
        return [[TooHigh alloc] init];
    } else {
        if (g<Secret) {
            return [[TooLow alloc] init];
        } else {
            return [[JustRight alloc] init];
        }
    }
}

So my question being is this considered good programming form, or am I better off sending back a 1,2,3 or three random characters (one meaning too high, another too low, etc)?

Upvotes: 2

Views: 59

Answers (3)

CRD
CRD

Reputation: 53010

What you need is an enumerated type - this is a simple value type (e.g. like int et al, not a reference type like NSObject) which you define with a fixed set of literal values. For example:

typedef enum { TooLow, JustRight, TooHigh } GuessClasification;

Defines a new type, GuessClasification, which has the three values TooLow, JustRight and TooHigh.

You can place this type declaration in your class header file.

Using this your method becomes:

- (GuessClassification) guessSecret:(int)g
{
    if (g>Secret)
        return TooHigh;
    else if (g<Secret)
        return TooLow;
    else
        return JustRight;
}

You use this type similarly to integers and other value types, so you can test for equality with ==, use the literals as case values in a switch statement, etc.

HTH

Upvotes: 1

jmrah
jmrah

Reputation: 6221

Your solution is a great example of OO programming, and taking advantage of polymorphism. There is nothing wrong with it in my opinion, though, for your simple example, it is the most 'complex' way of doing it. Let's discuss the options that have been put so far to solve your situation, starting with the simplest:

  1. Simply returning an int: This is the simplest in terms of lines of code. The SecretNumber will return a -1, 0, or 1, and the calling code will have to switch on these values, providing logic to handle each case. The con of this method is that the meaning of the returned integers are not readily apparent, and new cases will mean modifying all the classes that call on the SecretNumber class.

  2. Returning an enum: This is better than returning an int for the sole purpose of attaching a meaning the the returned values. Readability and comprehension increases. You still must switch on the returned enum type, however, and provide logic for each enum case.

  3. Encapsulate the behaviour of each return value in a class, and returning an interface. This is what you have done, minus the behaviour part (your classes are 'empty'). It is the most 'OO' (not nesessarily meaning better or worse) of the three, because you avoid the switching on the return type. This way tends to lend itself to being the most flexible of the three. If you have a different case in the future (say, for values WAY to high, or values WAY to low), you don't have to touch the the code that calls SecretNumber.

Either way works. I would always go with an enum return values over ints, however, and if the situation is complex enough, do #3 instead of #2

Upvotes: 0

wolfram77
wolfram77

Reputation: 3221

You could use -1, 0, 1 to indicate too low, correct or too high respectively. That would reduce your code size, and would be relatively simple to understand as well.

In such a case, it can be used with conditions < 0, == 0 or > 0.

Good programs are simple and that can be measured by the number of tasks that can be solved with a given program (generic), and how small it is (can measure as code+documentation size)

Upvotes: 1

Related Questions