【问题标题】:AbstractFactory pattern in objective-cObjective-C中的AbstractFactory模式
【发布时间】:2012-08-27 13:10:26
【问题描述】:

我只是想学习目标-c。

我在维基百科上看到过AbstractFactory 模式的示例,涵盖不同的语言。

这里是按钮定义:

@protocol Button
- (void)paint;
@end

@interface WinButton : NSObject <Button>
@end

这是一家工厂:

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

据我所知,obj-c 的 id 关键字应该类似于 C# 的 var 或 C++11 的 auto, 对吧?

所以我的问题是:

为什么要让工厂返回一个未指定类型的通用对象? 这是一个错误(让工厂返回其他不是按钮的东西)还是有任何理由这样做?

我会这样写一个工厂:

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

我错了吗?

【问题讨论】:

    标签: objective-c abstract-factory


    【解决方案1】:

    为什么要让工厂返回一个未指定类型的泛型对象?

    在许多情况下,您会看到 id 返回,这是因为它们的类型不一致(真正的抽象对象),或者是因为会引入隐式向上转换。

    这是一个错误(让工厂返回其他不是按钮的东西)还是有任何理由这样做?

    这不是错误。当然,你不应该返回不匹配的类型。

    我会这样写一个工厂:……我错了吗?

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

    在这种情况下,最大的问题是 ObjC 的类型非常松散,您应该努力确保所有选择器的参数和返回类型匹配。也就是说,所有翻译中的每个createButton 都应该返回相同的类型并且具有相同的参数类型。有时您必须选择一个更具描述性的名称以避免编译器产生歧义。

    这应该可以解释为什么+[NSString string] 返回id——如果它返回NSString,那么+[NSMutableString string] 可能是警告的来源。这是因为编译器可能很难(不可能)将方法声明与动态实例匹配。这也可以帮助您理解选择器的“冗长”命名,例如在方法中也包含类型的便利构造函数(例如 +[NSDictionary dictionaryWithObject:] 而不是简单的 +[NSDictionary withObject:])。

    但是要回答您的问题:id&lt;Button&gt;NSObject&lt;Button&gt;* 或其他一些合格的类型就可以了 - 只要您可以使用该通用方法签名。您正在引入类型限定,这有助于编译器帮助

    【讨论】:

    • 感谢您的明确回答。其实wan不是一个意外的错误。我不知道我必须写 id
    • @Heisenbug 不客气——在这种情况下,我将删除该语法位。欢呼
    【解决方案2】:

    这里更正确的返回类型是:

    - (id<Button>)createButton;
    

    这意味着返回的类型是一个符合&lt;Button&gt; 协议的对象。我可能会修复 WP 页面只是为了更清楚一点。 &lt;Button&gt; 协议还应继承自 &lt;NSObject&gt; 协议以确保完整性(并简化实际使用)。

    请注意,抽象工厂模式在 ObjC 中有些不寻常。我正在尝试考虑在 UIKit 或 Foundation 中使用它的情况。更常见的是类在内部处理这个问题(例如在NSNumber 中),称为类集群。

    尝试在 ObjC 中以 C++ 或 C# 风格编写代码时要非常小心。 ObjC 不是一门静态语言,使用的模式往往大相径庭。 (我并不是说 AF 是一种静态模式。它可以在 ObjC 中很好地使用。我只是说你在尝试学习 ObjC 时正在看它的事实意味着你可能正在倒退,学习“我如何在 ObjC 中做这个 C++”,而不是学习“我如何在 ObjC 中开发。”)

    【讨论】:

    • 你有什么书或讲座可以推荐给我,用于学习 obj-c 中的良好编程实践和模式吗?
    • 斯坦福课程受到好评 (cs193p.stanford.edu)。我也非常尊重 Jeff LaMarche 的作品 (amazon.com/Beginning-iOS-Development-Exploring-SDK/dp/…)。
    • +1
    【解决方案3】:

    Objective-C 有类簇的概念,即抽象工厂。 See this answer.

    【讨论】:

      猜你喜欢
      • 2013-02-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-11
      • 1970-01-01
      • 1970-01-01
      • 2011-12-30
      • 2015-09-15
      • 2011-01-07
      相关资源
      最近更新 更多