Методы класса, сохранение состояния, лучший способ регистрации функций - PullRequest
0 голосов
/ 02 февраля 2012

Я работаю над заданием, которое включает создание калькулятора RPN. В настоящее время я использую методы класса, чтобы проверить, является ли строка операцией, как показано ниже:

+ (NSSet *) noOpOperations {
    return [NSSet setWithObjects:@"π", nil];
}

+ (NSSet *) unaryOperations {
    return [NSSet setWithObjects:@"sin",@"cos",@"log",@"+/-", nil];
}

+ (NSSet *) binaryOperations {
    return [NSSet setWithObjects:@"+",@"-",@"*",@"/", nil];
}
+ (NSSet *) operations {
    /* surely there is a better way - is it possible to save this call and reuse it?  Or what about having the objects register themselves so you can add operations more easily? */
    return [[self noOpOperations] setByAddingObjectsFromSet:
            [[self unaryOperations] setByAddingObjectsFromSet:
             [self binaryOperations]]];
}

+ (BOOL) isOperation:operand {
    return [[self operations] containsObject:operand]; 
}

Я полагаю, что было бы лучше реализовать систему реестров функций, позволяющую динамически добавлять операции из другого места в проекте, но я думаю, что для этого потребуется переменная класса. Есть ли лучший способ сделать это, чем я делаю это сейчас?

1 Ответ

1 голос
/ 02 февраля 2012

Мое личное решение для таких ситуаций:

#define INT_OBJ(x) [NSNumber numberWithInt:x]

@implementation MyClass

static NSDictionary *operations;

enum {
    kOperationNoOp = 1,
    kOperationUnaryOp,
    kOperationBinaryOp,
};

+(void) initialize
{
    operations = [NSDictionary dictionaryWithObjectsAndKeys:@"π",   INT_OBJ(kOperationNoOp), 

                                                            // unary operations
                                                            @"sin", INT_OBJ(kOperationUnaryOp), 
                                                            @"cos", INT_OBJ(kOperationUnaryOp), 
                                                            @"log", INT_OBJ(kOperationUnaryOp), 
                                                            @"+/-", INT_OBJ(kOperationUnaryOp), 

                                                            // binary operations
                                                            @"+",   INT_OBJ(kOperationBinaryOp), 
                                                            @"-",   INT_OBJ(kOperationBinaryOp), 
                                                            @"*",   INT_OBJ(kOperationBinaryOp), 
                                                            @"/",   INT_OBJ(kOperationBinaryOp), nil];
}

-(BOOL) isNoOpOperation:(NSString *) arg
{
    return [[operations objectForKey:arg] intValue] == kOperationNoOp;
}

-(BOOL) isUnaryOperation:(NSString *) arg
{
    return [[operations objectForKey:arg] intValue] == kOperationUnaryOp;
}

-(BOOL) isBinaryOperation:(NSString *) arg
{
    return [[operations objectForKey:arg] intValue] == kOperationBinaryOp;
}

-(BOOL) isAnOperation:(NSString *) arg
{
    // if objectForKey: returns nil, intValue will return 0, telling us that the input is not an operation
    return [[operations objectForKey:arg] intValue] != 0;
}

@end

Я считаю, что это очень просто и легко расширяется.

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