欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS App设计模式开发中策略模式的实现示例

程序员文章站 2023-11-20 16:45:40
这次介绍一下策略模式(strategy pattern),相比之下是一种比较简单的模式。它也叫政策模式(policy pattern)。 策略模式使用的就是面向对象的继承和...

这次介绍一下策略模式(strategy pattern),相比之下是一种比较简单的模式。它也叫政策模式(policy pattern)。 策略模式使用的就是面向对象的继承和多态机制,其他的没有什么玄机。策略模式适合使用在: 1. 多个类只有在算法或行为上稍有不同的场景。 2. 算法需要*切换的场景。 3. 需要屏蔽算法规则的场景。 使用策略模式当然也有需要注意的地方,那么就是策略类不要太多,如果一个策略家族的具体策略数量超过4个,则需要考虑混合模式,解决策略类膨胀和对外暴露问题。在实际项目中,我们一般通过工厂方法模式来实现策略类的声明。

下面我们就来具体讲解一下策略模式。

策略模式定义:

define a family of algorithms, encapsulate each one, and make them interchangeable.(定义一组算法,将每个算法都封装起来,并且是它们之间可以互换。)

下面我把策略模式的类层次结构图展示如下:

iOS App设计模式开发中策略模式的实现示例

如图所示,strategy类层次为context定义了一系列的可供重用的算法和行为,继承有助于析取出这些算法中的公共功能。下面我用一个普通超市里收费的例子简单模拟了这个模式。我把其中对应的类介绍一下:

context类———————————cashcontext类
strategy类———————————–cashsuper类
concretestrategya类—————-cashnormal类
concretestrategyb类—————-cashrebate类
concretestrategyc类—————-cashreturn类
好的,上面就是将要向大家展示的objective c源代码类。

下面,我把上面对应的类展示出来,供大家参考:

注意:本文所有代码均在arc环境下编译通过。

cashcontext类接口

复制代码 代码如下:

#import <foundation/foundation.h>
#import "cashsuper.h"

@interface cashcontext :nsobject{
@private cashsuper *cs;
}
-(cashcontext*)myinit:(int)types;
-(void)setcashsuper:(cashsuper*)cashsuper;
-(double)getresult:(double)money;
@end


cashcontext类实现

复制代码 代码如下:

#import "cashcontext.h"
#import "cashnormal.h"
#import "cashrebate.h"
#import "cashreturn.h"

@implementation cashcontext

-(cashcontext*)myinit:(int)types{
    int mytypes;
    mytypes = types;
    switch(mytypes) {
        case 1:
            [self setcashsuper:[[cashnormalalloc]init]];
            break;
        case 2:
            [self setcashsuper:[[cashreturnalloc]myinit:300 and:100]];
            break;
        case 3:
            [self setcashsuper:[[cashrebatealloc]myinit:0.8]];
            break;
        default:
            break;
    }
    return self;
}
-(void)setcashsuper:(cashsuper*)cashsuper{
    cs = cashsuper;
}
-(double)getresult:(double)money{
    return [cs acceptcash:money];
}

@end


cashsuper类接口

复制代码 代码如下:

#import <foundation/foundation.h>

@interface cashsuper :nsobject
-(double)acceptcash:(double)money;
@end


cashsuper类实现

复制代码 代码如下:

#import"cashsuper.h"

@implementation cashsuper

-(double)acceptcash:(double)money{
    return -1.0; //这里返回 -1.0无任何意义,只是为了定义此方法
}

@end


cashnormal类接口

复制代码 代码如下:

#import"cashsuper.h"

@interface cashnormal :cashsuper
@end


cashnormal类实现

复制代码 代码如下:

#import"cashnormal.h"

-(double)acceptcash:(double)money{
    return money;
}

@end


cashrebate类接口

复制代码 代码如下:

#import"cashsuper.h"

@interface cashrebate :cashsuper{
@private double moneyrebate;
}
@property double moneyrebate;
-(cashrebate*)myinit:(double)moneyrebates;
@end


cashrebate实现

复制代码 代码如下:

#import"cashrebate.h"

@implementation cashrebate
@synthesize moneyrebate;

-(cashrebate*)myinit:(double)moneyrebates{
    [self setmoneyrebate:moneyrebates];
    return self;
}
-(double)acceptcash:(double)money{
    return moneyrebate*money;
}

@end


cashreturn类接口

复制代码 代码如下:

#import "cashsuper.h"

@interface cashreturn :cashsuper{
@private double moneycondition;
@private double moneyreturn;
}
@property double moneycondition;
@property double moneyreturn;
-(cashreturn*)myinit:(double)moneyconditions and:(double)moneyreturns;
@end


cashreturn类实现

复制代码 代码如下:

#import "cashreturn.h"

@implementation cashreturn
@synthesize moneyreturn;
@synthesize moneycondition;

-(cashreturn*)myinit:(double)moneyconditions  and:(double)moneyreturns{
    [self setmoneyreturn:moneyreturns];
    [self setmoneycondition:moneyconditions];
    return self;
}
-(double)acceptcash:(double)money{
    double result;
    result = money;
    @try{
        if(money >=moneycondition){
            result = money - (money /moneycondition)*moneyreturn;
        }
    }
    @catch(nsexception *exception) {
        nslog(@"oh!man!!cashreturn has something wrong!");
    }
    @finally{
        return result;
    }
}

@end


main方法调用

复制代码 代码如下:

#import <foundation/foundation.h>
#import "cashcontext.h"

int main (int argc, const char  *argv[])
{
    @autoreleasepool {
        cashcontext *cc = [[cashcontext alloc]myinit:3];
        double total;
        total = [cc getresult:400];
        nslog(@"total money 400,the resual is %f", total);
    }
    return 0;
}


以上是对应的策略模式中相应的类,有一点需要声明的是,这些代码是在有arc环境下书写的,所以不需要手动释放其中的资源。所以有些传递指针地方没有进行手动释放,在此解释一下。

什么情况下需要用策略模式呢,其实我的理解是,当我们在分析需求的过程中,需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。另外,策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。