2010-01-20 48 views
26

我試圖創建目標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

回答

49

要做到這一點的最佳方法是使用類擴展。

.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

4

我想你可以在實現(而不是接口)文件中使用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

-1

您可以創建一個私有靜態功能

@implementation Car 

static createBlueCar() { 
    .... 
} 

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

@end 

,但沒有,你不能創建真正的私有成員。 (您可以調用一些約定,例如在私人類別中使用+(Car*)private_createCar以阻止其使用。)