选择多个值的好模式

时间:2015-12-17 19:50:22

标签: objective-c oop design-patterns

我有一个返回枚举值的方法。然后使用该枚举值来选择图像和颜色(在两个单独的函数中)。我试图找出一种比我已经拥有的更好的方法。目前,我使用该枚举值作为几个数组的索引。

这是根据某些逻辑给出枚举值的方法。

-(NSInteger)giveMeAValuePlease {
    if (something)
        return enumValue0;
    else if (somethingElse)
        return enumValue1;
    else
        return enumValue2;
}

这是使用枚举值选择图像的方法

-(void)methodThatRequiresImage {
    NSInteger imageNeeded = [self giveMeAValuePlease];
    UIImage* imageRequired = [self.imagesArray objectAtIndex:imageNeeded];
}

这是使用枚举值选择颜色

的方法
-(void)methodThatRequiresColor {
    NSInteger colorNeeded = [self giveMeAValuePlease];
    UIColor* colorRequired = [self.colorsArray objectAtIndex:colorNeeded];
}

虽然这不是一个糟糕的解决方案,但如果需要添加/删除值,我觉得将来容易出错。我很感激我对目前所拥有的任何意见。

更新

在看了@mawalker的答案和相关的Javadoc后,我决定尝试一种类似的方法。所以我所做的是创建两个类(以及维护原始枚举),一个用作枚举值的类型,另一个用于存储枚举值集。

这是充当枚举值类型的类(在容器类的.m文件中定义):

@interface MVColorAndFlagName : NSObject {
    NSString* _flagName;
    UIColor* _color;
}

-(instancetype)initWithColor:(UIColor*)color andFlagName:(NSString*)flagName;

@end

@implementation MVColorAndFlagName

-(instancetype)init {
    return nil;
}

-(instancetype)initWithColor:(UIColor *)color andFlagName:(NSString *)flagName {
    self = [super init];
    if (self) {
        if (!color || !flagName) {
            return nil;
        }
        _color = color;
        _flagName = flagName;
    }
    return self;
}

- (UIColor*)color {
    return _color;
}

-(NSString*)flagName {
    return _flagName;
}

@end

然后这是容器类' .H:

typedef NS_ENUM(NSInteger, StatusColor) {
    Red,
    Orange,
    Yellow,
    Green,
    Purple,

    count //always last element
};

@interface MVStatusColor : NSObject {
    NSArray* statusColors;
}

+(instancetype)sharedInstance;
- (NSString*)flagNameForStatusColor:(StatusColor)statusColor;
- (UIColor*)colorForStatusColor:(StatusColor)statusColor;

@end

容器类'实施:

@implementation MVStatusColor

+(instancetype)sharedInstance {
    static MVStatusColor* statusColorInstance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        statusColorInstance = [[self alloc] initTheSharedInstance];
    });
    return statusColorInstance;
}

-(instancetype)initTheSharedInstance {
    self = [super init];
    if (self) {
        // Array of MVColorAndFlagName in same order as StatusColor enum (not including 'None')
        statusColors = @[
                         [[MVColorAndFlagName alloc] initWithColor:[UIColor redColor] andFlagName:kRedFlag],
                         [[MVColorAndFlagName alloc] initWithColor:[UIColor orangeColor] andFlagName:kOrangeFlag],
                         [[MVColorAndFlagName alloc] initWithColor:[UIColor yellowColor] andFlagName:kYellowFlag],
                         [[MVColorAndFlagName alloc] initWithColor:[UIColor greenColor] andFlagName:kGreenFlag],
                         [[MVColorAndFlagName alloc] initWithColor:[UIColor purpleColor] andFlagName:kPurpleFlag]
                         ];
    }
    return self;
}

- (UIColor*)colorForStatusColor:(StatusColor)statusColor {
    if (statusColor >= 0 && statusColor < count)
        return [[statusColors objectAtIndex:statusColor] color];
    else
        return [UIColor clearColor];
}

- (NSString*)flagNameForStatusColor:(StatusColor)statusColor {
    if (statusColor >= 0 && statusColor < count)
        return [[statusColors objectAtIndex:statusColor] flagName];
    else
        return nil;
}

@end

我不确定这应该更新是否更好(虽然我个人更喜欢它),所以我绝对会感谢任何额外的输入。并感谢迄今为止提供意见的所有人。

1 个答案:

答案 0 :(得分:0)

最好避免使用数组和索引,并在某些方法中使其本地化。例如:

枚举和属性或ivars:

@property (strong) UIImage *catImage, *dogImage, *birdImage;
@property (strong) UIColor *catColor, *dogColor, *birdColor;

typedef NS_ENUM(NSUInteger, MYAnimal) {
    cat, dog, bird
};

- (MYAnimal)animal {
    if (meows)
        return cat;
    else
        if (barks)
            return dog;
        else
            return bird;
}

- (UIImage *)image {
    MYAnimal animal = [self animal];
    switch (animal) {
        case cat:
            return self.catImage;
        case dog:
            return self.dogImage;
        case bird:
            return self.birdImage;
        default:
            return nil;
    }
}

- (UIColor *)color {
    MYAnimal animal = [self animal];
    switch (animal) {
        case cat:
            return self.catColor;
        case dog:
            return self.dogColor;
        case bird:
            return self.birdColor;
        default:
            return nil;
    }
}

-(void)methodThatRequiresImage {
    UIImage* imageRequired = self.image;
}

字典和键:

@property (strong) NSDictionary *images, *colors;

NSString *const MYCatKey = @"MYCatKey";
NSString *const MYDogKey = @"MYDogKey";
NSString *const MYBirdKey = @"MYBirdKey";

- (void)awakeFromSomething {    // or init…
    self.images = @{MYCatKey: catImage,
                    MYDogKey: dogImage,
                    MYBirdKey: birdImage};
    self.colors = @{MYCatKey: catColor,
                    MYDogKey: dogColor,
                    MYBirdKey: birdColor};
}

- (NSString *)animal {
    if (meows)
        return MYCatKey;
    else
        if (barks)
            return MYDogKey;
        else
            return MYBirdKey;
}

- (UIImage *)image
{
    NSString *animal = [self animal];
    return [self.images objectForKey:animal];
}

- (UIColor *)color
{
    NSString *animal = [self animal];
    return [self.colors objectForKey:animal];
}

-(void)methodThatRequiresImage {
    UIImage* imageRequired = self.image;
}