2017-02-25 64 views
0

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

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

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

+0

你可以用字典替换开关盒,并做更简单的查找。某些产生相同结果的开关盒规则也可以分组。此外,如果您有视图的通用协议,则可以在每个子类中实现颜色/可选逻辑以避免切换。 – Andy

回答

0

开关是最后一个千年的亚类。最简单的方法是拥有(私人)子类。从该子类创建实例。

@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 

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

+0

我喜欢并且不喜欢子类的想法。我有大约15种不同类型,未来可能会更多。所以有一个子类只是为了具有某些预定的属性,似乎它可能是矫枉过正的,虽然组织良好。我使用枚举来简化视图控制器的接口。所以它必须知道的是它想要的是什么类型的视图。什么比这里的枚举更好? – OleShoebill

+0

存储类,而不是自制类型。请记住,这些类是Objective-C中的对象。但是,有15个小类没有什么不对。他们可能是私人的。 –