美文网首页
iOS设计模式之解释器模式

iOS设计模式之解释器模式

作者: 点滴86 | 来源:发表于2024-07-05 23:14 被阅读0次

解释器模式

解释器模式的英文是Interpreter Design Pattern。解释器模式为某个语言定义它的语法表示,并定义一个解释器来处理这个语法。
假如定义了一个新的加减乘除计算”语言“,语法规则如下:

  • 运算符只包含加、减、乘、除,并且没有优先级的概念
  • 表达式中,先书写数字,后书写运算符,空格隔开
  • 按照先后顺序,取出两个数字和一个运算符计算结果,结果重新放入数字的最头部位置,循环上述过程,直到只剩下一个数字,这个数字就是表达式最终的计算结果。

举个例子来解释上面的语法规则。比如”8 3 2 4 - + *“这样一个表达式,按照上面的语法规则来处理,取出数字”8 3“和”-“运算法,计算得到5,于是表达式就变成了”5 2 4 + *“。然后,再取出数字”5 2“和”+“运算符,计算得到7,表达式就变成了”7 4 “。最后,取出数字”7 4“和”“运算符,最终得到的结果就是28。代码实现如下:

@interface DMDemoApplication : NSObject 

@end

@implementation DMDemoApplication

- (void)test
{
    [self interpret:@"8 3 2 4 - + *"];
}

- (void)interpret:(NSString *)expression
{
    NSArray *tmpArray = [expression componentsSeparatedByString:@" "];
    NSMutableArray *numberArray = [[NSMutableArray alloc] init];
    NSMutableArray *operatorArray = [[NSMutableArray alloc] init];
    NSInteger count = [tmpArray count];
    for (NSInteger i = 0; i < count; i++) {
        NSInteger j = count / 2 + 1;
        NSString *str = [tmpArray objectAtIndex:i];
        if (i < j) {
            [numberArray addObject:str];
        } else {
            [operatorArray addObject:str];
        }
    }
    
    for (NSInteger i = 0; i < [operatorArray count]; i++) {
        NSString *operatorStr = [operatorArray objectAtIndex:i];
        NSString *numStrOne = [numberArray objectAtIndex:0];
        NSString *numStrTwo = [numberArray objectAtIndex:1];
        [numberArray removeObjectAtIndex:1];
        [numberArray removeObjectAtIndex:0];
        NSInteger result = 0;
        if ([operatorStr isEqualToString:@"+"]) {
            result = [numStrOne integerValue] + [numStrTwo integerValue];
        } else if ([operatorStr isEqualToString:@"-"]) {
            result = [numStrOne integerValue] - [numStrTwo integerValue];
        } else if ([operatorStr isEqualToString:@"*"]) {
            result = [numStrOne integerValue] * [numStrTwo integerValue];
        } else if ([operatorStr isEqualToString:@"/"]) {
            result = [numStrOne integerValue] / [numStrTwo integerValue];
        }
        
        NSString *resultStr = [NSString stringWithFormat:@"%@", [NSNumber numberWithInteger:result]];
        [numberArray insertObject:resultStr atIndex:0];
    }
    NSString *numStrOne = [numberArray objectAtIndex:0];
    NSLog(@"%@结果为:%@", expression, numStrOne);
}

@end

在上面的代码实现中,语法规则的解析逻辑都集中在一个函数中,对于简单的语法规则的解析,这样的设计就足够了。但是,对于复杂的语法规则的解析,逻辑复杂,代码量多,所有的解析逻辑都耦合在一个函数中,这样显然是不合理的。这个时候,就要考虑拆分代码,将解析逻辑拆分到独立的小类中。
前面定义的语法规则有两类表达式,一类是数字,一类是运算符,运算符又包括加减乘除。利用解释器模式,可以把解析的工作拆分到DMZNumberExpression、DMZAdditionExpression、DMZSubstractionExpression、DMZMultiplicationExpression、DMZDivisionExpression这样五个解析类中。重构之后代码如下:

@protocol DMZExpression <NSObject>

- (NSInteger)interpret;

@end

@interface DMZNumberExpression : NSObject <DMZExpression>

- (instancetype)initWithString:(NSString *)str;

- (instancetype)initWithInter:(NSInteger)value;

@end

@interface DMZNumberExpression ()

@property (nonatomic, assign) NSInteger mValue;

@end

@implementation DMZNumberExpression

- (instancetype)initWithString:(NSString *)str
{
    if (self = [super init]) {
        self.mValue = [str integerValue];
    }
    return self;
}

- (instancetype)initWithInter:(NSInteger)value
{
    if (self = [super init]) {
        self.mValue = value;
    }
    return self;
}

- (NSInteger)interpret
{
    return self.mValue;
}

@end

@interface DMZAdditionExpression : NSObject <DMZExpression>

- (instancetype)initWithNumberOne:(DMZNumberExpression *)numberOne numberTwo:(DMZNumberExpression *)numberTwo;

@end

@interface DMZAdditionExpression ()

@property (nonatomic, strong) DMZNumberExpression *mNumberOne;

@property (nonatomic, strong) DMZNumberExpression *mNumberTwo;

@end

@implementation DMZAdditionExpression

- (instancetype)initWithNumberOne:(DMZNumberExpression *)numberOne numberTwo:(DMZNumberExpression *)numberTwo
{
    if (self = [super init]) {
        self.mNumberOne = numberOne;
        self.mNumberTwo = numberTwo;
    }
    return self;
}

- (NSInteger)interpret
{
    return [self.mNumberOne interpret] + [self.mNumberTwo interpret];
}

@end

@interface DMZSubstractionExpression : NSObject <DMZExpression>

- (instancetype)initWithNumberOne:(DMZNumberExpression *)numberOne numberTwo:(DMZNumberExpression *)numberTwo;

@end

@interface DMZSubstractionExpression ()

@property (nonatomic, strong) DMZNumberExpression *mNumberOne;

@property (nonatomic, strong) DMZNumberExpression *mNumberTwo;

@end

@implementation DMZSubstractionExpression

- (instancetype)initWithNumberOne:(DMZNumberExpression *)numberOne numberTwo:(DMZNumberExpression *)numberTwo
{
    if (self = [super init]) {
        self.mNumberOne = numberOne;
        self.mNumberTwo = numberTwo;
    }
    return self;
}

- (NSInteger)interpret
{
    return [self.mNumberOne interpret] - [self.mNumberTwo interpret];
}

@end

@interface DMZMultiplicationExpression : NSObject <DMZExpression>

- (instancetype)initWithNumberOne:(DMZNumberExpression *)numberOne numberTwo:(DMZNumberExpression *)numberTwo;

@end

@interface DMZMultiplicationExpression ()

@property (nonatomic, strong) DMZNumberExpression *mNumberOne;

@property (nonatomic, strong) DMZNumberExpression *mNumberTwo;

@end

@implementation DMZMultiplicationExpression

- (instancetype)initWithNumberOne:(DMZNumberExpression *)numberOne numberTwo:(DMZNumberExpression *)numberTwo
{
    if (self = [super init]) {
        self.mNumberOne = numberOne;
        self.mNumberTwo = numberTwo;
    }
    return self;
}

- (NSInteger)interpret
{
    return [self.mNumberOne interpret] * [self.mNumberTwo interpret];
}

@end

@interface DMZDivisionExpression : NSObject <DMZExpression>

- (instancetype)initWithNumberOne:(DMZNumberExpression *)numberOne numberTwo:(DMZNumberExpression *)numberTwo;

@end

@interface DMZDivisionExpression ()

@property (nonatomic, strong) DMZNumberExpression *mNumberOne;

@property (nonatomic, strong) DMZNumberExpression *mNumberTwo;

@end

@implementation DMZDivisionExpression

- (instancetype)initWithNumberOne:(DMZNumberExpression *)numberOne numberTwo:(DMZNumberExpression *)numberTwo
{
    if (self = [super init]) {
        self.mNumberOne = numberOne;
        self.mNumberTwo = numberTwo;
    }
    return self;
}

- (NSInteger)interpret
{
    return [self.mNumberOne interpret] / [self.mNumberTwo interpret];
}

@end

@implementation DMDemoApplication

- (void)test
{
    [self interpret:@"8 3 2 4 - + *"];
}

- (void)interpret:(NSString *)expression
{
    NSArray *tmpArray = [expression componentsSeparatedByString:@" "];
    NSMutableArray *numberArray = [[NSMutableArray alloc] init];
    NSMutableArray *operatorArray = [[NSMutableArray alloc] init];
    NSInteger count = [tmpArray count];
    for (NSInteger i = 0; i < count; i++) {
        NSInteger j = count / 2 + 1;
        NSString *str = [tmpArray objectAtIndex:i];
        if (i < j) {
            [numberArray addObject:[[DMZNumberExpression alloc] initWithString:str]];
        } else {
            [operatorArray addObject:str];
        }
    }
    
    for (NSInteger i = 0; i < [operatorArray count]; i++) {
        NSString *operatorStr = [operatorArray objectAtIndex:i];
        DMZNumberExpression *numOne = [numberArray objectAtIndex:0];
        DMZNumberExpression *numTwo = [numberArray objectAtIndex:1];
        [numberArray removeObjectAtIndex:1];
        [numberArray removeObjectAtIndex:0];
        id<DMZExpression> expression = nil;
        if ([operatorStr isEqualToString:@"+"]) {
            expression = [[DMZAdditionExpression alloc] initWithNumberOne:numOne numberTwo:numTwo];
        } else if ([operatorStr isEqualToString:@"-"]) {
            expression = [[DMZSubstractionExpression alloc] initWithNumberOne:numOne numberTwo:numTwo];
        } else if ([operatorStr isEqualToString:@"*"]) {
            expression = [[DMZMultiplicationExpression alloc] initWithNumberOne:numOne numberTwo:numTwo];
        } else if ([operatorStr isEqualToString:@"/"]) {
            expression = [[DMZDivisionExpression alloc] initWithNumberOne:numOne numberTwo:numTwo];
        }
        NSInteger result = [expression interpret];
        DMZNumberExpression *tmpNumberExpression = [[DMZNumberExpression alloc] initWithInter:result];
        [numberArray insertObject:tmpNumberExpression atIndex:0];
    }
    DMZNumberExpression *numberExpresionOne = [numberArray objectAtIndex:0];
    NSLog(@"%@结果为:%@", expression, [NSNumber numberWithInteger:[numberExpresionOne interpret]]);
}

@end

相关文章

网友评论

      本文标题:iOS设计模式之解释器模式

      本文链接:https://www.haomeiwen.com/subject/ktjgcjtx.html