Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AbstractFactory pattern in objective-c

I'm just trying to learn objectives-c.

I've seen wikipedia example for AbstractFactory pattern, across different languages.

Here's the Button definition:

@protocol Button
- (void)paint;
@end

@interface WinButton : NSObject <Button>
@end

Here's a factory:

@implementation WinFactory
- (id)createButton {
    return [[[WinButton alloc] init] autorelease];
}
@end

As far as I kwnow, obj-c's id keyword should be something like C#'s var or C++11's auto, right?

So I my question is:

why let the factory return a generic object of a not specified type? Is this an error (that let factory return something other that is not a Button) or is there any reason to do that?

I'd write a factory this way:

@implementation WinFactory
- (id<Button>)createButton {
    return [[[WinButton alloc] init] autorelease];
}
@end 

am I wrong?

like image 612
Heisenbug Avatar asked Dec 27 '22 18:12

Heisenbug


1 Answers

why let the factory return a generic object of a not specified type?

In many cases where you see id returned, it is because they are not consistently typed (really abstract objects), or it is because an implicit upcast would have been introduced.

Is this an error (that let factory return something other that is not a Button) or is there any reason to do that?

It is not an error. Of course, you should not return a type which does not match.

I'd write a factory this way:… am I wrong?

@implementation WinFactory
- (id<Button>)createButton {
    return [[[WinButton alloc] init] autorelease];
}
@end

The big gotcha in this scenario is that ObjC is quite loosely typed, and you should strive to ensure all selectors' parameters and return types match. That is to say, every createButton in all your translations should all return the same type and have the same types for parameters. Sometimes you will have to choose a more descriptive name in order to avoid ambiguity for the compiler.

That ought to explain why +[NSString string] returns id -- if it returned NSString, then +[NSMutableString string] could be a source of warnings. This is because the compiler can have a difficult (impossible) time matching a method declaration to a dynamic instance. That may also help you understand the 'wordy' naming of selectors, such as convenience constructors which also contain the type in the method (e.g. +[NSDictionary dictionaryWithObject:] as opposed to simply +[NSDictionary withObject:]).

But to get to your question: id<Button> or NSObject<Button>* or some other qualified type is just fine -- as long as you can live with that common method signature. You're introducing type-qualification, which helps the compiler help you.

like image 124
justin Avatar answered Jan 11 '23 17:01

justin