I'm trying to create a factory (design pattern) in Objective C So I'm doing something like:
+ (Car *)createCar:(int)color {
if (color == 1) {
return [CarFactory createBlueCar];
} else if (color == 2) {
return [CarFactory createRedCar];
} else {
return nil;
}
}
+ (Car *)createBlueCar {
// ...
}
+(Car*)createRedCar{
// ...
}
However I don't want the createBlueCar
and the createRedCar
to be available to public and if I don't define them in the .h
file then I get a warning of the missing definition.
I'm a former Java developer and a newbie in Objective-C — So it might be just bad practice If so what the be good practice of doing so.
The factory method is a creational design pattern, i.e., related to object creation. In the Factory pattern, we create objects without exposing the creation logic to the client and the client uses the same common interface to create a new type of object.
Factory pattern removes the instantiation of actual implementation classes from client code. Factory pattern makes our code more robust, less coupled and easy to extend. For example, we can easily change PC class implementation because client program is unaware of this.
Simple factory pattern describes a class that has one creation method with a large conditional that based on method parameters chooses which product class to instantiate and then return. People usually confuse simple factories with a general factories or with one of the creational design patterns.
The factory pattern is a creational pattern that provides a way to make objects without exposing creation logic. It involves two types: The factory creates objects. The products are the objects that are created.
The best way to do this is with a Class Extension.
.h
@interface MyClass : NSObject
@property(readonly) BOOL publiclyReadOnlyPrivatelyWritableFlag;
+ (id) myExposedFactoryMethod;
@end
.m
#import "MyClass.h"
@interface MyClass ()
@property(readwrite) BOOL publiclyReadOnlyPrivatelyWritableFlag;
+ (id) privateMethod1;
+ (id) privateMEthod2;
@end
@implementation MyClass
@synthesize publiclyReadOnlyPrivatelyWritableFlag; // no ivar -- only works in 64 bit and iPhone
+ (id) myExposedFactoryMethod
{
...
[self privateMethod1];
...
}
+ (id) privateMethod1;
{
return ...
}
+ (id) privateMEthod2;
{
return ...
}
@end
A class extension is a better solution because it is a true extension of the class's interface whereas a category (without a corresponding implementation) is merely a suggestion that the class implement the methods. That is, the compiler will warn if you don't implement the interface -- the methods -- declared in the class extension, but will not warn if you did the same with a named category.
Note also that a class extension allows you to upgrade a readonly
property to a readwrite
property as per the above example.
I think you can add them to the class using an objective-c category within the implementation (not the interface) file as a way of emulating private methods if you want to "hide" them from users of your class.
Note, although you will no longer be advertising the methods to clients of your class, they will still be able to use them if they use the correct selectors. Additionally, they can always use something like classdump to regenerate the full interface to your class so your methods will never truly be hidden.
See this question for further examples of creating "private" methods under objective-c.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With