Objective c 基于枚举构造对象

Objective c 基于枚举构造对象,objective-c,enums,Objective C,Enums,我有一个基于枚举值构建对象的类。所以这些对象的一些属性是基于某个枚举值,一个类型 备选案文1: typedef NS_ENUM (NSUInteger, ViewType) { VTHouse, VTCar, VTChair, ... }; 我有几种基于类型确定对象属性的方法 - (NSURL*)urlForViewType:(ViewType)type { NSURL *url = nil; switch (type) {

我有一个基于枚举值构建对象的类。所以这些对象的一些属性是基于某个枚举值,一个类型

备选案文1:

typedef NS_ENUM (NSUInteger, ViewType) {
    VTHouse,
    VTCar,
    VTChair,
    ...
};
我有几种基于类型确定对象属性的方法

- (NSURL*)urlForViewType:(ViewType)type {

    NSURL *url = nil;

    switch (type) {
        case VTHouse: {
            url = [NSURL URLWithString:@"House url"];
            break;
        }
        case VTCar: {
            url = [NSURL URLWithString:@"Car url"];
            break;
        }
        case VTChair: {
            url = [NSURL URLWithString:@"Chair url"];
            break;
        }
        ...
    }

    return url;
}

- (NSURL*)isSelectableViewType:(ViewType)type {

    BOOL selectable = NO;

    switch (type) {
        case VTHouse: {
            selectable = YES;
            break;
        }
        case VTCar: {
            selectable = YES;
            break;
        }
        default: {
            break;
        }
    }

    return selectable;
}

- (NSURL*)colorForViewType:(ViewType)type {

    UIColor *color = nil;

    switch (type) {
        case VTHouse: {
            color = [UIColor redColor];
            break;
        }
        case VTCar: {
            color = [UIColor blueColor];
            break;
        }
        case VTChair: {
            color = [UIColor lightGrayColor];
            break;
        }
        ...
    }

    return color;
}

// And so on...
然后我有一个方法,这个类的用户将调用它

- (SpecialView*)specialViewForType:(ViewType)type {

    NSURL *url = [self urlForViewType:type];
    BOOL selectable = [self isSelectableViewType:type];
    UIColor *color = [self colorForViewType:type];
    ...

    return [SpecialView specialViewURL:url selectable:selectable color:color ...];
}
这一切都很好,但它给我一种不安的感觉。有点不对劲。也许是所有的开关。我觉得有一种更干净的方法可以做到这一点

另一种摆脱大多数开关的方法是:

备选案文2:

- (SpecialView*)specialViewForType:(ViewType)type {

    SpecialView *view = nil;

    switch (type) {
        case VTHouse: {
            view = [self specialViewHouse];
            break;
        }
        case VTCar: {
            view = [self specialViewCar];
            break;
        }
        case VTChair: {
            view = [self specialViewChair];
            break;
        }
        ...
    }
    return view;
}
其中每个方法都已经知道要为每个类型设置哪些属性。但我更喜欢选项1


所以我的问题是,;有人对如何改进这种代码有什么建议吗?

开关是上千年的子类。最简单的方法是拥有(private?)子类。从该子类创建实例

@implementation BaseClass
+ (instancetype)newBaseClassForType:(ViewType)viewType
{
  // Do a look-up to a array or a one-time switch to get the subclass
  Class appropiateSubclass = …;
  return [appropiateSubclass new];
}
然后,子类可以重写方法,即。e、 :

@implementation HouswSubClass
- (BOOL)isSelectable { return YES; } // BTW: The return type was wrong

更重要的是:为什么有枚举?

您可以用字典替换开关大小写,并进行更简单的查找。某些产生相同结果的开关大小写规则也可以分组。此外,如果您有视图的通用协议,您可以在每个子类中实现颜色/可选逻辑,以避免切换情况。我喜欢和不喜欢子类的想法。我有大约15种不同的类型,将来可能会更多。因此,让一个子类只具有某些预先确定的属性似乎有些过分,尽管组织得很好。我使用枚举来简化视图控制器的接口。所以它只需要知道它想要什么类型的视图。这里有什么比枚举更好的呢?存储类,而不是自制类型。请记住,类是Objective-C中的对象。但是,拥有15个子类并没有什么错。很可能是私人的。