【问题标题】:Factory (design pattern) in Objective CObjective C 中的工厂(设计模式)
【发布时间】:2011-01-07 08:15:01
【问题描述】:

我正在尝试在 Objective 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 的新手——所以这可能只是不好的做法如果是这样,那么这样做的好做法是什么。

【问题讨论】:

  • Objective-C 中通常没有工厂类,因为类是第一类对象。查看 Umbrella 类,例如 NSPredicate 或 NSNumber。他们是工厂。您通常会返回一个 NSPredicate 或 NSNumber 的子类。
  • 同意@AdamSmith,最好的方法是 Car 上的类方法,例如+(Car *)carWithColor:(int)color;
  • 实际上,我注意到另一件事,从 Java 来时可能不清楚。如果“createCar”在 CarFactory 类上,最佳实践通常是编写 [self createBlueCar]。在 ObjC 中,类是与 Java 不同的对象。所以类方法中的 self 指的是类对象(在本例中为 CarFactory)。使用“self”的原因是如果你继承“CarFactory”并重新实现例如代码不会中断。 “createBlueCar”

标签: objective-c


【解决方案1】:

最好的方法是使用类扩展。

.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 属性。

【讨论】:

  • +1 这确实应该是公认的答案,因为它演示了如何做到这一点以及为什么这样做。
【解决方案2】:

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

请注意,尽管您将不再向您的类的客户宣传这些方法,但如果他们使用正确的选择器,他们仍然可以使用它们。此外,他们总是可以使用 classdump 之类的东西来重新生成您的类的完整接口,这样您的方法就永远不会真正被隐藏。

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

【讨论】:

  • 然后我将“隐藏”包含类别的 h 文件
  • @Guy:不,您可以在实现文件中完全实现类别。没什么好说的,@interface 部分必须在 .h 文件中。
  • @Guy JKP 是对的,你把它放在 .m 的顶部,这是相当标准的做法。请记住:objective-c 中从来没有任何私有的东西,只有不可见或未知的
【解决方案3】:

你可以创建一个私有静态函数

@implementation Car 

static createBlueCar () {
  ....
}

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

@end

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多