AbstractFactory pattern in objective-c

I'm just trying to learn goals-c.

I saw a wikipedia example for the AbstractFactory template in different languages.

Here is the definition of the button:

@protocol Button - (void)paint; @end @interface WinButton : NSObject <Button> @end 

Here is the factory:

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

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

So my question is:

Why let's factory return a generic object of an unspecified type? Is this a bug (which allows the factory to return something else that is not a button), or is there any reason for this?

I will write factory as follows:

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

I'm wrong?

+4
source share
3 answers

Why does factory return a generic object of an unspecified type?

In many cases, when you see the returned id , this is because they were not printed sequentially (really abstract objects), or because an implicit upcast was introduced.

Is this a bug (which allows the factory to return something else that is not a button), or is there any reason for this?

It's not a mistake. Of course, you should not return a type that does not match.

I would write a factory as follows: ... am I mistaken?

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

The big mistake in this scenario is that ObjC is pretty weakly typed, and you should strive to ensure that all selector parameters and return types are consistent . That is, each createButton in all your translations must return the same type and have the same parameter types. Sometimes you need to choose a more descriptive name to avoid ambiguity for the compiler.

This should explain why +[NSString string] returns id - if it returned NSString , then +[NSMutableString string] could be a source of warnings. This is due to the fact that the compiler may have a difficult (impossible) time corresponding to the declaration of the method to a dynamic instance. It can also help you understand the β€œverbose” designation of selectors, for example convenience constructors that also contain a method type (for example, +[NSDictionary dictionaryWithObject:] , and not just +[NSDictionary withObject:] ).

But to answer your question: id<Button> or NSObject<Button>* or some other qualified type - this is normal - as long as you can live with this common method signature. You introduce a type qualification that helps the compiler help you.

+6
source

A more correct return type would be:

 - (id<Button>)createButton; 

This means that the return type is an object that conforms to the <Button> protocol. I can fix the WP page to be a little more understandable. The <Button> protocol must also inherit from the <NSObject> protocol for completeness (and to simplify actual use).

Note that the abstract Factory pattern in ObjC is somewhat unusual. I am trying to think about the case when it was used in UIKit or Foundation. Most often, a class handles this internally (for example, in NSNumber ) and is called a class cluster.

Be very careful when trying code in C ++ or C # style in ObjC. ObjC is not a static language, and the patterns used are often different. (I’m not saying that AF is a static template, it can be used pretty well in ObjC. I’m just saying that the fact that you look at it while trying to learn ObjC means that you can get closer to it while studying " how to do it in C ++ in ObjC "and not learn" how can I develop in ObjC ".)

+4
source

Objective-C has the concept of class clusters, which are abstract factories. See this answer.

0
source

All Articles