Способы замены массивного оператора if альтернативной конструкцией в Objective-C - PullRequest
5 голосов
/ 09 ноября 2011

У меня довольно длинное утверждение if.Оператор if проверяет строку «тип», чтобы определить, какой тип объекта должен быть создан.Вот пример ...

if ( [type rangeOfString:@"coin-large"].location != NSNotFound ) 
{
   ... create large coin ...
   mgr = gameLayer.coinLargeMgr;
}
else if ( [type rangeOfString:@"coin-small"].location != NSNotFound ) 
{
   mgr = gameLayer.coinLargeMgr;
}

... more else statements ...

myObject = [mgr getNewObject];

Операторы "else-if" продолжаются для других типов объектов, которые сейчас стоят около 20, и это число, вероятно, увеличится.Это работает довольно хорошо, но с точки зрения обслуживания и эффективности, я думаю, это можно улучшить.Мой главный кандидат на данный момент - создать NSDictionary с ключом для строки типа объекта (coin-small, coin-large и т. Д.) Со значением объекта manager, который должен быть привязан к этому типу.Идея в том, что это будет быстрый взгляд на тип объекта, который мне нужно создать.Не уверен, что это лучший подход, продолжая искать другие варианты, но мне любопытно, что люди здесь могли бы сделать для аналогичной проблемы.Любая помощь / обратная связь с благодарностью.

Ответы [ 2 ]

6 голосов
/ 09 ноября 2011

Вы можете использовать NSDictionary, заполненный ObjC 'Blocks', чтобы сделать оператор, подобный переключателю, который выполняет желаемый код.Поэтому создайте словарь с вашими строковыми ключами, сопоставленными с блоком кода, который будет выполняться, когда каждый найден:

NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
                      ^{ NSLog(@"found key1"); }, @"key1", 
                      ^{ NSLog(@"found key2"); }, @"key2", 
                      nil];

Вы, вероятно, подготовите этот словарь только один раз на каком-то раннем этапе, как в конструкторе или статическоминициализатор, чтобы он был готов к выполнению вашего более позднего кода.

Затем вместо вашего блока if / else вырежьте строковый ключ из любого входного значения, которое вы получаете (или, возможно, вам не понадобится его разрезать,все что угодно):

NSString *input = ...
NSRange range = ...
NSString *key = [input substringWithRange:range]; 

И выполнить (быстрый) словарь поиска кода для выполнения.Затем выполните:

void (^myBlock)(void) = [dict objectForKey:key];
myBlock();
5 голосов
/ 09 ноября 2011

Словарь подход был бы легко выполнимым.Предполагая, что различные менеджеры сводятся к конкретным экземплярам при создании словаря, это будет почти то же самое, что почти любой объектно-ориентированный язык:

NSDictionary *stringsToManagers = 
    [NSDictionary dictionaryWithObjectsAndKeys:
         @"coin-large", gameLayer.coinLargeMgr,
         @"coin-small", gameLayer.coinSmallMgr,
         nil];

// this is assuming that type may contain multiple types; otherwise
// just use [stringsToManagers objectForKey:string]
for(NSString *string in [stringsToManagers allKeys])
{
    if([type rangeOfString:string].location != NSNotFound)
    {
         [[stringsToManagers objectForKey:string] addNewObject];
         // or get it and store it wherever it should go
    }
}

Если все менеджеры делают, продают соответствующие объектыболее объектно-ориентированный подход может быть следующим:

NSDictionary *stringsToClasses = 
    [NSDictionary dictionaryWithObjectsAndKeys:
         @"coin-large", [LargeCoin class],
         @"coin-small", [SmallCoin class],
         nil];

// this is assuming that type may contain multiple types; otherwise
// just use [stringsToManagers objectForKey:string]
for(NSString *string in [stringsToManagers allKeys])
{
    if([type rangeOfString:string].location != NSNotFound)
    {
         id class = [stringsToManagers objectForKey:string];

         id newObject = [[class alloc] init];
         // this is exactly the same as if, for example, you'd
         // called [[LargeCoin alloc] init] after detecting coin-large
         // within the input string; you should obviously do something
         // with newObject now
    }
}

Это может избавить вас от необходимости писать какие-либо менеджеры, если структура вашей программы в противном случае подходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...