厂(设计模式)的目标C

问题描述:

我试图创建目标C 所以我做的东西像一个工厂(设计模式):厂(设计模式)的目标C

+ (Car *)createCar:(int)color { 
    if (color == 1) { 
     return [CarFactory createBlueCar]; 
    } else if (color == 2) { 
     return [CarFactory createRedCar]; 
    } else { 
     return nil; 
    } 
} 

+ (Car *)createBlueCar { 
    // ... 
} 

+(Car*)createRedCar{ 
    // ... 
} 

不过,我不希望createBlueCarcreateRedCar可供公众使用,如果我没有在.h文件中定义它们,则会收到缺少定义的警告。

我是一名前Java开发人员和Objective-C中的新手 - 所以这可能只是不好的做法如果是这样做是一个很好的做法。

+2

您通常在Objective-C中没有Factory类,因为类是第一类对象。查看Umbrella类,如NSPredicate或NSNumber。他们是工厂。您通常会得到NSPredicate或NSNumber返回的子类。 – 2014-02-14 12:39:25

+2

同意@AdamSmith,最好的方法是在Car上使用类方法,例如'+(Car *)carWithColor:(int)color;' – dmur 2014-07-09 00:12:24

+0

其实我注意到另一件事情,从Java来的时候可能并不清楚。如果CarFactory类中的“createCar”最佳实践通常是编写[self createBlueCar]。在ObjC类中是不同于Java的对象。因此,类方法中的self引用类对象(本例中为CarFactory)。使用“self”的原因是,如果继承“CarFactory”并重新实现,代码不会中断。 “createBlueCar” – 2014-07-09 10:51:51

要做到这一点的最佳方法是使用类扩展。

.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 

一类扩展是一个更好的解决方案,因为它是类的接口,而一个类别的一个真正的延伸部(没有相应的实现)仅仅是这个类实现这些方法的一个建议。也就是说,如果你没有实现在类扩展中声明的接口(方法),编译器会发出警告,但如果你对命名类别做了相同的处理,则不会发出警告。

还要注意,类扩展允许您根据上面的示例将readonly属性升级到readwrite属性。

+2

+1这应该是被接受的答案,因为它演示了如何做到这一点,以及为什么。 – 2010-01-20 20:51:22

我想你可以在实现(而不是接口)文件中使用objective-c category将它们添加到类中,作为模拟私有方法的一种方法,如果你想从你的类的用户中“隐藏”它们。

请注意,尽管您不再将方法广告给您班级的客户,但如果他们使用正确的选择器,他们仍然可以使用它们。此外,他们总是可以使用类似classdump的东西来重新生成您的课程的完整界面,以便您的方法永远不会真正隐藏。

有关在objective-c下创建“专用”方法的更多示例,请参阅this question

+0

但我会隐藏包含类别 – 2010-01-20 16:00:16

+2

@Guy的h文件:否,您可以在实现文件中完全实现该类别。没有什么可说的@interface部分必须在.h文件中。 – jkp 2010-01-20 16:00:52

+1

@Guy JKP是对的,你把它放在.m的顶部,这是相当标准的做法。请记住:在objective-c中绝不会有任何私人的,只有隐形或未知的 – slf 2010-01-20 16:03:10

您可以创建一个私有静态功能

@implementation Car 

static createBlueCar() { 
    .... 
} 

+(Car*) createCar:(int) color{ 
    if (color==1) { 
    return createBlueCar(); 
    } ... 
} 

@end 

,但没有,你不能创建真正的私有成员。 (您可以调用一些约定,例如在私人类别中使用+(Car*)private_createCar以阻止其使用。)