【问题标题】:Objective-C and Class Cluster patternObjective-C 和类集群模式
【发布时间】:2013-07-27 23:02:57
【问题描述】:

我看了一些关于类簇模式的资料,接下来就明白了:

  • 公共集群类只提供接口,没有实际实现,其他类根据不同情况实现;

  • 它与抽象工厂模式有一些相似之处:当我们调用方法+classNameWith...时,它可以根据参数选择最合适的子类并返回它。

例如,+[NSNumber numberWithDouble:1.0],将返回用于存储双精度值的实现。

但我不明白的是:-init... 公共集群类的方法如何工作: [[NSNumber alloc] initWithDouble:1.0],因为在调用alloc 之后它已经分配了NSNumber 的实例,而不是它的子类。

那么,谁能解释一下公共集群类的alloc-init 方法的实际工作原理,以及具体子类何时实例化并返回?

【问题讨论】:

标签: ios objective-c design-patterns


【解决方案1】:

基本上,您分配的实例可能会被丢弃并替换为不同的实例。从技术上讲,这并不特定于类集群,这就是为什么当您在任何 init 方法中调用 super 时,您需要将结果设置为 self

self = [super init];

【讨论】:

  • 此外,+alloc 方法可以像任何其他方法一样被覆盖。类簇 alloc 可能会返回一个静态实例,而不是每次请求新实例时都会创建和释放新对象。
  • 无聊的宇航员,是的,我还认为它们会覆盖 alloc 方法,因为否则销毁分配的对象会有一些开销。
【解决方案2】:

这是 Objective C 的抽象工厂实现。

// Usage
    BrandingFactory * factory = [BrandingFactory factory:Sierra];

    UIView * view = [factory brandedView];

    UIButton * button = [factory brandedMainButton];

    UIToolbar * toolbar = [factory brandedToolbar];
____________________________________________
//  BrandingFactory.h
//  AbstractFactory

#import <Foundation/Foundation.h>

typedef enum ouputTypes {
    Acme,
    Sierra
} OutputTypes;

@interface BrandingFactory : NSObject 
{

}

+ (BrandingFactory *) factory: (OutputTypes)type;

- (UIView *) brandedView;
- (UIButton *) brandedMainButton;
- (UIToolbar *) brandedToolbar;

@end

___________________________________________________

//  BrandingFactory.m
//  AbstractFactory

#import "BrandingFactory.h"
#import "AcmeBrandingFactory.h"
#import "SierraBrandingFactory.h"


@implementation BrandingFactory

+ (BrandingFactory *) factory:(OutputTypes)type
{
    if (type == Sierra) {
        return [[[SierraBrandingFactory alloc] init] autorelease];
    }
    else if (type == Acme)
    {
        return [[[AcmeBrandingFactory alloc] init] autorelease];
    }
    return nil;

}

- (UIView *) brandedView
{
    return nil;
}

- (UIButton *) brandedMainButton
{
    return nil;
}

- (UIToolbar *) brandedToolbar
{
    return nil;
}

@end

________________________________________

//  SierraBrandingFactory.h
//  AbstractFactory

#import <Foundation/Foundation.h>
#import "BrandingFactory.h"


@interface SierraBrandingFactory : BrandingFactory
{

}

- (UIView*) brandedView;
- (UIButton*) brandedMainButton;
- (UIToolbar*) brandedToolbar;

@end


//  SierraBrandingFactory.m
//  AbstractFactory

#import "SierraBrandingFactory.h"
#import "SierraView.h"
#import "SierraMainButton.h"
#import "SierraToolbar.h"

@implementation SierraBrandingFactory

- (UIView*) brandedView
{
    // returns a custom view for Sierra
    return [[[SierraView alloc] init] autorelease];
}

- (UIButton*) brandedMainButton
{
    // returns a custom main button for Sierra
    return [[[SierraMainButton alloc] init] autorelease];
}

- (UIToolbar*) brandedToolbar
{
    // returns a custom toolbar for Sierra
    return [[[SierraToolbar alloc] init] autorelease];
}

@end

________________________________________
//  AcmeBrandingFactory.h
//  AbstractFactory


#import <Foundation/Foundation.h>
#import "BrandingFactory.h"


@interface AcmeBrandingFactory : BrandingFactory
{

}

- (UIView *) brandedView;
- (UIButton *) brandedMainButton;
- (UIToolbar *) brandedToolbar;

@end


//  AcmeBrandingFactory.m
//  AbstractFactory

#import "AcmeBrandingFactory.h"
#import "AcmeView.h"
#import "AcmeMainButton.h"
#import "AcmeToolbar.h"


@implementation AcmeBrandingFactory

- (UIView *) brandedView
{
    // returns a custom view for Acme
    return [[[AcmeView alloc] init] autorelease];
}

- (UIButton *) brandedMainButton
{
    // returns a custom main button for Acme
    return [[[AcmeMainButton alloc] init] autorelease];
}

- (UIToolbar *) brandedToolbar
{
    // returns a custom toolbar for Acme
    return [[[AcmeToolbar alloc] init] autorelease];
}

@end

【讨论】:

  • 正如 OP 指出的那样。这两种模式相似但不相同
  • 这就是抽象工厂的实现。但总的来说它们非常相似stackoverflow.com/a/2459385/1847511
  • 你能用几句话解释一下区别吗?
  • 类簇中的工厂是一个抽象类,它产生自己的具体子类。你只需要知道你正在使用NSNumber,你不必知道你在后台得到了NSSignedIntegerNumber 的一个实例,但你仍然可以得到那个类的具体行为。它更加隐含,因为您所做的只是在 NSNumber 上调用 init 方法并返回一个作为 NSNumber 的类。
  • 您可以在Concepts in Objective-C Programming: Class Clusters了解更多信息。
猜你喜欢
  • 1970-01-01
  • 2014-11-19
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 1970-01-01
相关资源
最近更新 更多