基于枚举构造对象

时间:2017-02-25 03:18:50

标签: objective-c enums

我有一个基于枚举值构建对象的类。因此,这些对象的几个属性基于某个枚举值,即类型。

选项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。

所以我的问题是;有没有人对如何改进这种代码有任何建议?

1 个答案:

答案 0 :(得分:0)

开关是上一个千年的子类。最简单的方法是拥有(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

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