何为策略模式
定义一系列算法,把它们一个个封装起来,并且使它们可互相替换。
策略模式中的一个关键角色是策略类,它为所有支持的或相关的算法声明了一个共同接口。
场景对象使用策略接口调用由具体策略类定义的算法。
策略模式的组成
1、抽象策略角色:通常有一个接口或一个抽象类实现
2、具体策略角色:包装了相关的算法和行为
3、环境角色:持有一个策略类的应用,最终供客户端调用
何时使用策略模式
- 一个类在其操作中使用了多个条件语句来定义许多行为,我们可以把相关的条件分支移到它们自己的策略类中
- 需要算法的各种变体。
- 需要避免把复杂的、与算法相关的数据结构暴露给客户端。
策略模式的使用
//一个打折的例子
//没有使用策略之前是这样的
- (float)getTotalPrice:(NSString *)type price:(float)price{
if ([type isEqual: @"9折"]) {
return price*0.9;
}else if ([type isEqual: @"7折"]) {
return price*0.7;
}else if ([type isEqual: @"300-50"]) {
return price-30;
}
return price;
}
//使用了策略之后
//策略基类
@interface Dicounnt : NSObject
- (float)discount:(float)price;
@end
@implementation Dicounnt
- (float)discount:(float)price{
return 0;
}
@end
//策略子类1
@interface DiscountNight : Dicounnt
@end
@implementation DiscountNight
- (float)discount:(float)price{
return price*0.9;
}
@end
//策略子类2
@interface DiscountSeven : Dicounnt
@end
@implementation DiscountSeven
- (float)discount:(float)price{
return price*0.7;
}
@end
//策略子类3
@interface DiscountCutThirty : Dicounnt
@end
@implementation DiscountCutThirty
- (float)discount:(float)price{
return price-30;
}
@end
//使用策略的类
@interface Price : NSObject
@property (nonatomic, strong) Dicounnt *type;
- (float)getTotalPrice:(float)price;
@end
@implementation Price
- (float)getTotalPrice:(float)price{
return [self.type discount:price];
}
//具体实现
- (void)viewDidLoad {
[super viewDidLoad];
Price *p = [Price new];
p.type = [DiscountCutThirty new];
[p getTotalPrice:200];
}
总结
看了很多文章,包括设计模式的书,没有说在哪里选择策略,只是说给他一个策略然后去实现。
结论是我还是需要一个地方判断需要使用哪个策略,if-else不能避免。
看到网上最合理的解释:策略模式不是为了避免if-else,而是为了遵循程序的开闭原则。
策略模式不是用来避免if-else的问题,程序中是不可或缺if-else的,我们根据if-else来确定具体应该选择使用哪种策略,当有新的策略行为时,我们就可以新添加一个策略实现,这样就可以避免改动原有的策略代码,从而实现程序的扩展性,避免改动原有的策略。
所谓开闭原则,也就是说:对扩展是开放的,对修改是关闭的。运行程序的扩展,但是不允许修改原有的程序策略行为。
可能理解的有偏差,欢迎讨论~