[Biococoa-dev] Compilation warning with the factory class

Charles PARNOT charles.parnot at stanford.edu
Sun Feb 6 01:44:03 EST 2005

At 4:37 PM -0500 2/5/05, Koen van der Drift wrote:
>OK, I think I know why this happens. In this case:
>BCSequence  *theProtein = [[BCSequenceFactory sharedSequenceFactory] sequenceWithString: aString];
>the BCSequenceFactory actually returns a BCAbstractSequence object, not a BCSequence, so that will cause the warning.
><snip>.... But I am not sure how to fix the <...> warning.

This is actually partly a flaw of the 'factory class' design when dealing with several subclasses.
The only solution is to have the method in the factory declared as follows:
+(id) sequenceWithString:aString;

When you use factory methods in the sequence classes, the problem goes away.

The code in the translation example could simply be:
    BCSequence *theProtein = [BCSequence sequenceWithString: aString];

And then you should have the following for the sequence classes:

@interface BCAbstractSequence : NSObject { }
+ (BCAbstractSequence *) sequenceWithString: (NSString *)aString;

@implementation BCAbstractSequence
+ (BCAbstractSequence *) sequenceWithString: (NSString *)aString;
    return [[[[self class] alloc] initWithString:aString] autorelease];

@interface BCSequence : BCAbstractSequence { }
+ (BCSequence *) sequenceWithString: (NSString *)aString;

@implementation BCAbstractSequence
+ (BCSequence *)sequenceWithString:(NSString *)aString;
    return (BCSequence *)[super sequenceWithString:aString];

+ similar stuff in the other subclasses.

But this is not the only option. For a moment, consider NSArray and NSMutableArray. This is the same situation faced by the factory method 'array'. Both classes respond to '+array', and the method will return an NSArray  or a NSMutableArray. Apple chose another route by declaring '-(id)array' only in the superclass NSArary, so that it does not need to be declared again in the subclass NSMutableArray. In our case, this would be even more efficient as this would reduce the code in not just one subclass, but 5. The only problem is you can then write things like this without compiler warnings:
    NSDictionary *dic=[NSArray array]; //try that, it is funny!
    BCSequenceDNA *seq=[BCSequenceProtein sequenceWithString:aString];

I would be actually probably more inclined to use the (id) return value, because there is then less code, and also because this is what NextStep and Apple decided to do... What would be your choice?

A final note: this does not mean we should not use BCSequenceFactory, but that it could remain private. Another option, which I personaly think is better, is to have the BCSequenceFactory code in the BCSequence implementation, which will not have anything else anyway. Indeed, the only job of the BCSequence placeholder class is to determine which sequence type should be used and then return the right instance types. What do you think, Koen?

can't wait to read you, guys!

Help science go fast forward:

Charles Parnot
charles.parnot at stanford.edu

Room  B157 in Beckman Center
279, Campus Drive
Stanford University
Stanford, CA 94305 (USA)

Tel +1 650 725 7754
Fax +1 650 725 8021

More information about the Biococoa-dev mailing list